summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2014-12-22 01:59:51 +0000
committerCarl Hetherington <cth@carlh.net>2014-12-22 01:59:51 +0000
commit151de8245e0e1bcc7e7910bf75dcacdba3af4cde (patch)
tree0c816ff99caac8739b360993f052597cf2eb8a16
parent9b14293950981cd530dcd7a624811f82bc1213d1 (diff)
Handle duplicate dependencies; tidy up cwd handling a bit, hopefully.
-rwxr-xr-xcdist154
1 files changed, 102 insertions, 52 deletions
diff --git a/cdist b/cdist
index 91f1434..703b1ba 100755
--- a/cdist
+++ b/cdist
@@ -44,6 +44,29 @@ class Error(Exception):
def __repr__(self):
return str(self)
+class Projects:
+ """
+ Store for Project objects which re-uses already-created objects
+ and checks for requests for different versions of the same thing.
+ """
+
+ def __init__(self):
+ self.projects = []
+
+ def get(self, name, specifier, target):
+ for p in self.projects:
+ if p.name == name and p.specifier == specifier:
+ return p
+ elif p.name == name and p.specifier != p.specifier:
+ raise Error('conflicting versions of %s requested (%s and %s)' % (name, specifier, p.specifier))
+
+ np = Project(name, specifier, target)
+ self.projects.append(np)
+ return np
+
+projects = Projects()
+
+
#
# Configuration
#
@@ -216,6 +239,16 @@ def devel_to_git(project, filename):
filename = filename.replace('devel', '-%s' % project.git_commit)
return filename
+class ProjectDirectory:
+ def __init__(self, target, project):
+ self.target = target
+ self.project = project
+ def __enter__(self):
+ self.cwd = os.getcwd()
+ os.chdir('%s/src/%s' % (self.target.directory, self.project.name))
+ def __exit__(self, type, value, traceback):
+ os.chdir(self.cwd)
+
#
# Version
#
@@ -291,12 +324,10 @@ class Target(object):
self.debug = False
def build_dependencies(self, project):
- cwd = os.getcwd()
if 'dependencies' in project.cscript:
for d in project.cscript['dependencies'](self):
log('Building dependency %s %s of %s' % (d[0], d[1], project.name))
- dep = Project(d[0], d[1])
- dep.checkout(self)
+ dep = projects.get(d[0], d[1], self)
self.build_dependencies(dep)
# Make the options to pass in from the option_defaults of the thing
@@ -310,27 +341,29 @@ class Target(object):
self.build(dep, options)
- os.chdir(cwd)
-
def build(self, project, options=None):
+ if project.built:
+ return
+
variables = copy.copy(self.variables)
+
if len(inspect.getargspec(project.cscript['build']).args) == 2:
- project.cscript['build'](self, options)
+ project.call(self, 'build', options)
else:
- project.cscript['build'](self)
+ project.call(self, 'build')
+
self.variables = variables
+ project.built = True
def package(self, project):
- project.checkout(self)
self.build_dependencies(project)
self.build(project)
- return project.cscript['package'](self, project.version)
+ return project.call(self, 'package', project.version)
def test(self, project):
- project.checkout(self)
self.build_dependencies(project)
self.build(project)
- project.cscript['test'](self)
+ return project.call(self, 'test')
def set(self, a, b):
self.variables[a] = b
@@ -473,11 +506,10 @@ class OSXUniversalTarget(OSXTarget):
def package(self, project):
for p in self.parts:
- project.checkout(p)
p.build_dependencies(project)
p.build(project)
- return project.cscript['package'](self, project.version)
+ project.call(self, 'package', project.version)
#
@@ -496,7 +528,6 @@ class SourceTarget(Target):
rmtree(self.directory)
def package(self, project):
- project.checkout(self)
name = read_wscript_variable(os.getcwd(), 'APPNAME')
command('./waf dist')
return os.path.abspath('%s-%s.tar.bz2' % (name, project.version))
@@ -545,18 +576,22 @@ class Project(object):
Attributes:
name -- name of git repository (without the .git)
specifier -- git tag or revision to use
+ target --- target object that we are using
+ version --- version from the wscript (if one is present)
git_commit -- git revision that is actually being used
+ built --- true if the project has been built yet in this run
"""
- def __init__(self, name, specifier=None):
+ def __init__(self, name, specifier, target):
self.name = name
- self.version = None
self.specifier = specifier
+ self.target = target
+ self.version = None
self.git_commit = None
- if self.specifier is None:
- self.specifier = 'master'
+ self.built = False
+
+ cwd = os.getcwd()
- def checkout(self, target):
flags = ''
redirect = ''
if globals.quiet:
@@ -564,7 +599,12 @@ class Project(object):
redirect = '>/dev/null'
command('git clone %s %s/%s.git %s/src/%s' % (flags, config.get('git_prefix'), self.name, target.directory, self.name))
os.chdir('%s/src/%s' % (target.directory, self.name))
- command('git checkout %s %s %s' % (flags, self.specifier, redirect))
+
+ spec = self.specifier
+ if spec is None:
+ spec = 'master'
+
+ command('git checkout %s %s %s' % (flags, spec, redirect))
self.git_commit = command_and_read('git rev-parse --short=7 HEAD').readline().strip()
command('git submodule init --quiet')
command('git submodule update --quiet')
@@ -579,6 +619,11 @@ class Project(object):
if v is not None:
self.version = Version(v)
+ os.chdir(cwd)
+
+ def call(self, target, function, *args):
+ with ProjectDirectory(target, self):
+ return self.cscript[function](target, *args)
#
# Command-line parser
@@ -639,8 +684,6 @@ def main():
globals.quiet = args.quiet
globals.command = args.command
- project = Project(args.project, args.checkout)
-
if not globals.command in commands:
e = 'command must be one of:\n' + one_of
raise Error('command must be one of:\n%s' % one_of)
@@ -650,7 +693,7 @@ def main():
raise Error('you must specify -t or --target')
target = target_factory(args.target, args.debug, args.work)
- project.checkout(target)
+ project = projects.get(args.project, args.checkout, target)
target.build_dependencies(project)
target.build(project)
if not args.keep:
@@ -661,6 +704,7 @@ def main():
raise Error('you must specify -t or --target')
target = target_factory(args.target, args.debug, args.work)
+ project = projects.get(args.project, args.checkout, target)
packages = target.package(project)
if hasattr(packages, 'strip') or (not hasattr(packages, '__getitem__') and not hasattr(packages, '__iter__')):
@@ -690,7 +734,7 @@ def main():
raise Error('you must specify --minor or --micro')
target = SourceTarget()
- project.checkout(target)
+ project = projects.get(args.project, args.checkout, target)
version = project.version
version.to_release()
@@ -716,9 +760,9 @@ def main():
elif globals.command == 'pot':
target = SourceTarget()
- project.checkout(target)
+ project = projects.get(args.project, args.checkout, target)
- pots = project.cscript['make_pot'](target)
+ pots = project.call(target, 'make_pot')
for p in pots:
copyfile(p, '%s%s' % (args.output, os.path.basename(p)))
@@ -726,9 +770,11 @@ def main():
elif globals.command == 'changelog':
target = SourceTarget()
- project.checkout(target)
+ project = projects.get(args.project, args.checkout, target)
+
+ with ProjectDirectory(target, project):
+ text = open('ChangeLog', 'r')
- text = open('ChangeLog', 'r')
html = tempfile.NamedTemporaryFile()
versions = 8
@@ -770,9 +816,9 @@ def main():
elif globals.command == 'manual':
target = SourceTarget()
- project.checkout(target)
+ project = projects.get(args.project, args.checkout, target)
- outs = project.cscript['make_manual'](target)
+ outs = project.call(target, 'make_manual')
for o in outs:
if os.path.isfile(o):
copyfile(o, '%s%s' % (args.output, os.path.basename(o)))
@@ -783,9 +829,9 @@ def main():
elif globals.command == 'doxygen':
target = SourceTarget()
- project.checkout(target)
+ project = projects.get(args.project, args.checkout, target)
- dirs = project.cscript['make_doxygen'](target)
+ dirs = project.call(target, 'make_doxygen')
if hasattr(dirs, 'strip') or (not hasattr(dirs, '__getitem__') and not hasattr(dirs, '__iter__')):
dirs = [dirs]
@@ -796,23 +842,24 @@ def main():
elif globals.command == 'latest':
target = SourceTarget()
- project.checkout(target)
-
- f = command_and_read('git log --tags --simplify-by-decoration --pretty="%d"')
- latest = None
- while latest is None:
- t = f.readline()
- m = re.compile(".*\((.*)\).*").match(t)
- if m:
- tags = m.group(1).split(', ')
- for t in tags:
- s = t.split()
- if len(s) > 1:
- t = s[1]
- if len(t) > 0 and t[0] == 'v':
- v = Version(t[1:])
- if args.major is None or v.major == args.major:
- latest = v
+ project = projects.get(args.project, args.checkout, target)
+
+ with ProjectDirectory(target, project):
+ f = command_and_read('git log --tags --simplify-by-decoration --pretty="%d"')
+ latest = None
+ while latest is None:
+ t = f.readline()
+ m = re.compile(".*\((.*)\).*").match(t)
+ if m:
+ tags = m.group(1).split(', ')
+ for t in tags:
+ s = t.split()
+ if len(s) > 1:
+ t = s[1]
+ if len(t) > 0 and t[0] == 'v':
+ v = Version(t[1:])
+ if args.major is None or v.major == args.major:
+ latest = v
print latest
target.cleanup()
@@ -824,7 +871,9 @@ def main():
target = None
try:
target = target_factory(args.target, args.debug, args.work)
- target.test(project)
+ project = projects.get(args.project, args.checkout, target)
+ with ProjectDirectory(target, project):
+ target.test(project)
except Error as e:
if target is not None:
target.cleanup()
@@ -843,8 +892,9 @@ def main():
elif globals.command == 'revision':
target = SourceTarget()
- project.checkout(target)
- print command_and_read('git rev-parse HEAD').readline().strip()[:7]
+ project = projects.get(args.project, args.checkout, target)
+ with ProjectDirectory(target, project):
+ print command_and_read('git rev-parse HEAD').readline().strip()[:7]
target.cleanup()
else: