From 84770b9ef2afbfa1232845ce6538b56df99cee3a Mon Sep 17 00:00:00 2001 From: Steven Armstrong Date: Mon, 19 Nov 2012 11:25:56 +0100 Subject: [PATCH] implement before/after to declare dependencies and deprecate require Signed-off-by: Steven Armstrong --whitespace Signed-off-by: Steven Armstrong --- cdist/core/cdist_object.py | 2 ++ cdist/emulator.py | 25 +++++++++++++++++++++---- cdist/resolver.py | 17 ++++++++++++++--- cdist/test/object/__init__.py | 1 + 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/cdist/core/cdist_object.py b/cdist/core/cdist_object.py index 90a21e59..7e587bf3 100644 --- a/cdist/core/cdist_object.py +++ b/cdist/core/cdist_object.py @@ -186,6 +186,8 @@ class CdistObject(object): return os.path.join(self.path, "explorer") requirements = fsproperty.FileListProperty(lambda obj: os.path.join(obj.absolute_path, 'require')) + before = fsproperty.FileListProperty(lambda obj: os.path.join(obj.absolute_path, 'before')) + after = fsproperty.FileListProperty(lambda obj: os.path.join(obj.absolute_path, 'after')) autorequire = fsproperty.FileListProperty(lambda obj: os.path.join(obj.absolute_path, 'autorequire')) parameters = fsproperty.DirectoryDictProperty(lambda obj: os.path.join(obj.base_path, obj.parameter_path)) explorers = fsproperty.DirectoryDictProperty(lambda obj: os.path.join(obj.base_path, obj.explorer_path)) diff --git a/cdist/emulator.py b/cdist/emulator.py index a9c760cb..bd3661d3 100644 --- a/cdist/emulator.py +++ b/cdist/emulator.py @@ -23,6 +23,7 @@ import argparse import logging import os +import warnings import sys import cdist @@ -92,8 +93,12 @@ class Emulator(object): def commandline(self): """Parse command line""" + self.meta_parameters = dict.fromkeys(('after', 'before')) + meta_parser = argparse.ArgumentParser(add_help=False) + for meta_parameter in self.meta_parameters.keys(): + meta_parser.add_argument('--%s' % meta_parameter, action='append', required=False) - parser = argparse.ArgumentParser(add_help=False, argument_default=argparse.SUPPRESS) + parser = argparse.ArgumentParser(add_help=False, parents=[meta_parser], argument_default=argparse.SUPPRESS) for parameter in self.cdist_type.required_parameters: argument = "--" + parameter @@ -119,6 +124,11 @@ class Emulator(object): self.args = parser.parse_args(self.argv[1:]) self.log.debug('Args: %s' % self.args) + # Handle meta parameters + for meta_parameter in self.meta_parameters.keys(): + if meta_parameter in self.args: + self.meta_parameters[meta_parameter] = getattr(self.args, meta_parameter) + delattr(self.args, meta_parameter) def setup_object(self): # Setup object_id - FIXME: unset / do not setup anymore! @@ -175,10 +185,18 @@ class Emulator(object): def record_requirements(self): """record requirements""" + for key in ('before', 'after'): + if key in self.meta_parameters and self.meta_parameters[key]: + for value in self.meta_parameters[key]: + self.log.debug("Recording requirement: %s %s %s", self.cdist_object.name, key, value) + dependency_list = getattr(self.cdist_object, key) + # append to the object.after or object.before lists + dependency_list.append(value) if "require" in self.env: + warnings.warn("The 'require' envrionment variable is deprecated. Use the --before and --after meta parameters to define dependencies.", category=PendingDeprecationWarning, stacklevel=2) + requirements = self.env['require'] - self.log.debug("reqs = " + requirements) for requirement in requirements.split(" "): # Ignore empty fields - probably the only field anyway if len(requirement) == 0: continue @@ -187,11 +205,10 @@ class Emulator(object): cdist_object = self.cdist_object.object_from_name(requirement) self.log.debug("Recording requirement: " + requirement) - # Save the sanitised version, not the user supplied one # (__file//bar => __file/bar) # This ensures pattern matching is done against sanitised list - self.cdist_object.requirements.append(cdist_object.name) + self.cdist_object.after.append(cdist_object.name) def record_auto_requirements(self): """An object shall automatically depend on all objects that it defined in it's type manifest. diff --git a/cdist/resolver.py b/cdist/resolver.py index 7e3a1a68..d181d066 100644 --- a/cdist/resolver.py +++ b/cdist/resolver.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# 2011 Steven Armstrong (steven-cdist at armstrong.cc) +# 2011-2012 Steven Armstrong (steven-cdist at armstrong.cc) # # This file is part of cdist. # @@ -109,10 +109,21 @@ class DependencyResolver(object): raise RequirementNotFoundError(pattern) def _preprocess_requirements(self): - """Find all autorequire dependencies and merge them to be just requirements - for further processing. + """Find all before, after and autorequire dependencies and merge them + to be just requirements for further processing. """ for cdist_object in self.objects.values(): + if cdist_object.after: + cdist_object.requirements.extend(cdist_object.after) + # As we changed the object on disc, we have to ensure it is not + # preprocessed again if someone would call us multiple times. + cdist_object.after = [] + if cdist_object.before: + for other_object in self.find_requirements_by_name(cdist_object.before): + other_object.requirements.append(cdist_object.name) + # As we changed the object on disc, we have to ensure it is not + # preprocessed again if someone would call us multiple times. + cdist_object.before = [] if cdist_object.autorequire: # The objects (children) that this cdist_object (parent) defined # in it's type manifest shall inherit all explicit requirements diff --git a/cdist/test/object/__init__.py b/cdist/test/object/__init__.py index 3a91f709..7bdc037e 100644 --- a/cdist/test/object/__init__.py +++ b/cdist/test/object/__init__.py @@ -87,6 +87,7 @@ class ObjectTestCase(test.CdistTestCase): self.cdist_object.code_local = '' self.cdist_object.code_remote = '' self.cdist_object.state = '' + self.cdist_object.requirements = [] def test_name(self): self.assertEqual(self.cdist_object.name, '__third/moon')