Example #1
0
def test_flatten_walk():
    walk = [{'e': 1, 'a': 2},
            [{'e': 1, 'z': 5}, {'e': 2}, [{'x': 50}]]]
    flat = flatten_walk(walk, ['e', 'x'])
    assert_equal(flat, {'e': set((1, 2)), 'x': set([50])})
Example #2
0
    def collect_dependencies(self,
                             obj,
                             dependencies=['build', 'runtime'],
                             ids=[],
                             caller=None):
        """ Build a dict of dependencies for a given obj.

        NB : This assumes the obj has a walk method similar to the one found
        in ComplexTask

        Parameters
        ----------
        obj : object with a walk method
            Obj for which dependencies should be computed.

        dependencies : {['build'], ['runtime'], ['build', 'runtime']}
            Kind of dependencies which should be gathered.

        ids : list, optional
            List of dependencies ids to use when collecting.

        caller : optional
            Calling plugin. Used for some runtime dependencies needing to know
            the ressource owner.

        Returns
        -------
        result : bool
            Flag indicating the success of the operation.

        dependencies : dict
            In case of success:
            - Dicts holding all the classes or other dependencies to build, run
            or build and run a task without any access to the workbench.
            If a single kind of dependencies is requested a single dict is
            returned otherwise two are returned one for the build ones and one
            for the runtime ones

            Otherwise:
            - dict holding the id of the dependencie and the asssociated
            error message.

        """
        # Use a set to avoid collecting several times the same entry, which
        # could happen if an entry is both a build and a runtime dependency.
        members = set()
        callables = {}
        if 'runtime' in dependencies and caller is None:
            raise RuntimeError(
                cleandoc('''Cannot collect runtime dependencies
                without knowing the caller plugin'''))

        if 'build' in dependencies:
            if ids:
                b = self.build_collectors
                build_deps = [dep for id, dep in b.iteritems() if id in ids]
            else:
                build_deps = self.build_collectors.values()

            for build_dep in build_deps:
                members.update(set(build_dep.walk_members))

        if 'runtime' in dependencies:
            if ids:
                r = self.runtime_collectors
                runtime_deps = [dep for id, dep in r.iteritems() if id in ids]
            else:
                runtime_deps = self.runtime_collectors.values()

            for runtime_dep in runtime_deps:
                members.update(set(runtime_dep.walk_members))
                callables.update(runtime_dep.walk_callables)

        walk = obj.walk(members, callables)
        flat_walk = flatten_walk(walk, list(members) + callables.keys())

        deps = ({}, {})
        errors = {}
        if 'build' in dependencies:
            for build_dep in self.build_collectors.values():
                try:
                    deps[0].update(build_dep.collect(self.workbench,
                                                     flat_walk))
                except ValueError as e:
                    errors[build_dep.id] = e.message

        if 'runtime' in dependencies:
            for runtime_dep in self.runtime_collectors.values():
                try:
                    deps[1].update(
                        runtime_dep.collect(self.workbench, flat_walk, caller))
                except ValueError as e:
                    errors[runtime_dep.id] = e.message

        if errors:
            return False, errors

        if 'build' in dependencies and 'runtime' in dependencies:
            return True, deps[0], deps[1]
        elif 'build' in dependencies:
            return True, deps[0]
        else:
            return True, deps[1]
Example #3
0
    def collect_dependencies(self, obj, dependencies=['build', 'runtime'],
                             ids=[], caller=None):
        """ Build a dict of dependencies for a given obj.

        NB : This assumes the obj has a walk method similar to the one found
        in ComplexTask

        Parameters
        ----------
        obj : object with a walk method
            Obj for which dependencies should be computed.

        dependencies : {['build'], ['runtime'], ['build', 'runtime']}
            Kind of dependencies which should be gathered.

        ids : list, optional
            List of dependencies ids to use when collecting.

        caller : optional
            Calling plugin. Used for some runtime dependencies needing to know
            the ressource owner.

        Returns
        -------
        result : bool
            Flag indicating the success of the operation.

        dependencies : dict
            In case of success:
            - Dicts holding all the classes or other dependencies to build, run
            or build and run a task without any access to the workbench.
            If a single kind of dependencies is requested a single dict is
            returned otherwise two are returned one for the build ones and one
            for the runtime ones

            Otherwise:
            - dict holding the id of the dependencie and the asssociated
            error message.

        """
        # Use a set to avoid collecting several times the same entry, which
        # could happen if an entry is both a build and a runtime dependency.
        members = set()
        callables = {}
        if 'runtime' in dependencies and caller is None:
            raise RuntimeError(cleandoc('''Cannot collect runtime dependencies
                without knowing the caller plugin'''))

        if 'build' in dependencies:
            if ids:
                b = self.build_collectors
                build_deps = [dep for id, dep in b.iteritems()
                              if id in ids]
            else:
                build_deps = self.build_collectors.values()

            for build_dep in build_deps:
                members.update(set(build_dep.walk_members))

        if 'runtime' in dependencies:
            if ids:
                r = self.runtime_collectors
                runtime_deps = [dep for id, dep in r.iteritems()
                                if id in ids]
            else:
                runtime_deps = self.runtime_collectors.values()

            for runtime_dep in runtime_deps:
                members.update(set(runtime_dep.walk_members))
                callables.update(runtime_dep.walk_callables)

        walk = obj.walk(members, callables)
        flat_walk = flatten_walk(walk, list(members) + callables.keys())

        deps = ({}, {})
        errors = {}
        if 'build' in dependencies:
            for build_dep in self.build_collectors.values():
                try:
                    deps[0].update(build_dep.collect(self.workbench,
                                                     flat_walk))
                except ValueError as e:
                    errors[build_dep.id] = e.message

        if 'runtime' in dependencies:
            for runtime_dep in self.runtime_collectors.values():
                try:
                    deps[1].update(runtime_dep.collect(self.workbench,
                                                       flat_walk, caller))
                except ValueError as e:
                    errors[runtime_dep.id] = e.message

        if errors:
            return False, errors

        if 'build' in dependencies and 'runtime' in dependencies:
            return True, deps[0], deps[1]
        elif 'build' in dependencies:
            return True, deps[0]
        else:
            return True, deps[1]
Example #4
0
def test_flatten_walk():
    walk = [{'e': 1, 'a': 2}, [{'e': 1, 'z': 5}, {'e': 2}, [{'x': 50}]]]
    flat = flatten_walk(walk, ['e', 'x'])
    assert_equal(flat, {'e': set((1, 2)), 'x': set([50])})