Golang core.BuildState类(方法)实例源码

下面列出了Golang core.BuildState 类(方法)源码代码实例,从而了解它的用法。

作者:thought-machin    项目:pleas   
func printLines(state *core.BuildState, buildingTargets []buildingTarget, maxLines, cols int) {
	now := time.Now()
	printf("Building [%d/%d, %3.1fs]:\n", state.NumDone(), state.NumActive(), time.Since(startTime).Seconds())
	for i := 0; i < len(buildingTargets) && i < maxLines; i++ {
		buildingTargets[i].Lock()
		// Take a local copy of the structure, which isn't *that* big, so we don't need to retain the lock
		// while we do potentially blocking things like printing.
		target := buildingTargets[i].buildingTargetData
		buildingTargets[i].Unlock()
		label := target.Label.Parent()
		if target.Active {
			lprintf(cols, "${BOLD_WHITE}=> [%4.1fs] ${RESET}%s%s ${BOLD_WHITE}%s${ERASE_AFTER}\n",
				now.Sub(target.Started).Seconds(), target.Colour, label, target.Description)
		} else if time.Since(target.Finished).Seconds() < 0.5 {
			// Only display finished targets for half a second after they're done.
			duration := target.Finished.Sub(target.Started).Seconds()
			if target.Failed {
				lprintf(cols, "${BOLD_RED}=> [%4.1fs] ${RESET}%s%s ${BOLD_RED}Failed${ERASE_AFTER}\n",
					duration, target.Colour, label)
			} else if target.Cached {
				lprintf(cols, "${BOLD_WHITE}=> [%4.1fs] ${RESET}%s%s ${BOLD_GREY}%s${ERASE_AFTER}\n",
					duration, target.Colour, label, target.Description)
			} else {
				lprintf(cols, "${BOLD_WHITE}=> [%4.1fs] ${RESET}%s%s ${WHITE}%s${ERASE_AFTER}\n",
					duration, target.Colour, label, target.Description)
			}
		} else {
			printf("${BOLD_GREY}=|${ERASE_AFTER}\n")
		}
	}
	printf("${RESET}")
}

作者:thought-machin    项目:pleas   
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)
		}
	}
}

作者:thought-machin    项目:pleas   
// setWindowTitle sets the title of the current shell window based on the current build state.
func setWindowTitle(state *core.BuildState) {
	if state == nil {
		SetWindowTitle("plz: finishing up")
	} else {
		SetWindowTitle(fmt.Sprintf("plz: %d / %d tasks, %3.1fs", state.NumDone(), state.NumActive(), time.Since(startTime).Seconds()))
	}
}

作者:thought-machin    项目:pleas   
func addTarget(state *core.BuildState, i int) *core.BuildTarget {
	// Create and add a new target, with a parent and a dependency.
	target := core.NewBuildTarget(label(i))
	target.Command = "__FILEGROUP__" // Will mean it doesn't have to shell out to anything.
	target.SetState(core.Active)
	state.Graph.AddTarget(target)
	if i <= size {
		if i > 10 {
			target.Flakiness = i // Stash this here, will be useful later.
			target.PostBuildFunction = reflect.ValueOf(&postBuildFunc).Pointer()
		}
		if i < size/10 {
			for j := 0; j < 10; j++ {
				dep := label(i*10 + j)
				log.Info("Adding dependency %s -> %s", target.Label, dep)
				target.AddDependency(dep)
				state.Graph.AddDependency(target.Label, dep)
			}
		} else {
			// These are buildable now
			state.AddPendingBuild(target.Label, false)
		}
	}
	state.AddActiveTarget()
	return target
}

作者:thought-machin    项目:pleas   
func Test(tid int, state *core.BuildState, label core.BuildLabel) {
	state.LogBuildResult(tid, label, core.TargetTesting, "Testing...")
	startTime := time.Now()
	target := state.Graph.TargetOrDie(label)
	test(tid, state, label, target)
	metrics.Record(target, time.Since(startTime))
}

作者:thought-machin    项目:pleas   
// prepareAndRunTest sets up a test directory and runs the test.
func prepareAndRunTest(tid int, state *core.BuildState, target *core.BuildTarget) (out []byte, err error) {
	if err = prepareTestDir(state.Graph, target); err != nil {
		state.LogBuildError(tid, target.Label, core.TargetTestFailed, err, "Failed to prepare test directory for %s: %s", target.Label, err)
		return []byte{}, err
	}
	return runPossiblyContainerisedTest(state, target)
}

