Commit bd90944b authored by Kazuhiko Shiozaki's avatar Kazuhiko Shiozaki

Add referred parts' hash strings in __buildout_signature__, that invokes...

Add referred parts' hash strings in __buildout_signature__, that invokes rebuild of a part when one of its (recursive) dependencies are modified.

Also remove duplicates and sort entries in __buildout_signature__.
parent d45589b2
...@@ -657,7 +657,6 @@ class Buildout(DictMixin): ...@@ -657,7 +657,6 @@ class Buildout(DictMixin):
if k not in old_options: if k not in old_options:
self._logger.debug("Part %s, new option %s.", self._logger.debug("Part %s, new option %s.",
part, k) part, k)
elif not uninstall_missing: elif not uninstall_missing:
continue continue
...@@ -866,7 +865,13 @@ class Buildout(DictMixin): ...@@ -866,7 +865,13 @@ class Buildout(DictMixin):
options = self[part] = {} options = self[part] = {}
recipe, entry = _recipe(options) recipe, entry = _recipe(options)
req = pkg_resources.Requirement.parse(recipe) req = pkg_resources.Requirement.parse(recipe)
sig = _dists_sig(pkg_resources.working_set.resolve([req])) sig = sorted(set(_dists_sig(pkg_resources.working_set.resolve([req]))))
for dependency in sorted(getattr(options, '_dependency', [])):
m = md5()
for k, v in sorted(self.get(dependency).items()):
m.update(('%r: %r' % (k, v)).encode())
dependency_hash = m.hexdigest()
sig.append('%s:%s' % (dependency, dependency_hash))
options['__buildout_signature__'] = ' '.join(sig) options['__buildout_signature__'] = ' '.join(sig)
def _read_installed_part_options(self): def _read_installed_part_options(self):
...@@ -1274,6 +1279,7 @@ class Options(DictMixin): ...@@ -1274,6 +1279,7 @@ class Options(DictMixin):
self._raw = data self._raw = data
self._cooked = {} self._cooked = {}
self._data = {} self._data = {}
self._dependency = set([])
def _initialize(self): def _initialize(self):
name = self.name name = self.name
...@@ -1400,6 +1406,8 @@ class Options(DictMixin): ...@@ -1400,6 +1406,8 @@ class Options(DictMixin):
section, option = s section, option = s
if not section: if not section:
section = self.name section = self.name
elif section != 'buildout':
self._dependency.add(section)
v = self.buildout[section].get(option, None, seen) v = self.buildout[section].get(option, None, seen)
if v is None: if v is None:
if option == '_buildout_section_name_': if option == '_buildout_section_name_':
......
...@@ -2529,7 +2529,7 @@ were created. ...@@ -2529,7 +2529,7 @@ were created.
The .installed.cfg is only updated for the recipes that ran: The .installed.cfg is only updated for the recipes that ran:
>>> cat(sample_buildout, '.installed.cfg') >>> cat(sample_buildout, '.installed.cfg')
... # doctest: +NORMALIZE_WHITESPACE ... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
[buildout] [buildout]
installed_develop_eggs = /sample-buildout/develop-eggs/recipes.egg-link installed_develop_eggs = /sample-buildout/develop-eggs/recipes.egg-link
parts = debug d1 d2 d3 d4 parts = debug d1 d2 d3 d4
...@@ -2559,7 +2559,7 @@ The .installed.cfg is only updated for the recipes that ran: ...@@ -2559,7 +2559,7 @@ The .installed.cfg is only updated for the recipes that ran:
<BLANKLINE> <BLANKLINE>
[d4] [d4]
__buildout_installed__ = /sample-buildout/data2-extra __buildout_installed__ = /sample-buildout/data2-extra
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg== __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg== d2:...
path = /sample-buildout/data2-extra path = /sample-buildout/data2-extra
recipe = recipes:mkdir recipe = recipes:mkdir
...@@ -2571,6 +2571,7 @@ Now, if we run the buildout without the install command: ...@@ -2571,6 +2571,7 @@ Now, if we run the buildout without the install command:
>>> print_(system(buildout), end='') >>> print_(system(buildout), end='')
Develop: '/sample-buildout/recipes' Develop: '/sample-buildout/recipes'
Uninstalling d4.
Uninstalling d2. Uninstalling d2.
Uninstalling d1. Uninstalling d1.
Uninstalling debug. Uninstalling debug.
...@@ -2580,7 +2581,8 @@ Now, if we run the buildout without the install command: ...@@ -2580,7 +2581,8 @@ Now, if we run the buildout without the install command:
Installing d2. Installing d2.
d2: Creating directory data2 d2: Creating directory data2
Updating d3. Updating d3.
Updating d4. Installing d4.
d4: Creating directory data2-extra
We see the output of the debug recipe and that data2 was created. We We see the output of the debug recipe and that data2 was created. We
also see that d1 and d2 have gone away: also see that d1 and d2 have gone away:
......
...@@ -97,17 +97,14 @@ of extra requirements to be included in the working set. ...@@ -97,17 +97,14 @@ of extra requirements to be included in the working set.
We can see that the options were augmented with additional data We can see that the options were augmented with additional data
computed by the egg recipe by looking at .installed.cfg: computed by the egg recipe by looking at .installed.cfg:
>>> cat(sample_buildout, '.installed.cfg') >>> cat(sample_buildout, '.installed.cfg') # doctest: +ELLIPSIS
[buildout] [buildout]
installed_develop_eggs = /sample-buildout/develop-eggs/sample.egg-link installed_develop_eggs = /sample-buildout/develop-eggs/sample.egg-link
parts = sample-part parts = sample-part
<BLANKLINE> <BLANKLINE>
[sample-part] [sample-part]
__buildout_installed__ = __buildout_installed__ =
__buildout_signature__ = sample-6aWMvV2EJ9Ijq+bR8ugArQ== __buildout_signature__ = sample-... setuptools-...egg zc.buildout-... zc.recipe.egg-...
zc.recipe.egg-cAsnudgkduAa/Fd+WJIM6Q==
setuptools-0.7-py2.4.egg
zc.buildout-+rYeCcmFuD1K/aB77XTj5A==
_b = /sample-buildout/bin _b = /sample-buildout/bin
_d = /sample-buildout/develop-eggs _d = /sample-buildout/develop-eggs
_e = /sample-buildout/eggs _e = /sample-buildout/eggs
......
  • This needs to be reviewed. I have a case of dependency that is not detected. The option is retrieved from a recipe __init__ (buildout[section][option]) and Options.get returns immediately.

    Other minor remarks:

    • set([]) -> set()
    • .hexdigest() -> .digest().encode('base64').strip() (smaller and same as for eggs)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment