Target Author Toolkit

The pkg/gomake helpers available when writing GoMake targets.

GoMake is a tool, not a library

GoMake is a command-line tool. Its machinery — parsing, out-of-source builds, the makefile runtime, built-in target generation, and installation — lives in internal/ packages that cannot be imported from other modules. There is no supported way to drive GoMake programmatically, and that is by design.

The one public package, pkg/gomake, is not an entry point for building tooling on top of GoMake. It is a small toolkit of helpers for the code you write as GoMake targets: functions in a project’s makefile.go, or the external and built-in target packages compiled into the binary.

The only import you need

import "github.com/ctx42/gomake/pkg/gomake"

It is the only GoMake package a makefile.go or a target package needs — or is able — to import. A target itself is an ordinary function:

func Name(ctx context.Context, rng *ring.Ring) error

The ctx carries the running target’s name; the rng (ring.Ring) carries the arguments, environment, standard streams, and metadata. The pkg/gomake helpers operate on those values.

What’s in the toolkit

AreaHelpers
Target contextTargetName, WithTargetName
ConfigurationTargetConfig, ConfigMetaKey
Module & pathsRoot, PathExists, FileExists, DirExists, ReadFile
EnvironmentGetenv, LookupEnv, GetGOOS, GetGOARCH, EnvSplit, EnvJoin, EnvSplitOrdered, Expander, PrettyPrintEnv
Interactive inputReadLine, ReadChar
Errors & exit codesExitStatus, HasRun, ErrNoGoMod
ConstantsCCIDEnvKey, ProjectDirEnvKey, VersionEnvKey

Using the helpers in a target

package targets

import (
    "context"
    "fmt"

    "github.com/ctx42/ring/pkg/ring"

    "github.com/ctx42/gomake/pkg/gomake"
)

// Info reports details about the current invocation.
func Info(ctx context.Context, rng *ring.Ring) error {
    env := rng.EnvAll()

    name, _ := gomake.TargetName(ctx)
    root, err := gomake.Root(".")
    if err != nil {
        return err
    }

    fmt.Fprintf(
        rng.Stdout(),
        "target=%s goos=%s root=%s\n",
        name, gomake.GetGOOS(env), root,
    )
    return nil
}

TargetName reads the name the runtime set for this call, Root walks up to the module’s go.mod, and GetGOOS resolves the effective GOOS from the target’s environment (falling back to the runtime value).

Reading interactive input

ReadLine and ReadChar take any io.Reader, so a target can prompt the user:

func Confirm(ctx context.Context, rng *ring.Ring) error {
    fmt.Fprint(rng.Stdout(), "continue? [y/N] ")
    answer, err := gomake.ReadLine(os.Stdin)
    if err != nil {
        return err
    }
    if answer != "y" {
        return errors.New("aborted")
    }
    return nil
}

Browse the API

go doc github.com/ctx42/gomake/pkg/gomake
go doc github.com/ctx42/gomake/pkg/gomake Root

Runnable examples live in pkg/gomake/examples_test.go:

go test ./pkg/gomake -run '^Example'