rake

package module
v0.0.0-...-0e8cc46 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 17, 2026 License: BSD-3-Clause Imports: 6 Imported by: 0

README

go-ruby-rake/rake

rake — go-ruby-rake

Docs License Go Coverage

A pure-Go (no cgo) reimplementation of the task-graph core of Ruby's Rake — the rake-13.x gem's Rake::Task / Rake::FileTask, the Rake::TaskManager registry with namespace/scope resolution and rule synthesis, Rake::FileList filtering, and Rake::InvocationChain circular-dependency detection. It reproduces Rake's depth-first prerequisite-first invoke order, the invoke-once guard, circular detection, FileTask needed? timestamp logic, and namespace resolution — validated byte-for-byte against the real rake gem — without any Ruby runtime.

It is the Rake backend for go-embedded-ruby, but is a standalone, reusable module — a sibling of go-ruby-marshal, go-ruby-yaml, go-ruby-regexp, go-ruby-erb, and go-ruby-pstore.

What it is — and isn't. The pure-compute half of Rake — the task DAG, the depth-first prerequisite-first invoke order, the invoke-once guard, circular detection, FileTask out-of-date timestamp logic, namespace/scope lookup, rule synthesis, and FileList pattern/exclude filtering — is fully deterministic and needs no interpreter, so it lives here as plain Go. The effectful half — the action bodies (the do ... end blocks), sh / FileUtils, real Dir.glob, and file mtimes — are seams the host injects: an Action is a Go func rbgo wires to a Ruby block; FileTask timestamps come from an injected Stat function, and FileList globbing from an injected Glob function. Tests inject deterministic seams, so the whole suite is Ruby-free and reproducible across arches.

Features

Faithful port of Rake's task-graph semantics, validated against the rake gem (ruby -rrake, Rake 13.x) on every supported platform:

  • Depth-first, prerequisite-first invoke orderTask#invoke runs every prerequisite (ordinary then order-only, in declared order) before the task's own actions, depth-first, each task at most once (the @already_invoked guard); Reenable clears the guard, and a remembered failure is re-raised on a later invoke.
  • Circular-dependency detectionRake::InvocationChain raises with MRI's exact "Circular dependency detected: TOP => x => y => x" message.
  • FileTask#needed? — a file target is rebuilt when it is missing or older than any transitive prerequisite (or when build-all is forced); a missing file reports the Rake::LATE distant-future time stamp. Timestamps are injected, so the logic is tested deterministically.
  • Namespace / scope resolutionnamespace/task/file bookkeeping, define_task, lookup/[], embedded-namespace names ("a:b:c"), the "rake:" (top-level) and "^" (scope-trim) hints, synthesize_file_task, and the desc comment/description table.
  • Rule synthesisrule pattern => sources matches a task name, resolves each source (existing file / defined task / nested rule), and synthesizes a FileTask with those sources as prerequisites, guarding against runaway recursion (Rake::RuleRecursionOverflowError).
  • Rake::FileList — lazy include/exclude filtering with default ignore patterns; regexp, glob, literal, and predicate excludes; sub/ext/existing transforms. The actual Dir.glob is a seam.

CGO-free, 100% test coverage, gofmt + go vet clean, and green across the six 64-bit Go targets (amd64, arm64, riscv64, loong64, ppc64le, s390x) and three OSes (Linux, macOS, Windows).

Install

go get github.com/go-ruby-rake/rake

Usage

package main

import (
	"fmt"

	"github.com/go-ruby-rake/rake"
)

func main() {
	app := rake.NewApplication()

	var order []string
	rec := func(name string) rake.Action {
		return func(t rake.TaskItem, a rake.Args) error {
			order = append(order, name) // the action body is a seam; here a closure
			return nil
		}
	}

	// task :a ; task :b => :a ; task :top => [:b, :a]
	app.DefineTask(rake.PlainTask, "a", nil, nil, nil, rec("a"))
	app.DefineTask(rake.PlainTask, "b", nil, []string{"a"}, nil, rec("b"))
	top := app.DefineTask(rake.PlainTask, "top", nil, []string{"b", "a"}, nil, rec("top"))

	_ = top.(*rake.Task).Invoke()
	fmt.Println(order) // [a b top] — prerequisites first, each once
}

