jhbuild r1835 - in trunk: . jhbuild
- From: fpeters svn gnome org
- To: svn-commits-list gnome org
- Subject: jhbuild r1835 - in trunk: . jhbuild
- Date: Thu, 17 Jan 2008 21:12:50 +0000 (GMT)
Author: fpeters
Date: Thu Jan 17 21:12:50 2008
New Revision: 1835
URL: http://svn.gnome.org/viewvc/jhbuild?rev=1835&view=rev
Log:
* jhbuild/errors.py, jhbuild/moduleset.py: rewrote build ordering to
get dependency cycle detection (fatal for hard dependencies but quietly
ignored for suggests and after).
Modified:
trunk/ChangeLog
trunk/jhbuild/errors.py
trunk/jhbuild/moduleset.py
Modified: trunk/jhbuild/errors.py
==============================================================================
--- trunk/jhbuild/errors.py (original)
+++ trunk/jhbuild/errors.py Thu Jan 17 21:12:50 2008
@@ -39,3 +39,8 @@
class BuildStateError(Exception):
'''An error occurred while processing a build state.'''
+
+
+class DependencyCycleError(Exception):
+ '''There is a dependency cycle in the module set'''
+
Modified: trunk/jhbuild/moduleset.py
==============================================================================
--- trunk/jhbuild/moduleset.py (original)
+++ trunk/jhbuild/moduleset.py Thu Jan 17 21:12:50 2008
@@ -23,7 +23,7 @@
import sys
import urlparse
-from jhbuild.errors import UsageError, FatalError
+from jhbuild.errors import UsageError, FatalError, DependencyCycleError
try:
import xml.dom.minidom
@@ -75,56 +75,74 @@
if seed == 'all': seed = self.modules.keys()
try:
- modules = [self.modules[mod] for mod in seed if mod not in skip]
+ all_modules = [self.modules[mod] for mod in seed if mod not in skip]
except KeyError, e:
raise UsageError('module "%s" not found' % str(e))
- # expand dependencies
- i = 0
- while i < len(modules):
- depadd = []
- # dependencies
- for modname in modules[i].dependencies:
- if self.modules.has_key(modname):
- depmod = self.modules[modname]
- else:
- raise UsageError('dependent module "%s" not found'
- % modname)
- if depmod not in modules[:i+1] and depmod.name not in skip:
- depadd.append(depmod)
- # suggests
- for modname in modules[i].suggests:
- if self.modules.has_key(modname):
- depmod = self.modules[modname]
- else:
- # silently ignore unknown modules
- continue
- if depmod not in modules[:i+1] and depmod.name not in skip:
- depadd.append(depmod)
- if depadd:
- modules[i:i] = depadd
- else:
- i = i + 1
- # and now 'after' modules.
+
+ asked_modules = all_modules[:]
+
+ # 1st: get all modules that will be needed
+ # note this is only needed to skip "after" modules that would not
+ # otherwise be built
i = 0
- while i < len(modules):
- depadd = []
- for modname in modules[i].dependencies + modules[i].after:
- if self.modules.has_key(modname):
- depmod = self.modules[modname]
+ while i < len(all_modules):
+ for modname in all_modules[i].dependencies:
+ depmod = self.modules.get(modname)
+ if not depmod:
+ raise UsageError('dependent module "%s" not found' % modname)
+ if not depmod in all_modules:
+ all_modules.append(depmod)
+
+ # suggests can be ignored if not in moduleset
+ for modname in all_modules[i].suggests:
+ depmod = self.modules.get(modname)
+ if not depmod:
+ continue
+ if not depmod in all_modules:
+ all_modules.append(depmod)
+ i += 1
+
+ # 2nd: order them, raise an exception on hard dependency cycle, ignore
+ # them for soft dependencies
+ ordered = []
+ state = {}
+ def order(modules, module, mode = 'dependencies'):
+ if state.get(module, 'clean') == 'processed':
+ # already seen
+ return
+ if state.get(module, 'clean') == 'in-progress':
+ # dependency circle, abort when processing hard dependencies
+ if mode == 'dependencies':
+ raise DependencyCycleError()
else:
- continue # don't care about unknown after modules
- if depmod in modules and depmod not in modules[:i+1]:
- depadd.append(depmod)
- if depadd:
- modules[i:i] = depadd
- else:
- i = i + 1
- # remove duplicates
- ret = []
- for module in modules:
- if module not in ret:
- ret.append(module)
- return ret
+ state[module] = 'in-progress'
+ return
+ state[module] = 'in-progress'
+ for modname in module.dependencies:
+ depmod = self.modules[modname]
+ order([self.modules[x] for x in depmod.dependencies], depmod, mode)
+ for modname in module.suggests:
+ depmod = self.modules.get(modname)
+ if not depmod:
+ continue
+ order([self.modules[x] for x in depmod.dependencies], depmod, 'suggests')
+ for modname in module.after:
+ depmod = self.modules.get(modname)
+ if not depmod in all_modules:
+ # not built otherwise
+ continue
+ if not depmod:
+ continue
+ order([self.modules[x] for x in depmod.dependencies], depmod, 'after')
+ state[module] = 'processed'
+ ordered.append(module)
+
+ for i, module in enumerate(all_modules):
+ order([], module)
+ if i+1 == len(asked_modules):
+ break
+
+ return ordered
def get_full_module_list(self, skip=[]):
return self.get_module_list(self.modules.keys(), skip=skip)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]