github.com/tiagovtristao/plz@v13.4.0+incompatible/src/plz/plz.go (about) 1 package plz 2 3 import ( 4 "sync" 5 6 "gopkg.in/op/go-logging.v1" 7 8 "github.com/thought-machine/please/src/build" 9 "github.com/thought-machine/please/src/cli" 10 "github.com/thought-machine/please/src/core" 11 "github.com/thought-machine/please/src/follow" 12 "github.com/thought-machine/please/src/fs" 13 "github.com/thought-machine/please/src/metrics" 14 "github.com/thought-machine/please/src/parse" 15 "github.com/thought-machine/please/src/test" 16 "github.com/thought-machine/please/src/utils" 17 ) 18 19 var log = logging.MustGetLogger("plz") 20 21 // Run runs a build to completion. 22 // The given state object controls most of the parameters to it and can be interrogated 23 // afterwards to find success / failure. 24 // To get detailed results as it runs, use state.Results. You should call that *before* 25 // starting this (otherwise a sufficiently fast build may bypass you completely). 26 func Run(targets, preTargets []core.BuildLabel, state *core.BuildState, config *core.Configuration, arch cli.Arch) { 27 parse.InitParser(state) 28 build.Init(state) 29 30 if config.Events.Port != 0 && state.NeedBuild { 31 shutdown := follow.InitialiseServer(state, config.Events.Port) 32 defer shutdown() 33 } 34 if config.Events.Port != 0 || config.Display.SystemStats { 35 go follow.UpdateResources(state) 36 } 37 metrics.InitFromConfig(config) 38 39 // Start looking for the initial targets to kick the build off 40 go findOriginalTasks(state, preTargets, targets, arch) 41 // Start up all the build workers 42 var wg sync.WaitGroup 43 wg.Add(config.Please.NumThreads) 44 for i := 0; i < config.Please.NumThreads; i++ { 45 go func(tid int) { 46 doTasks(tid, state, state.Include, state.Exclude, arch) 47 wg.Done() 48 }(i) 49 } 50 // Wait until they've all exited, which they'll do once they have no tasks left. 51 wg.Wait() 52 if state.Cache != nil { 53 state.Cache.Shutdown() 54 } 55 } 56 57 func doTasks(tid int, state *core.BuildState, include, exclude []string, arch cli.Arch) { 58 for { 59 label, dependor, t := state.NextTask() 60 switch t { 61 case core.Stop, core.Kill: 62 return 63 case core.Parse, core.SubincludeParse: 64 t := t 65 label := label 66 dependor := dependor 67 state.ParsePool <- func() { 68 parse.Parse(tid, state, label, dependor, include, exclude, t == core.SubincludeParse) 69 state.TaskDone(false) 70 } 71 case core.Build, core.SubincludeBuild: 72 build.Build(tid, state, label) 73 state.TaskDone(true) 74 case core.Test: 75 test.Test(tid, state, label) 76 state.TaskDone(true) 77 } 78 } 79 } 80 81 // findOriginalTasks finds the original parse tasks for the original set of targets. 82 func findOriginalTasks(state *core.BuildState, preTargets, targets []core.BuildLabel, arch cli.Arch) { 83 if state.Config.Bazel.Compatibility && fs.FileExists("WORKSPACE") { 84 // We have to parse the WORKSPACE file before anything else to understand subrepos. 85 // This is a bit crap really since it inhibits parallelism for the first step. 86 parse.Parse(0, state, core.NewBuildLabel("workspace", "all"), core.OriginalTarget, state.Include, state.Exclude, false) 87 } 88 if arch.Arch != "" { 89 // Set up a new subrepo for this architecture. 90 state.Graph.AddSubrepo(core.SubrepoForArch(state, arch)) 91 } 92 if len(preTargets) > 0 { 93 findOriginalTaskSet(state, preTargets, false, arch) 94 for _, target := range preTargets { 95 log.Debug("Waiting for pre-target %s...", target) 96 state.WaitForBuiltTarget(target, targets[0]) 97 log.Debug("Pre-target %s built, continuing...", target) 98 } 99 } 100 findOriginalTaskSet(state, targets, true, arch) 101 state.TaskDone(true) // initial target adding counts as one. 102 } 103 104 func findOriginalTaskSet(state *core.BuildState, targets []core.BuildLabel, addToList bool, arch cli.Arch) { 105 for _, target := range targets { 106 if target == core.BuildLabelStdin { 107 for label := range cli.ReadStdin() { 108 109 findOriginalTask(state, core.ParseBuildLabels([]string{label})[0], addToList, arch) 110 } 111 } else { 112 findOriginalTask(state, target, addToList, arch) 113 } 114 } 115 } 116 117 func findOriginalTask(state *core.BuildState, target core.BuildLabel, addToList bool, arch cli.Arch) { 118 if arch.Arch != "" { 119 target.Subrepo = arch.String() 120 } 121 if target.IsAllSubpackages() { 122 for pkg := range utils.FindAllSubpackages(state.Config, target.PackageName, "") { 123 state.AddOriginalTarget(core.NewBuildLabel(pkg, "all"), addToList) 124 } 125 } else { 126 state.AddOriginalTarget(target, addToList) 127 } 128 }