}
// Ultimately the goal is to print the output.
- root := &work.Action{Mode: "go test", Func: printExitStatus, Deps: prints}
+ root := &work.Action{Mode: "go test", Actor: work.ActorFunc(printExitStatus), Deps: prints}
// Force the printing of results to happen in order,
// one at a time.
build := b.CompileAction(work.ModeBuild, work.ModeBuild, p)
run := &work.Action{Mode: "test run", Package: p, Deps: []*work.Action{build}}
addTestVet(b, p, run, nil)
- print := &work.Action{Mode: "test print", Func: builderNoTest, Package: p, Deps: []*work.Action{run}}
+ print := &work.Action{Mode: "test print", Actor: work.ActorFunc(builderNoTest), Package: p, Deps: []*work.Action{run}}
return build, run, print, nil
}
pmain.Target = target
installAction = &work.Action{
Mode: "test build",
- Func: work.BuildInstallFunc,
+ Actor: work.ActorFunc(work.BuildInstallFunc),
Deps: []*work.Action{buildAction},
Package: pmain,
Target: target,
c := new(runCache)
runAction = &work.Action{
Mode: "test run",
- Func: c.builderRunTest,
+ Actor: work.ActorFunc(c.builderRunTest),
Deps: []*work.Action{buildAction},
Package: p,
IgnoreFail: true, // run (prepare output) even if build failed
vetRunAction = runAction
cleanAction = &work.Action{
Mode: "test clean",
- Func: builderCleanTest,
+ Actor: work.ActorFunc(builderCleanTest),
Deps: []*work.Action{runAction},
Package: p,
IgnoreFail: true, // clean even if test failed
}
printAction = &work.Action{
Mode: "test print",
- Func: builderPrintTest,
+ Actor: work.ActorFunc(builderPrintTest),
Deps: []*work.Action{cleanAction},
Package: p,
IgnoreFail: true, // print even if test failed
// NOTE: Much of Action would not need to be exported if not for test.
// Maybe test functionality should move into this package too?
+// An Actor runs an action.
+type Actor interface {
+ Act(*Builder, context.Context, *Action) error
+}
+
+// An ActorFunc is an Actor that calls the function.
+type ActorFunc func(*Builder, context.Context, *Action) error
+
+func (f ActorFunc) Act(b *Builder, ctx context.Context, a *Action) error {
+ return f(b, ctx, a)
+}
+
// An Action represents a single action in the action graph.
type Action struct {
- Mode string // description of action operation
- Package *load.Package // the package this action works on
- Deps []*Action // actions that must happen before this one
- Func func(*Builder, context.Context, *Action) error // the action itself (nil = no-op)
- IgnoreFail bool // whether to run f even if dependencies fail
- TestOutput *bytes.Buffer // test output buffer
- Args []string // additional args for runProgram
+ Mode string // description of action operation
+ Package *load.Package // the package this action works on
+ Deps []*Action // actions that must happen before this one
+ Actor Actor // the action itself (nil = no-op)
+ IgnoreFail bool // whether to run f even if dependencies fail
+ TestOutput *bytes.Buffer // test output buffer
+ Args []string // additional args for runProgram
triggers []*Action // inverse of deps
a := &Action{
Mode: "build",
Package: p,
- Func: (*Builder).build,
+ Actor: ActorFunc((*Builder).build),
Objdir: b.NewObjdir(),
}
case "builtin", "unsafe":
// Fake packages - nothing to build.
a.Mode = "built-in package"
- a.Func = nil
+ a.Actor = nil
return a
}
// the target name is needed for cgo.
a.Mode = "gccgo stdlib"
a.Target = p.Target
- a.Func = nil
+ a.Actor = nil
return a
}
}
VetxOnly: true,
IgnoreFail: true, // it's OK if vet of dependencies "fails" (reports problems)
}
- if a1.Func == nil {
+ if a1.Actor == nil {
// Built-in packages like unsafe.
return a
}
deps[0].needVet = true
- a.Func = (*Builder).vet
+ a.Actor = ActorFunc((*Builder).vet)
return a
})
return a
}
a1 := b.CompileAction(ModeBuild, depMode, p)
- a.Func = (*Builder).link
+ a.Actor = ActorFunc((*Builder).link)
a.Deps = []*Action{a1}
a.Objdir = a1.Objdir
// If there's no actual action to build a1,
// there's nothing to install either.
// This happens if a1 corresponds to reusing an already-built object.
- if a1.Func == nil {
+ if a1.Actor == nil {
return a1
}
// on the install.
*a1 = Action{
Mode: buildAction.Mode + "-install",
- Func: BuildInstallFunc,
+ Actor: ActorFunc(BuildInstallFunc),
Package: p,
Objdir: buildAction.Objdir,
Deps: []*Action{buildAction},
Mode: "install header",
Package: a.Package,
Deps: []*Action{a.Deps[0]},
- Func: (*Builder).installHeader,
+ Actor: ActorFunc((*Builder).installHeader),
Objdir: a.Deps[0].Objdir,
Target: hdrTarget,
}
Mode: "go build -buildmode=shared",
Package: p,
Objdir: b.NewObjdir(),
- Func: (*Builder).linkShared,
+ Actor: ActorFunc((*Builder).linkShared),
Deps: []*Action{a1},
}
a.Target = filepath.Join(a.Objdir, shlib)
})
// Install result.
- if (mode == ModeInstall || mode == ModeBuggyInstall) && a.Func != nil {
+ if (mode == ModeInstall || mode == ModeBuggyInstall) && a.Actor != nil {
buildAction := a
a = b.cacheAction("install-shlib "+shlib, nil, func() *Action {
a := &Action{
Mode: "go install -buildmode=shared",
Objdir: buildAction.Objdir,
- Func: BuildInstallFunc,
+ Actor: ActorFunc(BuildInstallFunc),
Deps: []*Action{buildAction},
Target: target,
}
a.Deps = append(a.Deps, &Action{
Mode: "shlibname",
Package: p,
- Func: (*Builder).installShlibname,
+ Actor: ActorFunc((*Builder).installShlibname),
Target: filepath.Join(pkgTargetRoot, p.ImportPath+".shlibname"),
Deps: []*Action{a.Deps[0]},
})