Skip to content

Commit

Permalink
keep going flag
Browse files Browse the repository at this point in the history
  • Loading branch information
goddenrich committed Oct 25, 2023
1 parent 917f233 commit 88c6000
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 14 deletions.
1 change: 1 addition & 0 deletions src/build/build_step.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ func Build(state *core.BuildState, target *core.BuildTarget, remote bool) {
log.Errorf("Failed to remove outputs for %s: %s", target.Label, err)
}
target.SetState(core.Failed)
target.FinishBuild()
return
}
if remote {
Expand Down
30 changes: 17 additions & 13 deletions src/core/build_target.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,19 +309,20 @@ type BuildTargetState uint8

// The available states for a target.
const (
Inactive BuildTargetState = iota // Target isn't used in current build
Semiactive // Target would be active if we needed a build
Active // Target is going to be used in current build
Pending // Target is ready to be built but not yet started.
Building // Target is currently being built
Stopped // We stopped building the target because we'd gone as far as needed.
Built // Target has been successfully built
Cached // Target has been retrieved from the cache
Unchanged // Target has been built but hasn't changed since last build
Reused // Outputs of previous build have been reused.
BuiltRemotely // Target has been built but outputs are not necessarily local.
ReusedRemotely // Outputs of previous remote action have been reused.
Failed // Target failed for some reason
Inactive BuildTargetState = iota // Target isn't used in current build
Semiactive // Target would be active if we needed a build
Active // Target is going to be used in current build
Pending // Target is ready to be built but not yet started.
Building // Target is currently being built
Stopped // We stopped building the target because we'd gone as far as needed.
Built // Target has been successfully built
Cached // Target has been retrieved from the cache
Unchanged // Target has been built but hasn't changed since last build
Reused // Outputs of previous build have been reused.
BuiltRemotely // Target has been built but outputs are not necessarily local.
ReusedRemotely // Outputs of previous remote action have been reused.
DependencyFailed // At least one dependency of this target has failed.
Failed // Target failed for some reason
)

// String implements the fmt.Stringer interface.
Expand All @@ -338,6 +339,7 @@ func (s BuildTargetState) String() string {
return "Building"
} else if s == Stopped {
return "Stopped"

Check failure on line 342 in src/core/build_target.go

View workflow job for this annotation

GitHub Actions / lint

unnecessary trailing newline (whitespace)
} else if s == Built {
return "Built"
} else if s == Cached {
Expand All @@ -346,6 +348,8 @@ func (s BuildTargetState) String() string {
return "Unchanged"
} else if s == Reused {
return "Reused"
} else if s == DependencyFailed {
return "Dependency Failed"
} else if s == Failed {
return "Failed"
} else if s == BuiltRemotely {
Expand Down
9 changes: 9 additions & 0 deletions src/core/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ type BuildState struct {
Arch cli.Arch
// Aggregated coverage for this run
Coverage TestCoverage
// True if we want to keep going on build failures and not exit early on the first error encountered
KeepGoing bool
// True if we require rule hashes to be correctly verified (usually the case).
VerifyHashes bool
// True if tests should calculate coverage metrics
Expand Down Expand Up @@ -1141,6 +1143,13 @@ func (state *BuildState) queueTargetAsync(target *BuildTarget, forceBuild, build
if building {
for _, t := range target.Dependencies() {
t.WaitForBuild()
if t.State() >= DependencyFailed { // Either the target failed or its dependencies failed
// Give up and set the original target as dependency failed
target.SetState(DependencyFailed)
state.LogBuildResult(target, TargetBuilt, "Dependency failed")
target.FinishBuild()
return
}
}
}
if !called.Value() {
Expand Down
4 changes: 3 additions & 1 deletion src/output/targets.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ func (bt *buildingTargets) handleOutput(result *core.BuildResult) {
if result.Status != core.TargetTestFailed {
// Reset colour so the entire compiler error output doesn't appear red.
log.Errorf("%s failed:\x1b[0m\n%s", label, shortError(result.Err))
bt.state.Stop()
if !bt.state.KeepGoing {
bt.state.Stop()
}
} else if msg := shortError(result.Err); msg != "" {
log.Errorf("%s failed: %s", result.Label, msg)
} else {
Expand Down
2 changes: 2 additions & 0 deletions src/please.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ var opts struct {
KeepWorkdirs bool `long:"keep_workdirs" description:"Don't clean directories in plz-out/tmp after successfully building targets."`
HTTPProxy cli.URL `long:"http_proxy" env:"HTTP_PROXY" description:"HTTP proxy to use for downloads"`
Debug bool `long:"debug" description:"When enabled, Please will enter into an interactive debugger when breakpoint() is called during parsing."`
KeepGoing bool `long:"keep_going" description:"Continue as much as possible after an error. While the target that failed and those that depend on it cannot be build, other prerequisites of these targets can be."`
} `group:"Options that enable / disable certain behaviors"`

HelpFlags struct {
Expand Down Expand Up @@ -1084,6 +1085,7 @@ func Please(targets []core.BuildLabel, config *core.Configuration, shouldBuild,
config.Build.Config = "dbg"
}
state := core.NewBuildState(config)
state.KeepGoing = opts.BehaviorFlags.KeepGoing
state.VerifyHashes = !opts.BehaviorFlags.NoHashVerification
// Only one of these two can be passed
state.NumTestRuns = uint16(opts.Test.NumRuns)
Expand Down
9 changes: 9 additions & 0 deletions test/keep_going/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
subinclude("//test/build_defs")

please_repo_e2e_test(
name = "build_all",
expected_failure = True,
plz_command = "plz build --keep_going //package:all",
repo = "test_repo",
)

Empty file.
46 changes: 46 additions & 0 deletions test/keep_going/test_repo/package/BUILD_FILE
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
build_rule(
name = "fail",
cmd = "exit 1",
outs = ["fail"],
)

build_rule(
name = "fail2",
cmd = "exit 1",
outs = ["fail2"],
)

build_rule(
name = "pass",
cmd = "touch $OUTS",
outs = ["pass"],
)

build_rule(
name = "dep_pass",
deps = [":pass"],
cmd = "touch $OUTS",
outs = ["dep_pass"],
)

build_rule(
name = "dep_fail",
deps = [":fail"],
cmd = "touch $OUTS",
outs = ["dep_fail"],
)

build_rule(
name = "dep_dep_fail",
deps = [":dep_fail"],
cmd = "touch $OUTS",
outs = ["dep_dep_fail"],
)

build_rule(
test = True,
name = "fail_test",
cmd = "touch $OUTS",
test_cmd = "exit 1",
outs = ["fail_test"],
)

0 comments on commit 88c6000

Please sign in to comment.