From aa0979647bce340cd09754c91d46755f9c645122 Mon Sep 17 00:00:00 2001 From: Sven Greb Date: Thu, 22 Apr 2021 21:12:39 +0200 Subject: [PATCH] Task for Go toolchain `env` command To support the `go env` command of the Go toolchain [1], a new `Task` [2] has been implemented in the new `env` [3] package that can be used through a Go toolchain `Runner` [4]. The task is customizable through the following functions: - `WithEnv(env map[string]string) env.Option` - sets the task specific environment. - `WithEnvVars(envVars ...string) env.Option` - sets the names of the target environment variables. - `WithExtraArgs(extraArgs ...string) env.Option` - sets additional arguments to pass to the command. [1]: https://pkg.go.dev/cmd/go#hdr-Print_Go_environment_information [2]: https://pkg.go.dev/github.com/svengreb/wand/pkg/task#Task [3]: https://pkg.go.dev/github.com/svengreb/wand/pkg/task/golang/env [4]: https://pkg.go.dev/github.com/svengreb/wand/pkg/task/golang#Runner GH-81 --- README.md | 3 ++ pkg/elder/elder.go | 8 ++-- pkg/task/golang/env/env.go | 75 ++++++++++++++++++++++++++++++++++ pkg/task/golang/env/options.go | 63 ++++++++++++++++++++++++++++ 4 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 pkg/task/golang/env/env.go create mode 100644 pkg/task/golang/env/options.go diff --git a/README.md b/README.md index 04b6659..d2d833d 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,7 @@ The package also already provides tasks for basic [Go toolchain][go-pkg-cmd/go] - **`goimports`** — the [`goimports`][go-pkg-task/goimports] package provides a task for the [`golang.org/x/tools/cmd/goimports`][go-pkg-golang.org/x/tools/cmd/goimports] Go module command. `goimports` allows to update Go import lines, add missing ones and remove unreferenced ones. It also formats code in the same style as [`gofmt`][go-pkg-cmd/gofmt] so it can be used as a replacement. The source code of `goimports` is [available in the GitHub repository][gh-golang/tools-tree-cmd/goimports]. - **Go** — The [`golang`][go-pkg-task/golang] package provides tasks for [Go toolchain][go-pkg-cmd/go] commands. - **`build`** — to run the [`build` command of the Go toolchain][go-pkg-cmd/go#build] the task of the [`build`][go-pkg-task/golang/build] package can be used. + - **`env`** — to run the [`env` command of the Go toolchain][go-pkg-cmd/go#env] the task of the [`env`][go-pkg-task/golang/env] package can be used. - **`install`** — to run the [`install` command of the Go toolchain][go-pkg-cmd/go#install] the task of the [`install`][go-pkg-task/golang/install] package can be used. - **`test`** — to run the [`test` command of the Go toolchain][go-pkg-cmd/go#test] the task of the [`test`][go-pkg-task/golang/test] package can be used. - **`golangci-lint`** — the [`golangcilint`][go-pkg-task/golangcilint] package provides a task for the [`github.com/golangci/golangci-lint/cmd/golangci-lint`][go-pkg-github.com/golangci/golangci-lint/cmd/golangci-lint] Go module command. `golangci-lint` is a fast, parallel runner for dozens of Go linters that uses caching, supports YAML configurations and has integrations with all major IDEs. The source code of `golangci-lint` is [available in the GitHub repository][gh-golangci/golangci-lint]. @@ -325,6 +326,7 @@ The guide also includes information about [minimal, complete, and verifiable exa [go-pkg-cmd/go]: https://pkg.go.dev/cmd/go [go-pkg-cmd/go#build]: https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies [go-pkg-cmd/go#env_vars]: https://pkg.go.dev/cmd/go/#hdr-Environment_variables +[go-pkg-cmd/go#env]: https://pkg.go.dev/cmd/go#hdr-Print_Go_environment_information [go-pkg-cmd/go#install]: https://pkg.go.dev/cmd/go#hdr-Compile_and_install_packages_and_dependencies [go-pkg-cmd/go#mod_cmds]: https://golang.org/ref/mod#mod-commands [go-pkg-cmd/go#print_env]: https://pkg.go.dev/cmd/go/#hdr-Print_Go_environment_information @@ -362,6 +364,7 @@ The guide also includes information about [minimal, complete, and verifiable exa [go-pkg-task/goimports]: https://pkg.go.dev/github.com/svengreb/wand/pkg/task/goimports [go-pkg-task/golang]: https://pkg.go.dev/github.com/svengreb/wand/pkg/task/golang [go-pkg-task/golang/build]: https://pkg.go.dev/github.com/svengreb/wand/pkg/task/golang/build +[go-pkg-task/golang/env]: https://pkg.go.dev/github.com/svengreb/wand/pkg/task/golang/env [go-pkg-task/golang/install]: https://pkg.go.dev/github.com/svengreb/wand/pkg/task/golang/install [go-pkg-task/golang/test]: https://pkg.go.dev/github.com/svengreb/wand/pkg/task/golang/test [go-pkg-task/golangcilint]: https://pkg.go.dev/github.com/svengreb/wand/pkg/task/golangcilint diff --git a/pkg/elder/elder.go b/pkg/elder/elder.go index 1c45b69..0e83091 100644 --- a/pkg/elder/elder.go +++ b/pkg/elder/elder.go @@ -68,7 +68,7 @@ func (e *Elder) Clean(appName string, opts ...taskFSClean.Option) ([]string, err } t, tErr := taskFSClean.New(e.GetProjectMetadata(), ac, opts...) if tErr != nil { - return []string{}, fmt.Errorf("create %q task: %w", taskFSClean.TaskName, tErr) + return []string{}, tErr } return t.Clean() @@ -168,7 +168,7 @@ func (e *Elder) Goimports(appName string, opts ...taskGoimports.Option) error { t, tErr := taskGoimports.New(ac, opts...) if tErr != nil { - return fmt.Errorf("create %q task: %w", taskGoimports.TaskName, tErr) + return tErr } return e.gobinRunner.Run(t) @@ -193,7 +193,7 @@ func (e *Elder) GolangCILint(appName string, opts ...taskGolangCILint.Option) er t, tErr := taskGolangCILint.New(ac, opts...) if tErr != nil { - return fmt.Errorf("create %q task: %w", taskGolangCILint.TaskName, tErr) + return tErr } return e.gobinRunner.Run(t) @@ -241,7 +241,7 @@ func (e *Elder) Gox(appName string, opts ...taskGox.Option) error { t, tErr := taskGox.New(ac, opts...) if tErr != nil { - return fmt.Errorf("create %q task: %w", taskGox.TaskName, tErr) + return tErr } return e.gobinRunner.Run(t) diff --git a/pkg/task/golang/env/env.go b/pkg/task/golang/env/env.go new file mode 100644 index 0000000..93b12d1 --- /dev/null +++ b/pkg/task/golang/env/env.go @@ -0,0 +1,75 @@ +// Copyright (c) 2019-present Sven Greb +// This source code is licensed under the MIT license found in the LICENSE file. + +// Package env provides a task for the Go toolchain `env` command. +// See `go help environment`, `go help env` and the `go` command documentations at +// https://pkg.go.dev/cmd/go#hdr-Print_Go_environment_information and +// https://pkg.go.dev/cmd/go#hdr-Environment_variables for more details. +// +// References +// +// (1) https://pkg.go.dev/cmd/go#hdr-Print_Go_environment_information +// (2) https://pkg.go.dev/cmd/go#hdr-Environment_variables +// (3) https://pkg.go.dev/cmd/go/internal/envcmd +package env + +import ( + "github.com/svengreb/wand/pkg/app" + "github.com/svengreb/wand/pkg/task" +) + +// Task is a task for the Go toolchain `env` command. +// See `go help environment`, `go help env` and the `go` command documentations at +// https://pkg.go.dev/cmd/go#hdr-Print_Go_environment_information and +// https://pkg.go.dev/cmd/go#hdr-Environment_variables for more details. +// +// References +// +// (1) https://pkg.go.dev/cmd/go#hdr-Print_Go_environment_information +// (2) https://pkg.go.dev/cmd/go#hdr-Environment_variables +// (3) https://pkg.go.dev/cmd/go/internal/envcmd +type Task struct { + ac app.Config + opts *Options +} + +// BuildParams builds the parameters. +func (t *Task) BuildParams() []string { + params := []string{"env"} + + // Enable JSON output format. + if t.opts.EnableJSONOutput { + params = append(params, "-json") + } + + // Include additionally configured arguments. + params = append(params, t.opts.extraArgs...) + + return append(params, t.opts.EnvVars...) +} + +// Env returns the task specific environment. +func (t *Task) Env() map[string]string { + return t.opts.env +} + +// Kind returns the task kind. +func (t *Task) Kind() task.Kind { + return task.KindExec +} + +// Name returns the task name. +func (t *Task) Name() string { + return t.opts.name +} + +// Options returns the task options. +func (t *Task) Options() task.Options { + return *t.opts +} + +// New creates a new task for the Go toolchain `env` command. +//nolint:gocritic // The app.Config struct is passed as value by design to ensure immutability. +func New(ac app.Config, opts ...Option) *Task { + return &Task{ac: ac, opts: NewOptions(opts...)} +} diff --git a/pkg/task/golang/env/options.go b/pkg/task/golang/env/options.go new file mode 100644 index 0000000..0c8fdc7 --- /dev/null +++ b/pkg/task/golang/env/options.go @@ -0,0 +1,63 @@ +// Copyright (c) 2019-present Sven Greb +// This source code is licensed under the MIT license found in the LICENSE file. + +package env + +const ( + // taskName is the name of the task. + taskName = "go/env" +) + +// Option is a task option. +type Option func(*Options) + +// Options are task options. +type Options struct { + // EnableJSONOutput indicates whether the output should be in JSON format. + EnableJSONOutput bool + + // env is the task specific environment. + env map[string]string + + // EnvVars are the names of the target environment variables. + EnvVars []string + + // extraArgs are additional arguments passed to the command. + extraArgs []string + + // name is the task name. + name string +} + +// NewOptions creates new task options. +func NewOptions(opts ...Option) *Options { + opt := &Options{ + name: taskName, + } + for _, o := range opts { + o(opt) + } + + return opt +} + +// WithEnv sets the task specific environment. +func WithEnv(env map[string]string) Option { + return func(o *Options) { + o.env = env + } +} + +// WithEnvVars sets the names of the target environment variables. +func WithEnvVars(envVars ...string) Option { + return func(o *Options) { + o.EnvVars = append(o.EnvVars, envVars...) + } +} + +// WithExtraArgs sets additional arguments to pass to the command. +func WithExtraArgs(extraArgs ...string) Option { + return func(o *Options) { + o.extraArgs = append(o.extraArgs, extraArgs...) + } +}