Esempio n. 1
0
func parentsRemoved(parents []dag.Node, record *db.BuildRecord) bool {
	parentset := make(map[string]bool)
	for _, parent := range parents {
		parentset[parent.Name()] = true
	}
	for _, name := range record.Parents() {
		if !parentset[name] {
			return true
		}
	}
	return false
}
Esempio n. 2
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
}