API

// Application is the task registry + namespace resolver (Rake::Application /
// Rake::TaskManager). Two seams hang off it: Stat (FileTask mtimes, File.mtime)
// and Glob (FileList expansion, Dir.glob).
func NewApplication() *Application
func (a *Application) DefineTask(kind TaskKind, name string, argNames, deps, orderOnly []string, action Action) TaskItem
func (a *Application) Get(taskName string) (TaskItem, error)            // Rake::Task[]
func (a *Application) Lookup(taskName string, scope *Scope) TaskItem    // straight scoped lookup
func (a *Application) TaskDefined(taskName string) bool
func (a *Application) Tasks() []TaskItem                                // sorted by name
func (a *Application) InNamespace(name string, body func(ns *NameSpace)) *NameSpace
func (a *Application) CreateRule(pattern string, argNames, deps, orderOnly []string, action Action)
func (a *Application) Desc(description string)

// Stat / Glob / BuildAll are the injected seams + flag.
type Application struct {
	Stat     func(name string) (time.Time, bool) // File.mtime seam
	Glob     func(pattern string) []string       // Dir.glob seam
	BuildAll bool                                 // --build-all
	// ...
}

// TaskItem is the behaviour shared by Task and FileTask.
type TaskItem interface {
	Name() string
	Needed() bool
	Timestamp() time.Time
	// ...
}

// Task (Rake::Task): the basic unit of work.
func (t *Task) Invoke(args ...string) error
func (t *Task) Execute(args Args) error
func (t *Task) Enhance(deps []string, action Action) *Task
func (t *Task) Reenable()
func (t *Task) PrerequisiteTasks() ([]TaskItem, error)
func (t *Task) Comment() string
func (t *Task) FullComment() string

// FileTask (Rake::FileTask): timestamp-driven; Needed/Timestamp override Task.
type FileTask struct{ *Task }

// Action is a task action body — the seam for a Ruby `do ... end` block.
type Action func(t TaskItem, args Args) error

// InvocationChain (Rake::InvocationChain): circular-dependency detection.
type InvocationChain struct{ /* … */ }
func (c *InvocationChain) Append(invocation string) (*InvocationChain, error)
type CircularDependencyError struct{ Message string }

// FileList (Rake::FileList): lazy include/exclude filtering; Glob is a seam.
func NewFileList(glob func(pattern string) []string, patterns ...string) *FileList
func (fl *FileList) Include(filenames ...string) *FileList
func (fl *FileList) Exclude(patterns ...string) *FileList
func (fl *FileList) To() []string

What rbgo binds

The host (rbgo) wires the seams to the real Ruby runtime and filesystem:

  • each Action invokes the corresponding Ruby task block (the do ... end body), where sh / FileUtils live;
  • Application.StatFile.mtime (FileTask freshness);
  • Application.GlobDir.glob (FileList expansion);
  • argument values flow through Args to Rake::TaskArguments.

Everything else — the DAG, the invoke order and once-guard, circular detection, FileTask needed?, namespace/scope/rule resolution, and FileList filtering — is this library.

Tests & coverage

The suite pairs deterministic, Ruby-free tests over the in-process task graph (which alone hold coverage at 100%, so the qemu cross-arch and Windows lanes pass the gate) with a differential rake-gem oracle: it replays the same task graphs through the real ruby -rrake and asserts identical invoke order, namespace resolution, the byte-exact circular-dependency message, and the three FileTask#needed? outcomes. The oracle scripts $stdout.binmode so Windows text-mode never corrupts the comparison, and skip themselves where ruby (or the rake gem) is absent.

COVERPKG=$(go list ./... | paste -sd, -)
go test -race -coverpkg="$COVERPKG" -coverprofile=cover.out ./...
go tool cover -func=cover.out | tail -1   # 100.0%

License

BSD-3-Clause — see LICENSE. Copyright the go-ruby-rake/rake authors.

Documentation

Overview

