Fix a virtual target bug. Add an '-i' option.
This commit is contained in:
parent
64263686cb
commit
3bdc96019f
2 changed files with 38 additions and 20 deletions
56
mk.go
56
mk.go
|
|
@ -1,19 +1,18 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// True if messages should be printed without fancy colors.
|
// True if messages should be printed without fancy colors.
|
||||||
var nocolor bool = false
|
var nocolor bool = false
|
||||||
|
|
||||||
// True if we are no actualyl executing any recipes or updating any timestamps.
|
|
||||||
var dryrun bool = false
|
|
||||||
|
|
||||||
// True if we are ignoring timestamps and rebuilding everything.
|
// True if we are ignoring timestamps and rebuilding everything.
|
||||||
var rebuildall bool = false
|
var rebuildall bool = false
|
||||||
|
|
||||||
|
|
@ -58,20 +57,12 @@ const (
|
||||||
ansiTermUnderline = "\033[4m"
|
ansiTermUnderline = "\033[4m"
|
||||||
)
|
)
|
||||||
|
|
||||||
func mk(rs *ruleSet, target string, dryrun bool) {
|
|
||||||
g := buildgraph(rs, target)
|
|
||||||
if g.root.exists && !rebuildall {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mkNode(g, g.root)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build a target in the graph.
|
// Build a target in the graph.
|
||||||
//
|
//
|
||||||
// This selects an appropriate rule (edge) and builds all prerequisites
|
// This selects an appropriate rule (edge) and builds all prerequisites
|
||||||
// concurrently.
|
// concurrently.
|
||||||
//
|
//
|
||||||
func mkNode(g *graph, u *node) {
|
func mkNode(g *graph, u *node, dryrun bool) {
|
||||||
// try to claim on this node
|
// try to claim on this node
|
||||||
u.mutex.Lock()
|
u.mutex.Lock()
|
||||||
if u.status != nodeStatusReady {
|
if u.status != nodeStatusReady {
|
||||||
|
|
@ -129,10 +120,10 @@ func mkNode(g *graph, u *node) {
|
||||||
prereqs[i].mutex.Lock()
|
prereqs[i].mutex.Lock()
|
||||||
// needs to be built?
|
// needs to be built?
|
||||||
u.updateTimestamp()
|
u.updateTimestamp()
|
||||||
if !prereqs[i].exists || e.r.attributes.virtual || rebuildall || (u.exists && u.t.Before(prereqs[i].t)) {
|
if !prereqs[i].exists || rebuildall || (u.exists && u.t.Before(prereqs[i].t)) {
|
||||||
switch prereqs[i].status {
|
switch prereqs[i].status {
|
||||||
case nodeStatusReady:
|
case nodeStatusReady:
|
||||||
go mkNode(g, prereqs[i])
|
go mkNode(g, prereqs[i], dryrun)
|
||||||
fallthrough
|
fallthrough
|
||||||
case nodeStatusStarted:
|
case nodeStatusStarted:
|
||||||
prereqs[i].listeners = append(prereqs[i].listeners, prereqstat)
|
prereqs[i].listeners = append(prereqs[i].listeners, prereqstat)
|
||||||
|
|
@ -155,7 +146,7 @@ func mkNode(g *graph, u *node) {
|
||||||
// execute the recipe, unless the prereqs failed
|
// execute the recipe, unless the prereqs failed
|
||||||
if finalstatus != nodeStatusFailed && len(e.r.recipe) > 0 {
|
if finalstatus != nodeStatusFailed && len(e.r.recipe) > 0 {
|
||||||
reserveSubproc()
|
reserveSubproc()
|
||||||
if !dorecipe(u.name, u, e) {
|
if !dorecipe(u.name, u, e, dryrun) {
|
||||||
finalstatus = nodeStatusFailed
|
finalstatus = nodeStatusFailed
|
||||||
}
|
}
|
||||||
finishSubproc()
|
finishSubproc()
|
||||||
|
|
@ -216,10 +207,14 @@ func mkPrintRecipe(target string, recipe string) {
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var mkfilepath string
|
var mkfilepath string
|
||||||
|
var interactive bool
|
||||||
|
var dryrun bool
|
||||||
|
|
||||||
flag.StringVar(&mkfilepath, "f", "mkfile", "use the given file as mkfile")
|
flag.StringVar(&mkfilepath, "f", "mkfile", "use the given file as mkfile")
|
||||||
flag.BoolVar(&dryrun, "n", false, "print commands without actually executing")
|
flag.BoolVar(&dryrun, "n", false, "print commands without actually executing")
|
||||||
flag.BoolVar(&rebuildall, "a", false, "force building of all dependencies")
|
flag.BoolVar(&rebuildall, "a", false, "force building of all dependencies")
|
||||||
flag.IntVar(&subprocsAllowed, "p", 8, "maximum number of jobs to execute in parallel")
|
flag.IntVar(&subprocsAllowed, "p", 8, "maximum number of jobs to execute in parallel")
|
||||||
|
flag.BoolVar(&interactive, "i", false, "prompt before executing rules")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
mkfile, err := os.Open(mkfilepath)
|
mkfile, err := os.Open(mkfilepath)
|
||||||
|
|
@ -249,9 +244,32 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: For multiple targets, we should add a dummy rule that depends on
|
// Create a dummy virtula rule that depends on every target
|
||||||
// all let mk handle executing each.
|
root := rule{}
|
||||||
for _, target := range targets {
|
root.targets = []pattern{pattern{false, "", nil}}
|
||||||
mk(rs, target, dryrun)
|
root.attributes = attribSet{false, false, false, false, false, false, false, true}
|
||||||
|
root.prereqs = targets
|
||||||
|
rs.add(root)
|
||||||
|
|
||||||
|
if interactive {
|
||||||
|
g := buildgraph(rs, "")
|
||||||
|
mkNode(g, g.root, true)
|
||||||
|
fmt.Print("Proceed? ")
|
||||||
|
in := bufio.NewReader(os.Stdin)
|
||||||
|
for {
|
||||||
|
c, _, err := in.ReadRune()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
} else if strings.IndexRune(" \n\t\r", c) >= 0 {
|
||||||
|
continue
|
||||||
|
} else if c == 'y' {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g := buildgraph(rs, "")
|
||||||
|
mkNode(g, g.root, dryrun)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ func printIndented(out io.Writer, s string, ind int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute a recipe.
|
// Execute a recipe.
|
||||||
func dorecipe(target string, u *node, e *edge) bool {
|
func dorecipe(target string, u *node, e *edge, dryrun bool) bool {
|
||||||
vars := make(map[string][]string)
|
vars := make(map[string][]string)
|
||||||
vars["target"] = []string{target}
|
vars["target"] = []string{target}
|
||||||
if e.r.ismeta {
|
if e.r.ismeta {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue