Skip to content
Merged
Show file tree
Hide file tree
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
23 changes: 23 additions & 0 deletions go/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,26 @@ Run:
```
dagger check -l
```

## Environment variables

Pass `--env-vars` to set environment variables (in `KEY=VALUE` format) in the
Go container, e.g. for `GOEXPERIMENT` flags. As a toolchain, set it via a
customization in `dagger.json`:

```json
{
"toolchains": [
{
"name": "go",
"source": "github.com/papercomputeco/daggerverse/go@main",
"customizations": [
{
"argument": "envVars",
"default": "GOEXPERIMENT=jsonv2"
}
]
}
]
}
```
45 changes: 40 additions & 5 deletions go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,67 @@ import (
"dagger/go/internal/dagger"
"errors"
"fmt"
"strings"
)

type Go struct {
// +private
Source *dagger.Directory

// EnvVars is an optional list of environment variables to set in the
// Go container. Each entry must be in "KEY=VALUE" format.
// This is useful for build-time variables like GOEXPERIMENT.
//
// +private
EnvVars []string
}

func New(
// +defaultPath="/"
source *dagger.Directory,

// Optional environment variables to set in the Go container.
// Each entry must be in "KEY=VALUE" format (e.g. "GOEXPERIMENT=jsonv2").
// +optional
envVars []string,
) *Go {
return &Go{
Source: source,
Source: source,
EnvVars: envVars,
}
}

func (g *Go) goContainer() *dagger.Container {
return dag.Container().
func (g *Go) goContainer() (*dagger.Container, error) {
ctr := dag.Container().
From("golang:1.26-bookworm").
WithMountedCache("/go/pkg/mod", dag.CacheVolume("go-mod")).
WithMountedCache("/root/.cache/go-build", dag.CacheVolume("go-build")).
WithWorkdir("/src").
WithDirectory("/src", g.Source)

// Apply caller-provided environment variables.
for _, env := range g.EnvVars {
parts := strings.SplitN(env, "=", 2)
if len(parts) != 2 || parts[0] == "" {
return nil, fmt.Errorf("invalid env var %q: must be in KEY=VALUE format", env)
}
ctr = ctr.WithEnvVariable(parts[0], parts[1])
}

return ctr, nil
}

// CheckGoModTidy runs "go mod tidy" and fails if it produces any changes to
// go.mod or go.sum, indicating that the caller forgot to tidy before committing.
//
// +check
func (g *Go) CheckGoModTidy(ctx context.Context) (string, error) {
out, err := g.goContainer().
ctr, err := g.goContainer()
if err != nil {
return "", fmt.Errorf("could not create go container: %w", err)
}

out, err := ctr.
WithExec([]string{"cp", "go.mod", "go.mod.HEAD"}).
WithExec([]string{"cp", "go.sum", "go.sum.HEAD"}).
WithExec([]string{"go", "mod", "tidy"}).
Expand All @@ -62,7 +92,12 @@ func (g *Go) CheckGoModTidy(ctx context.Context) (string, error) {
//
// +check
func (g *Go) CheckGoVet(ctx context.Context) (string, error) {
return g.goContainer().
ctr, err := g.goContainer()
if err != nil {
return "", fmt.Errorf("could not create go container: %w", err)
}

return ctr.
WithExec([]string{"go", "vet", "./..."}).
Stdout(ctx)
}
Loading