Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions cli/module_generate/_templates/go/DEVELOPER_GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Getting Started with Go Module Development

This guide explains how to work with the files generated by `viam module generate` for Go modules.

---
### Module Setup

After generating your module, always make sure your Go dependencies are up to date:

run:
```bash
go mod tidy
```
---
## Working with `module.go` and module lifecycle

The generated `module.go` file contains the scaffolding for your resource. You will edit this file to add configuration, initialization, and method implementations.

1. **`Validate(path string)`**
- Called first, before the module is created.
- It checks that the **Config struct** (`cfg`) for this specific resource is valid.
- You can use it to ensure required fields exist and values are within valid ranges.
- It also returns dependency information:
- **First return:** required dependencies (other resources that must exist)
- **Second return:** optional dependencies (resources that are nice to have but not required)
- `path` is provided by the runtime and indicates **where this resource appears in the JSON config**, e.g., `"components.0"`. Use it in error messages to show which resource has a problem.

Example:

```go
func (cfg *Config) Validate(path string) ([]string, []string, error) {
if cfg.Camera == "" {
return nil, nil, fmt.Errorf("%s: missing required field 'camera'", path)
}
return []string{"board:main"}, []string{"sensor:temp"}, nil
}
```

2. **`new<ModuleName><ModelName>(...)`**
- Automatically called by the runtime after validation.
- Takes a generic `rawConf` from the robot’s JSON config.
- Converts it into a typed `*Config`.
- Passes the config to `New<ModelName>` to create the resource instance.
- You usually won’t edit this function.

3. **`New<ModelName>(...)`**
- Your actual constructor.
- Receives the already-parsed `*Config`.
- Sets up the logger, config, and any initial state.
- You can add hardware initialization or background tasks here.
- Returns the fully constructed resource instance.

4. **Resource Methods**
- These are called based on what is being used in the robot.

- The generated file contains stubs for all required interface methods. Each currently calls `panic("not implemented")`.

- Replace these with your logic. For example:

```go
func (r *myResource) DoCommand(ctx context.Context, cmd map[string]interface{}) (map[string]interface{}, error) {
r.logger.Infof("DoCommand called with: %+v", cmd)
return map[string]interface{}{"status": "ok"}, nil
}
```

5. **`Close(ctx)`**
- Called when the module is being shut down.
- Use it to clean up background tasks, stop goroutines, and close hardware connections.


### Logging

Use the provided `logger` for all debug, info, and error messages. You can view these logs on the Viam app when you're module is running on any robot.

Examples:

```go
// Informational message
s.logger.Infof("Starting move sequence for arm %s", s.name)

// Debug message
s.logger.Debugf("Current joint positions: %+v", positions)

// Error message
s.logger.Errorf("Failed to move resource: %v", err)

// Example in a method
func (s *<ModuleName><ModelName>) EndPosition(ctx context.Context, extra map[string]interface{}) (spatialmath.Pose, error) {
s.logger.Infof("EndPosition called for resource %s", s.name)
return spatialmath.Pose{}, nil
}
```


Loading