summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2015-12-08 18:12:15 +0000
committerCarl Hetherington <cth@carlh.net>2015-12-08 18:12:15 +0000
commitbe070a4a495b3fad1cefe4263e3fb1e1afaff812 (patch)
tree75e4ca16edf72276d089fb382d6b585606a9bfc3
parent2204a1810461c087ed85d0f5f0ea93134c0b7ada (diff)
Partial work on deps.better-deps
-rwxr-xr-xcdist95
-rw-r--r--test.py10
2 files changed, 95 insertions, 10 deletions
diff --git a/cdist b/cdist
index d0576e9..b56a8db 100755
--- a/cdist
+++ b/cdist
@@ -49,14 +49,11 @@ class Trees:
def get(self, name, specifier, target):
for t in self.trees:
- if t.name == name and t.specifier == specifier and t.target == target:
+ if t.name == name and t.target == target:
return t
- elif t.name == name and t.specifier != specifier:
- raise Error('conflicting versions of %s requested (%s and %s)' % (name, specifier, t.specifier))
- nt = Tree(name, specifier, target)
+ def add(nt):
self.trees.append(nt)
- return nt
class Globals:
quiet = False
@@ -569,6 +566,70 @@ def target_factory(s, debug, work):
return target
+class Specifier:
+ """Helper class for union()"""
+ def __init__(self, s):
+ self.revision = None
+ self.branch = None
+ self.at_least = False
+
+ if len(s) == 7:
+ self.revision = s
+ elif len(s) == 8 and s[-1] == '+':
+ self.revision = s[:7]
+ self.at_least = True
+ else:
+ self.branch = s
+
+ def specific_revision(self):
+ return self.revision is not None and self.at_least == False
+
+ def __str__(self):
+ s = ''
+ if self.revision is not None:
+ s = self.revision
+ else:
+ s = self.branch
+ if self.at_least:
+ s += '+'
+ return s
+
+def union(a, b, tree):
+ """Take two specifiers and return one which satisfies both"""
+
+ # One or other is None -> the other one wins
+ if a is None:
+ return b
+ if b is None:
+ return a
+
+ a = Specifier(a)
+ b = Specifier(b)
+
+ # Two specific revisions
+ if a.specific_revision() and b.specific_revision():
+ if a.revision == b.revision:
+ return a.revision
+ else:
+ raise 'Incompatible specifiers %s and %s for %s' % (a, b, tree.name)
+
+ # Two different branches
+ if a.branch is not None and b.branch is not None:
+ if a.branch == b.branch:
+ return a.branch
+ else:
+ raise 'Incompatible specifiers %s and %s for %s' % (a, b, tree.name)
+
+ if a.revision is not None and a.at_least and b.revision is not None and b.at_least:
+ # Two 'at-least' revisions; check that they are on the same branch
+ # and pick the most recent
+ with TreeDirectory(tree):
+ a_branches = command_and_read('git branch --contains %s' % a.revision).readlines()
+ b_branches = command_and_read('git branch --contains %s' % b.revision).readlines()
+
+
+
+
#
# Tree
#
@@ -628,6 +689,19 @@ class Tree(object):
with TreeDirectory(self):
return self.cscript[function](self.target, *args)
+ def calculate_dependencies(self):
+ if 'dependencies' in self.cscript:
+ for d in self.cscript['dependencies'](self.target):
+ # Get any existing Tree
+ dep = globals.trees.get(d[0], self.target)
+ if dep is None:
+ # No existing tree; make one
+ globals.trees.add(Tree(d[0], d[1], self.target))
+ else:
+ # Check that this specifier and the existing one are compatible,
+ # updating the existing one if required
+ dep.specifier = union(dep.specifier, d[1], d[0])
+
def build(self, options={}):
# Build any dependencies
if 'dependencies' in self.cscript:
@@ -950,8 +1024,9 @@ def main():
else:
raise Error('invalid command %s' % globals.command)
-try:
- main()
-except Error as e:
- print >>sys.stderr,'cdist: %s' % str(e)
- sys.exit(1)
+if __name__ == '__main__':
+ try:
+ main()
+ except Error as e:
+ print >>sys.stderr,'cdist: %s' % str(e)
+ sys.exit(1)
diff --git a/test.py b/test.py
new file mode 100644
index 0000000..5ad5b47
--- /dev/null
+++ b/test.py
@@ -0,0 +1,10 @@
+import imp
+import sys
+
+cdist = imp.load_source("cdist", "cdist")
+
+target = cdist.SourceTarget()
+tree = cdist.Tree('dcpomatic', 'master', target)
+
+assert(cdist.union(None, None, tree) is None)
+print cdist.union('master', 'master', tree)