Documentation
¶
Index ¶
- Variables
- func Compile(ctx context.Context, pkgdir, binfile string) error
- func GetForce(ctx context.Context) bool
- func GetVerbose(ctx context.Context) bool
- func Indentf(ctx context.Context, format string, args ...any)
- func RegistryNames() []string
- func Run(ctx context.Context, targets ...Target) error
- func ToRelPath(pkgdir string) (string, error)
- func Unique(s string) string
- func WithForce(ctx context.Context, force bool) context.Context
- func WithHashDB(ctx context.Context, db HashDB) context.Context
- func WithRunner(ctx context.Context, r *Runner) context.Context
- func WithVerbose(ctx context.Context, verbose bool) context.Context
- type CommandErr
- type CommandOpt
- type FilesTarget
- type HashDB
- type HashTarget
- type Main
- type Namer
- type Runner
- type Target
- func All(targets ...Target) Target
- func Clean(files ...string) Target
- func Command(cmd string, opts ...CommandOpt) Target
- func Deps(target Target, depTargets ...Target) Target
- func F(f func(context.Context) error) Target
- func Register(name, doc string, target Target) Target
- func RegistryTarget(name string) (Target, string)
- func Seq(targets ...Target) Target
Constants ¶
This section is empty.
Variables ¶
var DefaultRunner = NewRunner()
DefaultRunner is a Runner used by default in Run.
Functions ¶
func Compile ¶ added in v0.8.0
Compile compiles a "driver" from a directory of user code (combined with a main function supplied by fab) and places the executable result in a given file. The driver converts command-line target names into the necessary Fab rule invocations.
The package of user code should contain one or more exported identifiers whose types satisfy the Target interface. These become the build rules that the driver can invoke.
When Compile runs the "go" program must exist in the user's PATH. It must be Go version 1.19 or later.
How it works:
- The user's code is loaded with packages.Load.
- The set of exported top-level identifiers is filtered to find those implementing the fab.Target interface.
- The user's code is then copied to a temp directory together with a main package (and main() function) that registers (with Register) that set of targets.
- The go compiler is invoked to produce an executable, which is renamed into place as binfile.
For the synthesized calls to Register on Target-valued variables, the driver uses the variable's name as the "name" argument and the variable's doc comment as the "doc" argument.
The user's code is able to make its own calls to Register during program initialization in order to augment the set of available targets.
func GetForce ¶ added in v0.16.0
GetForce returns the value of the force boolean added to `ctx` with WithForce. The default, if WithForce was not used, is false.
func GetVerbose ¶
GetVerbose returns the value of the verbose boolean added to `ctx` with WithVerbose. The default, if WithVerbose was not used, is false.
func Indentf ¶ added in v0.9.0
Indentf calls Runner.Indent with the given format and args if a Runner can be found in the given context. If one cannot, then the formatted string is simply printed (with a trailing newline added if needed).
func RegistryNames ¶ added in v0.21.0
func RegistryNames() []string
RegistryNames returns the names in the registry.
func Run ¶
Run runs the given targets with a Runner. If `ctx` contains a Runner (e.g., because this call is nested inside a pending call to Runner.Run and the context has been decorated using WithRunner) then it uses that Runner, otherwise it uses DefaultRunner.
func ToRelPath ¶ added in v0.20.0
ToRelPath converts a Go package directory to a relative path beginning with ./ (suitable for use in a call to packages.Load, for example). It is an error for pkgdir to be outside the current working directory's tree.
func Unique ¶ added in v0.23.0
Unique produces a unique string by appending a unique counter value to the given prefix. For example, Unique("foo") might produce "foo-17".
func WithForce ¶ added in v0.16.0
WithForce decorates a context with the value of a "force" boolean. Retrieve it with GetForce.
func WithHashDB ¶
WithHashDB decorates a context with a HashDB. Retrieve it with GetHashDB.
func WithRunner ¶
WithRunner decorates a context with a Runner. Retrieve it with GetRunner.
Types ¶
type CommandErr ¶
CommandErr is a type of error that may be returned from command.Run. If the command's Stdout or Stderr field was nil, then that output from the subprocess is in CommandErr.Output and the underlying error is in CommandErr.Err.
type CommandOpt ¶ added in v0.23.0
type CommandOpt func(*command)
func CmdArgs ¶ added in v0.23.0
func CmdArgs(args ...string) CommandOpt
CmdArgs sets the arguments for the command to run. When this option is used, the string passed to Command is used as argument 0 (i.e., the command name).
func CmdDir ¶ added in v0.23.0
func CmdDir(dir string) CommandOpt
CmdDir sets the working directory for the command.
func CmdEnv ¶ added in v0.23.0
func CmdEnv(env []string) CommandOpt
CmdEnv adds to the environment variables for the command.
func CmdStderr ¶ added in v0.23.0
func CmdStderr(w io.Writer) CommandOpt
CmdStderr sets the stderr for the command.
func CmdStdout ¶ added in v0.23.0
func CmdStdout(w io.Writer) CommandOpt
CmdStdout sets the stdout for the command.
type FilesTarget ¶ added in v0.13.0
FilesTarget is a HashTarget. It contains a list of input files, and a list of expected output files. It also contains an embedded Target whose Run method should produce the expected output files.
The FilesTarget's hash is computed from the target and all the input and output files. If none of those have changed since the last time the output files were built, then the output files are up to date and running of this FilesTarget can be skipped.
The Target must be of a type that can be JSON-marshaled.
The In list should mention every file where a change should cause a rebuild. Ideally this includes any files required by the Target's Run method, plus any transitive dependencies. See the deps package for helper functions that can compute dependency lists of various kinds.
type HashDB ¶
type HashDB interface {
// Has tells whether the database contains the given entry.
Has(context.Context, []byte) (bool, error)
// Add adds an entry to the database.
Add(context.Context, []byte) error
}
HashDB is the type of a database for storing hashes. It must permit concurrent operations safely. It may expire entries to save space.
type HashTarget ¶
HashTarget is a Target that knows how to produce a hash (or "digest") representing the complete state of the target: the inputs, the outputs, and the rules for turning one into the other. Any change in any of those should produce a distinct hash value.
When a HashTarget is executed by Runner.Run, its Run method is skipped and it succeeds trivially if the Runner can determine that the outputs are up to date with respect to the inputs and build rules. It does this by consulting a HashDB that is populated with the hashes of HashTargets whose Run methods succeeded in the past.
Using such a hash to decide whether a target's outputs are up to date is preferable to using file modification times (like Make does, for example). Those aren't always sufficient for this purpose, nor are they entirely reliable, considering the limited resolution of filesystem timestamps, the possibility of clock skew, etc.
type Main ¶ added in v0.11.0
type Main struct {
// Pkgdir is where to find the user's build-rules Go package, e.g. "fab.d".
Pkgdir string
// Fabdir is where to find the user's hash DB and compiled binaries, default $HOME/.fab.
Fabdir string
// Verbose tells whether to run the driver in verbose mode
// (by supplying the -v command-line flag).
Verbose bool
// List tells whether to run the driver in list-targets mode
// (by supplying the -list command-line flag).
List bool
// Force tells whether to force recompilation of the driver before running it.
Force bool
// Args contains the additional command-line arguments to pass to the driver, e.g. target names.
Args []string
}
Main is the structure whose Run methods implements the main logic of the fab command.
func (Main) Run ¶ added in v0.11.0
Run executes the main logic of the fab command. A driver binary with a name matching m.Pkgdir is sought in m.Fabdir. If it does not exist, or if its corresponding dirhash is wrong (i.e., out of date with respect to the user's code), or if m.Force is true, it is created with Compile. It is then invoked with the command-line arguments indicated by the fields of m. Typically this will include one or more target names, in which case the driver will execute the associated rules as defined by the code in m.Pkgdir.
type Namer ¶ added in v0.23.0
type Namer struct {
// contains filtered or unexported fields
}
Namer aids in giving unique names to objects. It implements the Name and SetName methods needed by Target. Most Target implementations will want to embed a *Namer and initialize it with a call to NewNamer.
func (*Namer) Name ¶ added in v0.23.0
Name returns the name in the Namer. This is the string from the latest call to SetName. If SetName has never been called, then the Namer's name is first set to its "base" name (which was set with NewNamer) passed through a call to Unique. E.g. NewNamer("foo").Name() might produce "foo-17".
type Runner ¶
type Runner struct {
// contains filtered or unexported fields
}
Runner is an object that knows how to run Targets without ever running the same Target twice.
A zero runner is not usable. Use NewRunner to obtain one instead.
func GetRunner ¶
GetRunner returns the value of the Runner added to `ctx` with WithRunner. The default, if WithRunner was not used, is nil.
func (*Runner) Indentf ¶ added in v0.8.0
Indentf formats and prints its arguments with leading indentation based on the nesting depth of the Runner. The nesting depth increases with each call to Runner.Run and decreases at the end of the call.
A newline is added to the end of the string if one is not already there.
func (*Runner) Run ¶
Run runs the given targets, skipping any that have already run.
A Runner remembers which targets it has already run (whether in this call or any previous call to Run), distinguishing them by their Name() values.
The targets are executed concurrently. A separate goroutine is created for each one passed to Run. If the Runner has never yet run the Target, it does so, and caches the result (error or no error). If the Target did already run, the cached error value is used. If another goroutine concurrently requests the same Target, it blocks until the first one completes, then uses the first one's result.
As a special case, if the Target is a HashTarget and there is a HashDB attached to the context, then the HashTarget's hash is computed and looked up in the HashDB. If it's found, the target's outputs are already up to date and its Run method can be skipped. Otherwise, Run is invoked and (if it succeeds) a new hash is computed for the target and added to the HashDB.
This function waits for all goroutines to complete. The return value may be an accumulation of multiple errors. These can be retrieved with multierr.Errors.
The runner is added to the context with WithRunner and can be retrieved with GetRunner. Calls to Run (the global function, not the Runner.Run method) will use it instead of DefaultRunner by finding it in the context.
type Target ¶
type Target interface {
// Run invokes the target's logic.
//
// Callers generally should not invoke a target's Run method.
// Instead, pass the target to a Runner's Run method,
// or to the global Run function.
// That will handle concurrency properly
// and make sure that the target is not rerun
// when it doesn't need to be.
Run(context.Context) error
// Name is a unique name for the target.
// Each instance of each Target must have a persistent, unique name.
// You can embed a *Namer in your concrete type to achieve this.
Name() string
// SetName sets the name of this target.
// The name must be unique across all targets.
SetName(string)
}
Target is the interface that Fab targets must implement.
func Clean ¶ added in v0.18.0
Clean is a Target that deletes the files named in Files when it runs. Files that don't exist are silently ignored.
func Command ¶
func Command(cmd string, opts ...CommandOpt) Target
Command is a target whose Run function executes a command in a subprocess.
If `CmdArgs` appears among the options, then `cmd` is the name of a command to run and its arguments are given by the `CmdArgs` option. Otherwise `cmd` is the complete command and is parsed as if by a Unix shell, with quoting and so on (but not tilde escapes or backtick substitution etc.) in order to produce the command name and argument list.
func Deps ¶ added in v0.3.0
Deps wraps a target with a set of dependencies, making sure those run first.
It is equivalent to Seq(All(depTargets...), target).
func Register ¶ added in v0.21.0
Register places a target in the registry with a given name and doc string.
func RegistryTarget ¶ added in v0.21.0
RegistryTarget returns the target in the registry with the given name, and its doc string.