作者:thought-machin    项目:pleas   
func findOriginalTask(state *core.BuildState, target core.BuildLabel) {
	if target.IsAllSubpackages() {
		for pkg := range utils.FindAllSubpackages(state.Config, target.PackageName, "") {
			state.AddOriginalTarget(core.NewBuildLabel(pkg, "all"))
		}
	} else {
		state.AddOriginalTarget(target)
	}
}

作者:thought-machin    项目:pleas   
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
}

作者:thought-machin    项目:pleas   
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))
		}
	}
}

作者:thought-machin    项目:pleas   
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)))
	}
}

作者:thought-machin    项目:pleas   
// findOriginalTasks finds the original parse tasks for the original set of targets.
func findOriginalTasks(state *core.BuildState, targets []core.BuildLabel) {
	for _, target := range targets {
		if target == core.BuildLabelStdin {
			for label := range utils.ReadStdin() {
				findOriginalTask(state, core.ParseBuildLabels([]string{label})[0])
			}
		} else {
			findOriginalTask(state, target)
		}
	}
	state.TaskDone() // initial target adding counts as one.
}

作者:thought-machin    项目:pleas   
func logTestSuccess(state *core.BuildState, tid int, label core.BuildLabel, results core.TestResults, coverage core.TestCoverage) {
	var description string
	tests := pluralise("test", results.NumTests)
	if results.Skipped != 0 || results.ExpectedFailures != 0 {
		failures := pluralise("failure", results.ExpectedFailures)
		description = fmt.Sprintf("%d %s passed. %d skipped, %d expected %s",
			results.NumTests, tests, results.Skipped, results.ExpectedFailures, failures)
	} else {
		description = fmt.Sprintf("%d %s passed.", results.NumTests, tests)
	}
	state.LogTestResult(tid, label, core.TargetTested, results, coverage, nil, description)
}

作者:thought-machin    项目:pleas   
// please mimics the core build 'loop' from src/please.go.
func please(tid int, state *core.BuildState) {
	for {
		label, _, t := state.NextTask()
		switch t {
		case core.Stop, core.Kill:
			return
		case core.Build:
			Build(tid, state, label)
		default:
			panic(fmt.Sprintf("unexpected task type: %d", t))
		}
		state.TaskDone()
	}
}

作者:thought-machin    项目:pleas   
func Build(tid int, state *core.BuildState, label core.BuildLabel) {
	start := time.Now()
	target := state.Graph.TargetOrDie(label)
	target.SetState(core.Building)
	if err := buildTarget(tid, state, target); err != nil {
		if err == stopTarget {
			target.SetState(core.Stopped)
			state.LogBuildResult(tid, target.Label, core.TargetBuildStopped, "Build stopped")
			return
		}
		state.LogBuildError(tid, label, core.TargetBuildFailed, err, "Build failed: %s", err)
		if err := RemoveOutputs(target); err != nil {
			log.Errorf("Failed to remove outputs for %s: %s", target.Label, err)
		}
		target.SetState(core.Failed)
		return
	}
	metrics.Record(target, time.Since(start))

	// Add any of the reverse deps that are now fully built to the queue.
	for _, reverseDep := range state.Graph.ReverseDependencies(target) {
		if reverseDep.State() == core.Active && state.Graph.AllDepsBuilt(reverseDep) && reverseDep.SyncUpdateState(core.Active, core.Pending) {
			state.AddPendingBuild(reverseDep.Label, false)
		}
	}
	if target.IsTest && state.NeedTests {
		state.AddPendingTest(target.Label)
	}
	parse.UndeferAnyParses(state, target)
}

作者:thought-machin    项目:pleas   
func updateTarget(state *core.BuildState, plainOutput bool, buildingTarget *buildingTarget, label core.BuildLabel,
	active bool, failed bool, cached bool, description string, err error, colour string) {
	updateTarget2(buildingTarget, label, active, failed, cached, description, err, colour)
	if plainOutput {
		if failed {
			log.Errorf("%s: %s", label.String(), description)
		} else {
			if !active {
				active := pluralise(state.NumActive(), "task", "tasks")
				log.Notice("[%d/%s] %s: %s [%3.1fs]", state.NumDone(), active, label.String(), description, time.Now().Sub(buildingTarget.Started).Seconds())
			} else {
				log.Info("%s: %s", label.String(), description)
			}
		}
	}
}

作者:thought-machin    项目:pleas   
func please(tid int, state *core.BuildState, parsePackageOnly bool, include, exclude []string) {
	for {
		label, dependor, t := state.NextTask()
		switch t {
		case core.Stop, core.Kill:
			return
		case core.Parse, core.SubincludeParse:
			parse.Parse(tid, state, label, dependor, parsePackageOnly, include, exclude)
		case core.Build, core.SubincludeBuild:
			build.Build(tid, state, label)
		case core.Test:
			test.Test(tid, state, label)
		}
		state.TaskDone()
	}
}

