Skip to content

Go Conventions

All Amadla tools and libraries follow consistent Go coding conventions.

Naming

Interfaces

Interfaces are prefixed with I:

type IGit interface {
    Clone(url string) error
    Pull() error
}

type IFile interface {
    Read(path string) ([]byte, error)
    Write(path string, data []byte) error
}

Structs

Implementation structs are prefixed with S:

type SGit struct {
    url      string
    repoPath string
}

type SFile struct {
    basePath string
}

Constructors

Constructor functions follow the New*Service() pattern and return the interface type:

func NewGitService(url, repoPath string) IGit {
    return &SGit{
        url:      url,
        repoPath: repoPath,
    }
}

This pattern enables dependency injection and mocking.

Mocks

Mocks are generated by mockery and follow the Mock* or mock_I*.go naming:

type MockIGit struct {
    mock.Mock
}

Dependency Injection

Package-Level Function Variables

OS and system calls are assigned to package-level variables so tests can replace them:

// Production code
var osOpen = os.Open
var execCommand = exec.Command

func readFile(path string) ([]byte, error) {
    f, err := osOpen(path)
    // ...
}
// Test code
func TestReadFile(t *testing.T) {
    osOpen = func(name string) (*os.File, error) {
        return nil, errors.New("mock error")
    }
    defer func() { osOpen = os.Open }()
    // ...
}

Interface-Based Injection

Services accept interfaces in constructors, enabling mock injection:

type SEntity struct {
    git    IGit
    cache  ICache
    schema ISchema
}

func NewEntityService(git IGit, cache ICache, schema ISchema) IEntity {
    return &SEntity{git: git, cache: cache, schema: schema}
}

Error Handling

  • Use typed errors in message/ packages
  • Wrap errors with context: fmt.Errorf("failed to clone repo: %w", err)
  • Return errors up the call stack; handle at command level

Code Organization

  • One interface + implementation per file (named after the interface)
  • Tests alongside implementation: git.go + git_test.go
  • Mocks generated in-package: mock_IGit.go