Пример #1
0
// Build user's requested targets according to the dependency graph in
// self.dag (as constructed by runMainPhase()).
func (self *Runtime) runBuildPhase() []error {
	var errs []error

	errs = self.dag.ExpandNodes(self.stack)
	if len(errs) > 0 {
		return errs
	}
	self.dag.MarkSources()

	log.Debug(log.DAG, "dependency graph:")
	log.DebugDump(log.DAG, self.dag)

	goal, errs := self.dag.MatchTargets(self.options.Targets)
	if len(errs) > 0 {
		return errs
	}

	bdb, err := openBuildDB()
	if err != nil {
		errs = append(errs, err)
		return errs
	}
	defer bdb.Close()

	bstate := build.NewBuildState(self.dag, bdb, self.options)
	err = bstate.BuildTargets(goal)
	if err != nil {
		errs = append(errs, err)
	}
	return errs
}
Пример #2
0
func main() {
	if filepath.Base(os.Args[0]) == "fubsydebug" {
		debugmain()
		return
	}

	args := parseArgs()
	script, err := findScript(args.scriptFile)
	if err != nil {
		fmt.Fprintln(os.Stderr, "fubsy: error: "+err.Error())
		os.Exit(2)
	}
	log.SetVerbosity(args.verbosity)
	err = log.EnableDebugTopics(args.debugTopics)
	if err != nil {
		fmt.Fprintln(os.Stderr, "fubsy: error: "+err.Error())
		os.Exit(2)
	}

	ast, errors := dsl.Parse(script)
	if ast == nil && len(errors) == 0 {
		panic("ast == nil && len(errors) == 0")
	}
	checkErrors("parse error:", errors)
	log.Debug(log.AST, "ast:\n")
	log.DebugDump(log.AST, ast)

	rt := runtime.NewRuntime(args.options, script, ast)
	errors = rt.RunScript()
	checkErrors("error:", errors)
}
Пример #3
0
func (self *BuildRule) Execute() ([]dag.Node, []error) {
	stack := self.runtime.stack
	locals := types.NewValueMap()
	stack.Push(locals)
	defer stack.Pop()

	self.setLocals(locals)
	log.Debug(log.BUILD, "value stack:")
	log.DebugDump(log.BUILD, stack)
	err := self.action.Execute(self.runtime)
	return self.targets.Nodes(), err
}
Пример #4
0
// Inspect node and its parents to see if we need to build it. Return
// build=true if we should build it, tainted=true if we should skip
// building this node due to upstream failure. Return non-nil err if
// there were unexpected node errors (error checking existence or
// change status).
func (self *BuildState) considerNode(node dag.Node) (
	build bool, tainted bool, err error) {

	var exists, changed bool
	exists, err = node.Exists() // obvious rebuild (unless tainted)
	if err != nil {
		return
	}
	missing := !exists

	var record *db.BuildRecord
	if !missing {
		// skip DB lookup for missing nodes: the only thing that will
		// stop us from rebuilding them is a failed parent, and that
		// check comes later
		record, err = self.db.LookupNode(node.Name())
		if err != nil {
			return
		}
		if record != nil {
			log.Debug(log.BUILD, "old parents of %s:", node)
			log.DebugDump(log.BUILD, record)
		}
	}

	build = missing
	parents := self.graph.ParentNodes(node)

	// Check if any of node's former parents have been removed.
	if !build && record != nil {
		build = parentsRemoved(parents, record)
	}

	for _, parent := range parents {
		pstate := parent.State()
		if pstate == dag.FAILED || pstate == dag.TAINTED {
			build = false
			tainted = true
			return // no further inspection required
		}

		var oldsig []byte
		if record != nil {
			oldsig = record.SourceSignature(parent.Name())
		}
		if oldsig == nil {
			// New parent for this node: rebuild unless another
			// parent is failed/tainted.
			build = true
		}

		if build {
			continue
		}
		changed, err = self.parentChanged(parent, pstate, oldsig)
		if err != nil {
			return
		}
		if changed {
			// Do NOT return here: we need to continue inspecting
			// parents to make sure they don't taint this node with
			// upstream failure.
			build = true
		}
	}
	return
}