aboutsummaryrefslogtreecommitdiffstats
path: root/live_tracker.go
diff options
context:
space:
mode:
authorColin Cross <ccross@google.com>2015-01-23 13:38:48 -0800
committerColin Cross <ccross@google.com>2015-01-23 14:23:27 -0800
commit3e8e74f276eafaf709e8e4c4291431a1d4ccb7e2 (patch)
tree2599d6ac3c3810a41a87a709a004fc1fab4a7b74 /live_tracker.go
parent6bb4af9e208ea9769ae52933e8d9f42a4e75938e (diff)
downloadplatform_build_blueprint-3e8e74f276eafaf709e8e4c4291431a1d4ccb7e2.tar.gz
platform_build_blueprint-3e8e74f276eafaf709e8e4c4291431a1d4ccb7e2.tar.bz2
platform_build_blueprint-3e8e74f276eafaf709e8e4c4291431a1d4ccb7e2.zip
Move blueprint/* up a directory
Make integrating with go tools easier by putting the blueprint package files in the top level directory of the git project instead of in a subdirectory called blueprint. Change-Id: I35c144c5fe7ddf34e478d0c47c50b2f6c92c2a03
Diffstat (limited to 'live_tracker.go')
-rw-r--r--live_tracker.go155
1 files changed, 155 insertions, 0 deletions
diff --git a/live_tracker.go b/live_tracker.go
new file mode 100644
index 0000000..9d029ee
--- /dev/null
+++ b/live_tracker.go
@@ -0,0 +1,155 @@
+package blueprint
+
+import "sync"
+
+// A liveTracker tracks the values of live variables, rules, and pools. An
+// entity is made "live" when it is referenced directly or indirectly by a build
+// definition. When an entity is made live its value is computed based on the
+// configuration.
+type liveTracker struct {
+ sync.Mutex
+ config interface{} // Used to evaluate variable, rule, and pool values.
+
+ variables map[Variable]*ninjaString
+ pools map[Pool]*poolDef
+ rules map[Rule]*ruleDef
+}
+
+func newLiveTracker(config interface{}) *liveTracker {
+ return &liveTracker{
+ config: config,
+ variables: make(map[Variable]*ninjaString),
+ pools: make(map[Pool]*poolDef),
+ rules: make(map[Rule]*ruleDef),
+ }
+}
+
+func (l *liveTracker) AddBuildDefDeps(def *buildDef) error {
+ l.Lock()
+ defer l.Unlock()
+
+ err := l.addRule(def.Rule)
+ if err != nil {
+ return err
+ }
+
+ err = l.addNinjaStringListDeps(def.Outputs)
+ if err != nil {
+ return err
+ }
+
+ err = l.addNinjaStringListDeps(def.Inputs)
+ if err != nil {
+ return err
+ }
+
+ err = l.addNinjaStringListDeps(def.Implicits)
+ if err != nil {
+ return err
+ }
+
+ err = l.addNinjaStringListDeps(def.OrderOnly)
+ if err != nil {
+ return err
+ }
+
+ for _, value := range def.Args {
+ err = l.addNinjaStringDeps(value)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (l *liveTracker) addRule(r Rule) error {
+ _, ok := l.rules[r]
+ if !ok {
+ def, err := r.def(l.config)
+ if err == errRuleIsBuiltin {
+ // No need to do anything for built-in rules.
+ return nil
+ }
+ if err != nil {
+ return err
+ }
+
+ if def.Pool != nil {
+ err = l.addPool(def.Pool)
+ if err != nil {
+ return err
+ }
+ }
+
+ for _, value := range def.Variables {
+ err = l.addNinjaStringDeps(value)
+ if err != nil {
+ return err
+ }
+ }
+
+ l.rules[r] = def
+ }
+
+ return nil
+}
+
+func (l *liveTracker) addPool(p Pool) error {
+ _, ok := l.pools[p]
+ if !ok {
+ def, err := p.def(l.config)
+ if err != nil {
+ return err
+ }
+
+ l.pools[p] = def
+ }
+
+ return nil
+}
+
+func (l *liveTracker) addVariable(v Variable) error {
+ _, ok := l.variables[v]
+ if !ok {
+ value, err := v.value(l.config)
+ if err == errVariableIsArg {
+ // This variable is a placeholder for an argument that can be passed
+ // to a rule. It has no value and thus doesn't reference any other
+ // variables.
+ return nil
+ }
+ if err != nil {
+ return err
+ }
+
+ l.variables[v] = value
+
+ err = l.addNinjaStringDeps(value)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (l *liveTracker) addNinjaStringListDeps(list []*ninjaString) error {
+ for _, str := range list {
+ err := l.addNinjaStringDeps(str)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (l *liveTracker) addNinjaStringDeps(str *ninjaString) error {
+ for _, v := range str.variables {
+ err := l.addVariable(v)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}