Package rake is a pure-Go (no cgo), MRI-faithful port of the task-graph core of Ruby's Rake (the rake-13.x gem): Rake::Task / Rake::FileTask, the Rake::TaskManager registry and namespace/scope resolution, Rake::FileList filtering, and Rake::InvocationChain circular-dependency detection.

What it is — and isn't. The *pure-compute* half of Rake — the task DAG, the depth-first prerequisite-first invoke order, the invoke-once guard, circular detection, FileTask out-of-date timestamp logic, namespace/scope lookup, rule synthesis, and FileList pattern/exclude filtering — is fully deterministic and needs no interpreter, so it lives here as plain Go. The *effectful* half — the action bodies (the `do ... end` blocks), `sh`/FileUtils, real Dir.glob, and file mtimes — are SEAMS the host injects: an Action is a Go func the host (rbgo) wires to a Ruby block; FileList.Glob and FileTask timestamps are function fields the host wires to the real filesystem. Tests inject deterministic seams, so the whole suite is Ruby-free and reproducible across arches.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Action

type Action func(t TaskItem, args Args) error

Action is a task's action body — the seam for a Ruby `do ... end` block. rbgo wires each Action to invoke the corresponding Ruby block (passing the task and its arguments); tests pass plain Go closures. An Action may return an error to abort the invocation (mirroring an exception escaping the block).

type Application

type Application struct {

	// RecordTaskMetadata mirrors TaskManager.record_task_metadata: when true,
	// define_task attaches the pending description to the task. MRI defaults it
	// off; the DSL turns it on. We default it on so desc/Comment round-trips.
	RecordTaskMetadata bool

	// BuildAll forces every FileTask to be considered out of date
	// (Rake's --build-all / options.build_all).
	BuildAll bool

	// Stat is the file-mtime seam (Rake::FileTask via File.mtime). It returns
	// the file's modification time and whether it exists. nil → always absent.
	Stat func(name string) (time.Time, bool)

	// Glob is the directory-glob seam (Rake::FileList.glob via Dir.glob). It
	// returns the names matching pattern. Results are sorted by FileList, as
	// MRI sorts Dir.glob output. nil → empty.
	Glob func(pattern string) []string
	// contains filtered or unexported fields
}

Application is the task registry and namespace resolver — the port of Rake::Application together with the Rake::TaskManager mixin. It owns the task table, the rule list, the live namespace scope, and the pending description.

Two seams hang off it: Stat resolves a file name to its mtime (for FileTask timestamps; rbgo wires File.mtime), and Glob lists files matching a pattern (for FileList; rbgo wires Dir.glob). Both are nil by default, which makes every file "absent" and every glob empty — fine for the pure task-graph tests.

func NewApplication

func NewApplication() *Application

NewApplication returns an empty task manager with the top-level scope active and metadata recording on (Rake::Application.new + TaskManager#initialize).

func (*Application) Clear

func (a *Application) Clear()

Clear forgets every task and rule (Rake::TaskManager#clear).

func (*Application) CreateRule

func (a *Application) CreateRule(pattern string, argNames, deps, orderOnly []string, action Action)

CreateRule registers a synthesis rule (Rake::TaskManager#create_rule). The string pattern is regexp-quoted and anchored at end-of-name (MRI quotes it and appends "$"), so it always compiles. deps are the source extensions/names, action the rule body.

func (*Application) CurrentScope

func (a *Application) CurrentScope() *Scope

CurrentScope returns the live namespace scope (Rake::TaskManager#current_scope).

func (*Application) DefineTask

func (a *Application) DefineTask(kind TaskKind, name string, argNames, deps, orderOnly []string, action Action) TaskItem

DefineTask defines (or, when one already exists, enhances) a task — the port of Rake::TaskManager#define_task. For a PlainTask whose name embeds namespace segments ("a:b:c"), the leading segments extend the scope used to key the task (MRI splits on ":" and folds the outer segments into the scope); a FileTask ignores the scope entirely (its name is the file path).

deps are the prerequisites, orderOnly the order-only prerequisites, argNames the declared argument names, and action an optional body. It returns the defined task.

func (*Application) Desc

func (a *Application) Desc(description string)

Desc records the description applied to the next defined task (Rake's `desc` DSL → last_description). It is consumed by the following DefineTask, then cleared.

func (*Application) Get

func (a *Application) Get(taskName string) (TaskItem, error)

Get resolves a task by name (Rake::TaskManager#[]): a straight lookup, else rule synthesis, else a file-task synthesized from an existing file, else the "Don't know how to build task" error.

func (*Application) InNamespace

func (a *Application) InNamespace(name string, body func(ns *NameSpace)) *NameSpace

InNamespace evaluates body with name pushed onto the scope, returning a NameSpace over the nested scope (Rake::TaskManager#in_namespace). A nil/empty name yields an anonymous "_anon_N" namespace.

func (*Application) Lookup

func (a *Application) Lookup(taskName string, initialScope *Scope) TaskItem

Lookup performs a straight scoped lookup with no rule/file synthesis (Rake::TaskManager#lookup). It honours the scope hints in the name: "rake:NAME" resolves at top level, "^…" trims that many scope levels. A nil scope means the current scope.

func (*Application) TaskDefined

func (a *Application) TaskDefined(taskName string) bool

TaskDefined reports whether a task with the name is already registered (Rake::Task.task_defined? → lookup != nil).

func (*Application) Tasks

func (a *Application) Tasks() []TaskItem

Tasks returns every defined task sorted by name (Rake::TaskManager#tasks).

func (*Application) TasksInScope

func (a *Application) TasksInScope(scope *Scope) []TaskItem

TasksInScope returns the tasks defined in scope and its sub-scopes (Rake::TaskManager#tasks_in_scope — names prefixed by "scope:").

type Args

type Args struct {
	// contains filtered or unexported fields
}

Args carries a task's invocation arguments by name — the pure-compute slice of Rake::TaskArguments (the bookkeeping; value coercion stays in the host).

func NewArgs

func NewArgs(names, values []string) Args

NewArgs pairs argument names with the values passed to invoke (Rake::TaskArguments.new). Extra values past the named slots are ignored for lookup but preserved; missing values yield "".

func (Args) Lookup

func (a Args) Lookup(name string) string

Lookup returns the value bound to argument name, or "" if unbound (Rake::TaskArguments#[]).

func (Args) Names

func (a Args) Names() []string

Names returns the declared argument names.

func (Args) Values

func (a Args) Values() []string

Values returns the supplied argument values.

type CircularDependencyError

type CircularDependencyError struct {
	Message string
}

CircularDependencyError is the RuntimeError Rake raises when a task's prerequisite graph contains a cycle. Message is byte-for-byte MRI's "Circular dependency detected: TOP => x => y => x".

func (*CircularDependencyError) Error

func (e *CircularDependencyError) Error() string

type FileList

type FileList struct {
	// contains filtered or unexported fields
}

FileList is a lazily-resolved list of file names — the port of Rake::FileList. Include records glob patterns and literal names; Exclude records patterns (regexp, glob, literal, or predicate) to filter out. Resolution is deferred: the patterns are expanded (via the Glob seam) and the excludes applied only when the list is observed (To / Resolve). The actual Dir.glob is the seam — a func(pattern) []string injected at construction; everything else (literal adds, default ignores, exclude filtering) is pure.

func NewFileList

func NewFileList(glob func(pattern string) []string, patterns ...string) *FileList

NewFileList creates a FileList over the given include patterns, expanding globs through glob (the Dir.glob seam; nil → no expansion). It seeds the default ignore patterns, exactly as Rake::FileList#initialize does.

func (*FileList) ClearExclude

func (fl *FileList) ClearExclude() *FileList

ClearExclude drops every exclude pattern and predicate, including the default ignores (Rake::FileList#clear_exclude). Returns fl.

func (*FileList) Exclude

func (fl *FileList) Exclude(patterns ...string) *FileList

Exclude records patterns to remove (Rake::FileList#exclude). A pattern with glob metacharacters is matched as a glob, otherwise as a literal name; use ExcludeRegexp for a regexp and ExcludeFunc for a predicate. When nothing is pending, the exclusion is applied immediately (MRI's resolve_exclude unless @pending). Returns fl.

func (*FileList) ExcludeFunc

func (fl *FileList) ExcludeFunc(fn func(string) bool) *FileList

ExcludeFunc records a predicate exclude — entries for which fn returns true are removed (the block form of Rake::FileList#exclude). Returns fl.

func (*FileList) ExcludeRegexp

func (fl *FileList) ExcludeRegexp(res ...*regexp.Regexp) *FileList

ExcludeRegexp records a regexp exclude (the Regexp branch of Rake::FileList#exclude). Returns fl.

func (*FileList) Existing

func (fl *FileList) Existing(exists func(string) bool) *FileList

Existing returns a new list of the entries that exist on the filesystem (Rake::FileList#existing → File.exist?), via the Stat-like exists predicate. exists is the filesystem seam (rbgo wires File.exist?); nil → nothing exists.

func (*FileList) Ext

func (fl *FileList) Ext(newExt string) *FileList

Ext returns a new list with each entry's file extension swapped to newExt (Rake::FileList#ext → String#ext).

func (*FileList) Include

func (fl *FileList) Include(filenames ...string) *FileList

Include records file names / glob patterns to add (Rake::FileList#include). Resolution is deferred until the list is observed. Returns fl.

func (*FileList) Resolve

func (fl *FileList) Resolve() *FileList

Resolve expands pending includes (globs via the seam, literals verbatim) and applies the excludes (Rake::FileList#resolve). Idempotent until the next Include. Returns fl.

func (*FileList) String

func (fl *FileList) String() string

String resolves and joins the list with spaces (Rake::FileList#to_s).

func (*FileList) Sub

func (fl *FileList) Sub(re *regexp.Regexp, rep string) *FileList

Sub returns a new list with re→rep applied to every entry (Rake::FileList#sub).

func (*FileList) To

func (fl *FileList) To() []string

To resolves the list and returns its file names (Rake::FileList#to_a).

type FileTask

type FileTask struct {
	*Task
}

FileTask is a task with time-based dependencies — the port of Rake::FileTask. It rebuilds (its actions run) when its target file is missing or older than any prerequisite. The file system is a SEAM: the owning Application's Stat function maps a name to (mtime, exists); rbgo wires it to File.mtime, tests inject a deterministic map.

func (*FileTask) Needed

func (f *FileTask) Needed() bool

Needed reports whether the target must be rebuilt — true if it is missing or out of date against any prerequisite, or when build-all is forced (Rake::FileTask#needed?).

func (*FileTask) Timestamp

func (f *FileTask) Timestamp() time.Time

Timestamp is the target file's mtime, or the LATE sentinel when the file is absent (Rake::FileTask#timestamp — rescue Errno::ENOENT → Rake::LATE).

type InvocationChain

type InvocationChain struct {
	// contains filtered or unexported fields
}

InvocationChain tracks the chain of task invocations to detect circular dependencies — the port of Rake::InvocationChain (itself a LinkedList subclass). It is an immutable cons-list of task names; the empty chain (nil) renders as "TOP" (Rake::InvocationChain::EMPTY).

var EmptyChain *InvocationChain

EmptyChain is the Null Object for an empty chain (Rake::InvocationChain::EMPTY).

func (*InvocationChain) Append

func (c *InvocationChain) Append(invocation string) (*InvocationChain, error)

Append returns a new chain with invocation appended, or an error if invocation already appears — Rake's "Circular dependency detected" guard (Rake::InvocationChain#append, which fails with RuntimeError). The returned error is a *CircularDependencyError carrying the exact MRI message.

func (*InvocationChain) Member

func (c *InvocationChain) Member(invocation string) bool

Member reports whether invocation is already somewhere in the chain (Rake::InvocationChain#member?). The empty chain contains nothing.

func (*InvocationChain) String

func (c *InvocationChain) String() string

String renders the chain TOP => a => b (Rake::InvocationChain#to_s). The empty chain is "TOP".

type NameSpace

type NameSpace struct {
	// contains filtered or unexported fields
}

NameSpace is the lookup object returned by InNamespace (Rake::NameSpace): it resolves names within, and lists the tasks of, a captured scope.

func (*NameSpace) Get

func (n *NameSpace) Get(name string) TaskItem

Get resolves name within the namespace's scope (Rake::NameSpace#[]).

func (*NameSpace) Scope

func (n *NameSpace) Scope() *Scope

Scope returns the namespace's scope (Rake::NameSpace#scope).

func (*NameSpace) Tasks

func (n *NameSpace) Tasks() []TaskItem

Tasks lists the tasks defined in this and nested namespaces (Rake::NameSpace#tasks).

type RuleRecursionOverflowError

type RuleRecursionOverflowError struct{ Target string }

RuleRecursionOverflowError is Rake::RuleRecursionOverflowError — raised when rule synthesis recurses past 16 levels.

func (*RuleRecursionOverflowError) Error

type Scope

type Scope struct {
	// contains filtered or unexported fields
}

Scope is Rake's namespace stack — the port of Rake::Scope, which in MRI is a LinkedList subclass used as an immutable cons-list of namespace names. The head is the innermost namespace; the empty scope (Scope == nil) is the top-level / Null Object (Rake::Scope::EMPTY).

Like MRI it is a persistent (immutable) singly-linked list: Cons returns a fresh head sharing the same tail, so a saved Scope is never mutated by a later namespace push/pop.

func ScopeMake

func ScopeMake(names ...string) *Scope

ScopeMake builds a scope from names given outermost-first (Rake::Scope.make is called innermost-first; the manager builds it from a reversed split, so this helper takes the natural outer→inner order the caller already has).

func (*Scope) Cons

func (s *Scope) Cons(name string) *Scope

Cons returns a new scope with name pushed onto s (MRI Scope#conj / cons). Calling on a nil (empty) scope starts a one-element scope.

func (*Scope) Empty

func (s *Scope) Empty() bool

Empty reports whether s is the top-level (Null Object) scope.

func (*Scope) Head

func (s *Scope) Head() string

Head returns the innermost namespace name (empty string for the empty scope).

func (*Scope) Path

func (s *Scope) Path() string

Path is Rake::Scope#path — the namespace names joined outer:inner by ":". The empty scope's path is "".

func (*Scope) PathWithTaskName

func (s *Scope) PathWithTaskName(taskName string) string

PathWithTaskName is Rake::Scope#path_with_task_name — the scope path prefixed onto taskName. The empty scope returns taskName unchanged (EmptyScope).

func (*Scope) Tail

func (s *Scope) Tail() *Scope

Tail returns the enclosing scope (nil for the empty scope; MRI returns EMPTY, whose tail is itself).

func (*Scope) Trim

func (s *Scope) Trim(n int) *Scope

Trim drops the n innermost scope levels (Rake::Scope#trim). It never trims past the top-level scope.

type Task

type Task struct {
	// contains filtered or unexported fields
}

Task is the basic unit of work — the port of Rake::Task. It carries a name, prerequisites (ordinary and order-only), action bodies, the already-invoked guard, and the owning application for prerequisite lookup.

func (*Task) Actions

func (t *Task) Actions() []Action

Actions returns the task's action bodies (Rake::Task#actions).

func (*Task) AddOrderOnly

func (t *Task) AddOrderOnly(deps []string) *Task

AddOrderOnly adds order-only prerequisites — the union minus any already an ordinary prerequisite (Rake::Task#| ). Returns t.

func (*Task) AlreadyInvoked

func (t *Task) AlreadyInvoked() bool

AlreadyInvoked reports whether invoke has already run (Rake::Task#already_invoked).

func (*Task) ArgNames

func (t *Task) ArgNames() []string

ArgNames returns the declared argument names (Rake::Task#arg_names).

func (*Task) Clear

func (t *Task) Clear() *Task

Clear empties prerequisites, actions, comments, and arguments (Rake::Task#clear).

func (*Task) Comment

func (t *Task) Comment() string

Comment is the first sentence of each comment joined by " / " (Rake::Task#comment).

func (*Task) Enhance

func (t *Task) Enhance(deps []string, action Action) *Task

Enhance adds prerequisites (union, preserving order) and an optional action, returning t — Rake::Task#enhance.

func (*Task) Execute

func (t *Task) Execute(args Args) error

Execute runs the task's actions unconditionally (Rake::Task#execute), in the order they were added. With no actions it is a no-op (after rule enhancement, handled by the manager). args are passed to each action.

func (*Task) FullComment

func (t *Task) FullComment() string

FullComment joins all comments with newlines, or "" when there are none (Rake::Task#full_comment).

func (*Task) Invoke

func (t *Task) Invoke(args ...string) error

Invoke runs the task, prerequisites first, under a fresh invocation chain — Rake::Task#invoke. args are the positional argument values bound to the task's declared arg names.

func (*Task) Name

func (t *Task) Name() string

Name returns the task's fully-qualified name (Rake::Task#name).

func (*Task) Needed

func (t *Task) Needed() bool

Needed reports whether a basic task's actions must run — always true (Rake::Task#needed?). FileTask overrides this.

func (*Task) OrderOnlyPrerequisites

func (t *Task) OrderOnlyPrerequisites() []string

OrderOnlyPrerequisites returns the order-only prerequisite names (Rake::Task#order_only_prerequisites).

func (*Task) PrerequisiteTasks

func (t *Task) PrerequisiteTasks() ([]TaskItem, error)

PrerequisiteTasks resolves every prerequisite (ordinary then order-only) to its task via the application — Rake::Task#prerequisite_tasks. A prerequisite is looked up scoped first; if that resolves to t itself, the unscoped lookup is preferred (MRI's lookup_prerequisite, which lets a task depend on a same-named task in an outer scope).

func (*Task) Prerequisites

func (t *Task) Prerequisites() []string

Prerequisites returns the ordinary prerequisite names (Rake::Task#prerequisites).

func (*Task) Reenable

func (t *Task) Reenable()

Reenable clears the already-invoked guard so the task runs again on the next invoke (Rake::Task#reenable).

func (*Task) Scope

func (t *Task) Scope() *Scope

Scope returns the namespace scope the task was defined in (Rake::Task#scope).

func (*Task) Source

func (t *Task) Source() string

Source is the first source, or "" when there are none (Rake::Task#source).

func (*Task) Sources

func (t *Task) Sources() []string

Sources returns the task's sources, defaulting to its prerequisites when no explicit sources were set (Rake::Task#sources).

func (*Task) Timestamp

func (t *Task) Timestamp() time.Time

Timestamp is a basic task's time stamp — the current time (Rake::Task#timestamp). FileTask overrides this.

type TaskItem

type TaskItem interface {
	// Name is the fully-qualified task name (namespace-prefixed).
	Name() string
	// Needed reports whether the task's actions must run (Task#needed?:
	// always true; FileTask#needed?: out-of-date timestamp logic).
	Needed() bool
	// Timestamp is the task's time stamp (Task#timestamp: now; FileTask: the
	// file mtime, or the distant-future LATE sentinel when absent).
	Timestamp() time.Time
	// contains filtered or unexported methods
}

TaskItem is the behaviour every task kind exposes — Rake::Task and its subclass Rake::FileTask. It is the interface a prerequisite is resolved to, so the manager and the invoke walk treat plain tasks and file tasks uniformly.

type TaskKind

type TaskKind int

TaskKind selects which Task subclass define_task creates — a plain task (`task`) or a file task (`file`). It is the Go stand-in for the task_class argument MRI's TaskManager#define_task receives.

const (
	// PlainTask is Rake::Task — namespace-scoped, always-needed.
	PlainTask TaskKind = iota
	// File is Rake::FileTask — file-name-keyed, timestamp-driven, scope-ignoring.
	FileKind
)

type UndefinedTaskError

type UndefinedTaskError struct{ Name string }

UndefinedTaskError is the error Get raises for an unknown task. Message mirrors MRI's "Don't know how to build task '…'".

func (*UndefinedTaskError) Error

func (e *UndefinedTaskError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL