예제 #1
0
func printBuildResults(state *core.BuildState, duration float64) {
	// Count incrementality.
	totalBuilt := 0
	totalReused := 0
	for _, target := range state.Graph.AllTargets() {
		if target.State() == core.Built {
			totalBuilt++
		} else if target.State() == core.Reused {
			totalReused++
		}
	}
	incrementality := 100.0 * float64(totalReused) / float64(totalBuilt+totalReused)
	if totalBuilt+totalReused == 0 {
		incrementality = 100 // avoid NaN
	}
	// Print this stuff so we always see it.
	printf("Build finished; total time %0.2fs, incrementality %.1f%%. Outputs:\n", duration, incrementality)
	for _, label := range state.ExpandOriginalTargets() {
		target := state.Graph.TargetOrDie(label)
		fmt.Printf("%s:\n", label)
		for _, result := range buildResult(target) {
			fmt.Printf("  %s\n", result)
		}
	}
}
예제 #2
0
func MonitorState(state *core.BuildState, numThreads int, plainOutput, keepGoing, shouldBuild, shouldTest, shouldRun bool, traceFile string) bool {
	failedTargetMap := map[core.BuildLabel]error{}
	buildingTargets := make([]buildingTarget, numThreads, numThreads)

	displayDone := make(chan interface{})
	stop := make(chan interface{})
	if !plainOutput {
		go display(state, &buildingTargets, stop, displayDone)
	}
	aggregatedResults := core.TestResults{}
	failedTargets := []core.BuildLabel{}
	failedNonTests := []core.BuildLabel{}
	for result := range state.Results {
		processResult(state, result, buildingTargets, &aggregatedResults, plainOutput, keepGoing, &failedTargets, &failedNonTests, failedTargetMap, traceFile != "")
	}
	if !plainOutput {
		stop <- struct{}{}
		<-displayDone
	}
	if traceFile != "" {
		writeTrace(traceFile)
	}
	duration := time.Since(startTime).Seconds()
	if len(failedNonTests) > 0 { // Something failed in the build step.
		if state.Verbosity > 0 {
			printFailedBuildResults(failedNonTests, failedTargetMap, duration)
		}
		// Die immediately and unsuccessfully, this avoids awkward interactions with
		// --failing_tests_ok later on.
		os.Exit(-1)
	}
	// Check all the targets we wanted to build actually have been built.
	for _, label := range state.ExpandOriginalTargets() {
		if target := state.Graph.Target(label); target == nil {
			log.Fatalf("Target %s doesn't exist in build graph", label)
		} else if (state.NeedHashesOnly || state.PrepareOnly) && target.State() == core.Stopped {
			// Do nothing, we will output about this shortly.
		} else if shouldBuild && target != nil && target.State() < core.Built && len(failedTargetMap) == 0 {
			cycle := graphCycleMessage(state.Graph, target)
			log.Fatalf("Target %s hasn't built but we have no pending tasks left.\n%s", label, cycle)
		}
	}
	if state.Verbosity > 0 && shouldBuild {
		if shouldTest { // Got to the test phase, report their results.
			printTestResults(state, aggregatedResults, failedTargets, duration)
		} else if state.NeedHashesOnly {
			printHashes(state, duration)
		} else if state.PrepareOnly {
			printTempDirs(state, duration)
		} else if !shouldRun { // Must be plz build or similar, report build outputs.
			printBuildResults(state, duration)
		}
	}
	return len(failedTargetMap) == 0
}
예제 #3
0
func printTempDirs(state *core.BuildState, duration float64) {
	fmt.Printf("Temp directories prepared, total time %0.2fs:\n", duration)
	for _, label := range state.ExpandOriginalTargets() {
		target := state.Graph.TargetOrDie(label)
		cmd := build.ReplaceSequences(target, target.GetCommand())
		env := core.BuildEnvironment(state, target, false)
		fmt.Printf("  %s: %s\n", label, target.TmpDir())
		fmt.Printf("    Command: %s\n", cmd)
		fmt.Printf("   Expanded: %s\n", os.Expand(cmd, core.ReplaceEnvironment(env)))
	}
}
예제 #4
0
func printHashes(state *core.BuildState, duration float64) {
	fmt.Printf("Hashes calculated, total time %0.2fs:\n", duration)
	for _, label := range state.ExpandOriginalTargets() {
		hash, err := build.OutputHash(state.Graph.TargetOrDie(label))
		if err != nil {
			fmt.Printf("  %s: cannot calculate: %s\n", label, err)
		} else {
			fmt.Printf("  %s: %s\n", label, hex.EncodeToString(hash))
		}
	}
}
예제 #5
0
// Adds empty coverage entries for any files covered by the original query that we
// haven't discovered through tests to the overall report.
// The coverage reports only contain information about files that were covered during
// tests, so it's important that we identify anything with zero coverage here.
// This is made trickier by attempting to reconcile coverage targets from languages like
// Java that don't preserve the original file structure, which requires a slightly fuzzy match.
func AddOriginalTargetsToCoverage(state *core.BuildState, includeAllFiles bool) {
	// First we collect all the source files from all relevant targets
	allFiles := map[string]bool{}
	doneTargets := map[*core.BuildTarget]bool{}
	// Track the set of packages the user ran tests from; we only show coverage metrics from them.
	coveragePackages := map[string]bool{}
	for _, label := range state.OriginalTargets {
		coveragePackages[label.PackageName] = true
	}
	for _, label := range state.ExpandOriginalTargets() {
		collectAllFiles(state, state.Graph.TargetOrDie(label), coveragePackages, allFiles, doneTargets, includeAllFiles)
	}

	// Now merge the recorded coverage so far into them
	recordedCoverage := state.Coverage
	state.Coverage = core.TestCoverage{Tests: recordedCoverage.Tests, Files: map[string][]core.LineCoverage{}}
	mergeCoverage(state, recordedCoverage, coveragePackages, allFiles, includeAllFiles)
}