作者:thought-machin    项目:pleas   
// Return true if the rule needs building, false if the existing outputs are OK.
func needsBuilding(state *core.BuildState, target *core.BuildTarget, postBuild bool) bool {
	// Check the dependencies first, because they don't need any disk I/O.
	if target.NeedsTransitiveDependencies {
		if anyDependencyHasChanged(target) {
			return true // one of the transitive deps has changed, need to rebuild
		}
	} else {
		for _, dep := range target.Dependencies() {
			if dep.State() < core.Unchanged {
				log.Debug("Need to rebuild %s, %s has changed", target.Label, dep.Label)
				return true // dependency has just been rebuilt, do this too.
			}
		}
	}
	oldRuleHash, oldConfigHash, oldSourceHash := readRuleHashFile(ruleHashFileName(target), postBuild)
	if !bytes.Equal(oldConfigHash, state.Hashes.Config) {
		if len(oldConfigHash) == 0 {
			// Small nicety to make it a bit clearer what's going on.
			log.Debug("Need to build %s, outputs aren't there", target.Label)
		} else {
			log.Debug("Need to rebuild %s, config has changed (was %s, need %s)", target.Label, b64(oldConfigHash), b64(state.Hashes.Config))
		}
		return true
	}
	newRuleHash := RuleHash(target, false, postBuild)
	if !bytes.Equal(oldRuleHash, newRuleHash) {
		log.Debug("Need to rebuild %s, rule has changed (was %s, need %s)", target.Label, b64(oldRuleHash), b64(newRuleHash))
		return true
	}
	newSourceHash, err := sourceHash(state.Graph, target)
	if err != nil || !bytes.Equal(oldSourceHash, newSourceHash) {
		log.Debug("Need to rebuild %s, sources have changed (was %s, need %s)", target.Label, b64(oldSourceHash), b64(newSourceHash))
		return true
	}
	// Check the outputs of this rule exist. This would only happen if the user had
	// removed them but it's incredibly aggravating if you remove an output and the
	// rule won't rebuild itself.
	for _, output := range target.Outputs() {
		realOutput := path.Join(target.OutDir(), output)
		if !core.PathExists(realOutput) {
			log.Debug("Output %s doesn't exist for rule %s; will rebuild.", realOutput, target.Label)
			return true
		}
	}
	// Maybe we've forced a rebuild. Do this last; might be interesting to see if it needed building anyway.
	return state.ForceRebuild && (state.IsOriginalTarget(target.Label) || state.IsOriginalTarget(target.Label.Parent()))
}

作者:thought-machin    项目:pleas   
// UndeferAnyParses un-defers the parsing of a package if it depended on some subinclude target being built.
func UndeferAnyParses(state *core.BuildState, target *core.BuildTarget) {
	pendingTargetMutex.Lock()
	defer pendingTargetMutex.Unlock()
	if m, present := deferredParses[target.Label.PackageName]; present {
		if s, present := m[target.Label.Name]; present {
			for _, deferredPackageName := range s {
				log.Debug("Undeferring parse of %s", deferredPackageName)
				state.AddPendingParse(
					core.BuildLabel{PackageName: deferredPackageName, Name: getDependingTarget(deferredPackageName)},
					core.BuildLabel{PackageName: deferredPackageName, Name: "_UNDEFER_"},
					false,
				)
			}
			delete(m, target.Label.Name) // Don't need this any more
		}
	}
}

作者:thought-machin    项目:pleas   
// 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)
}

作者:thought-machin    项目:pleas   
// calculateAndCheckRuleHash checks the output hash for a rule.
func calculateAndCheckRuleHash(state *core.BuildState, target *core.BuildTarget) ([]byte, error) {
	hash, err := OutputHash(target)
	if err != nil {
		return nil, err
	}
	if err = checkRuleHashes(target, hash); err != nil {
		if state.NeedHashesOnly && (state.IsOriginalTarget(target.Label) || state.IsOriginalTarget(target.Label.Parent())) {
			return nil, stopTarget
		} else if state.VerifyHashes {
			return nil, err
		} else {
			log.Warning("%s", err)
		}
	}
	if err := writeRuleHashFile(state, target); err != nil {
		return nil, fmt.Errorf("Attempting to create hash file: %s", err)
	}
	return hash, nil
}


问题


面经


文章

微信
公众号

扫码关注公众号