Esempio n. 1
0
File: cli.py Progetto: srand/jolt
def display(ctx, task, reverse=None, show_cache=False):
    """
    Display a task and its dependencies visually.

    """
    registry = TaskRegistry.get()
    gb = graph.GraphBuilder(registry, ctx.obj["manifest"])
    dag = gb.build(task, influence=show_cache)

    options = JoltOptions()
    acache = cache.ArtifactCache.get(options)

    if reverse:

        def iterator(task):
            return list(dag.predecessors(task))

        reverse = utils.as_list(reverse)
        tasklist = dag.select(lambda graph, node: node.short_qualified_name in
                              reverse or node.qualified_name in reverse)
    else:

        def iterator(task):
            return task.children

        tasklist = dag.requested_goals

    if dag.has_tasks():

        def _display(task, indent=0, last=None):
            header = ""
            if indent > 0:
                for pipe in last[:-1]:
                    if pipe:
                        header += "\u2502 "
                    else:
                        header += "  "
                if last[-1]:
                    header += "\u251c\u2574"
                else:
                    header += "\u2514\u2574"

            if not show_cache:
                colorize = str
            elif task.is_cacheable() and not acache.is_available(task):
                colorize = colors.red
            else:
                colorize = colors.green

            print(header + colorize(task.short_qualified_name))
            children = iterator(task)
            for i in range(0, len(children)):
                _display(children[i],
                         indent + 1,
                         last=(last or []) + [i + 1 != len(children)])

        for task in tasklist:
            _display(task)
    else:
        log.info("no tasks to display")
Esempio n. 2
0
    def load(self):
        super(NativeRecipe, self).load()

        name = utils.canonical(self.path)
        loader = SourceFileLoader("joltfile_{0}".format(name), self.path)
        module = ModuleType(loader.name)
        module.__file__ = self.path
        loader.exec_module(module)
        sys.modules[loader.name] = module

        classes = inspection.getmoduleclasses(module, [Task, TaskGenerator],
                                              NativeRecipe._is_abstract)
        generators = []

        for cls in classes[TaskGenerator]:
            cls.joltdir = self.joltdir or os.path.dirname(self.path)
            generators.append(cls())

        for generator in generators:
            generated_tasks = utils.as_list(generator.generate())
            classes[Task] += filter(NativeRecipe._is_task, generated_tasks)

        for task in classes[Task]:
            task.name = task.name or task.__name__.lower()
            task.joltdir = self.joltdir or os.path.dirname(self.path)
            task.joltproject = self.project
            self.tasks.append(task)

        log.verbose("Loaded: {0}", self.path)
Esempio n. 3
0
File: cli.py Progetto: srand/jolt
def _list(ctx, task=None, all=False, reverse=None):
    """
    List all tasks, or dependencies of a task.

    By default, when no TASK is specified, all known task names
    are listed in alphabetical order.

    When a TASK is specified, only direct dependencies of that task
    are listed. Use -a to also list its indirect dependencies.

    Multiple TASK names are allowed.
    """

    raise_error_if(not task and reverse, "TASK required with --reverse")

    registry = TaskRegistry.get()

    if not task:
        classes = registry.get_task_classes()
        for task in sorted(classes, key=lambda x: x.name):
            if task.name:
                print(task.name)
        return

    task = [utils.stable_task_name(t) for t in task]
    reverse = [utils.stable_task_name(t) for t in utils.as_list(reverse or [])]

    try:
        dag = graph.GraphBuilder(registry,
                                 ctx.obj["manifest"]).build(task,
                                                            influence=False)
    except JoltError as e:
        raise e
    except Exception:
        raise_error(
            "an exception occurred during task dependency evaluation, see log for details"
        )

    task = reverse or task
    nodes = dag.select(lambda graph, node: node.short_qualified_name in task or
                       node.qualified_name in task)
    nodes = list(nodes)
    iterator = dag.predecessors if reverse else dag.successors

    tasklist = set()
    while nodes:
        node = nodes.pop()
        for task in iterator(node):
            if all and task.short_qualified_name not in tasklist:
                new_node = dag.get_task(task.qualified_name)
                nodes.append(new_node)
            tasklist.add(task.short_qualified_name)

    for task in sorted(list(tasklist)):
        print(task)
Esempio n. 4
0
def new_git(url, path, relpath, refspecs=None):
    refspecs = utils.as_list(refspecs or [])
    try:
        git = _gits[path]
        raise_error_if(git.url != url,
                       "multiple git repositories required at {}", relpath)
        raise_error_if(
            git.refspecs != refspecs,
            "conflicting refspecs detected for git repository at  {}", relpath)
        return git
    except Exception:
        git = _gits[path] = GitRepository(url, path, relpath, refspecs)
        return git
Esempio n. 5
0
def _list(ctx, task=None, reverse=None):
    """
    List all tasks, or dependencies of a task.

    """

    raise_error_if(not task and reverse, "TASK required with --reverse")

    registry = TaskRegistry.get()

    if not task:
        classes = registry.get_task_classes()
        classes += registry.get_test_classes()
        for task in sorted(classes, key=lambda x: x.name):
            if task.name:
                print(task.name)
        return

    task = [utils.stable_task_name(t) for t in task]
    reverse = [utils.stable_task_name(t) for t in utils.as_list(reverse or [])]

    try:
        dag = graph.GraphBuilder(registry,
                                 ctx.obj["manifest"]).build(task,
                                                            influence=False)
    except JoltError as e:
        raise e
    except Exception:
        raise_error(
            "an exception occurred during task dependency evaluation, see log for details"
        )

    task = reverse or task
    nodes = dag.select(lambda graph, node: node.short_qualified_name in task or
                       node.qualified_name in task)

    tasklist = set()
    iterator = dag.predecessors if reverse else dag.successors

    for node in nodes:
        for task in iterator(node):
            tasklist.add(task.short_qualified_name)

    for task in sorted(list(tasklist)):
        print(task)
Esempio n. 6
0
    def load(self):
        super(NativeRecipe, self).load()

        name = utils.canonical(self.path)
        module = imp.load_source("joltfile_{0}".format(name), self.path)
        classes = inspect.getmoduleclasses(module, [Task, TaskGenerator],
                                           NativeRecipe._is_abstract)

        for cls in classes[TaskGenerator]:
            cls.joltdir = self.joltdir or os.path.dirname(self.path)
            generated_tasks = utils.as_list(cls().generate())
            classes[Task] += filter(NativeRecipe._is_task, generated_tasks)

        for task in classes[Task]:
            task.name = task.name or task.__name__.lower()
            task.joltdir = self.joltdir or os.path.dirname(self.path)
            task.joltproject = self.project
            self.tasks.append(task)

        log.verbose("Loaded: {0}", self.path)
Esempio n. 7
0
File: cli.py Progetto: srand/jolt
def inspect(ctx, task, influence=False, artifact=False, salt=None):
    """
    View information about a task.

    This command displays information about a task, such as its class
    documentation, parameters and their accepted values, requirements,
    task class origin (file/line), influence attributes, artifact identity,
    cache status, and more. Default parameter values, if any, are highlighted.

    """
    task_name = task
    task_cls_name, task_params = utils.parse_task_name(task_name)
    task_registry = TaskRegistry.get()
    task = task_registry.get_task_class(task_cls_name)
    raise_task_error_if(not task, task_name, "no such task")

    from jolt import inspection

    print()
    print("  {0}".format(task.name))
    print()
    if task.__doc__:
        print("  {0}".format(task.__doc__.strip()))
        print()
    print("  Parameters")
    has_param = False
    params = {
        key: getattr(task, key)
        for key in dir(task)
        if isinstance(utils.getattr_safe(task, key), Parameter)
    }
    for item, param in params.items():
        has_param = True
        print("    {0:<15}   {1}".format(item, param.help or ""))
    if not has_param:
        print("    None")

    print()
    print("  Definition")
    print("    {0:<15}   {1} ({2})".format(
        "File",
        fs.path.relpath(inspection.getfile(task),
                        JoltLoader.get().joltdir), inspection.getlineno(task)))

    print()
    print("  Requirements")
    manifest = ctx.obj["manifest"]
    try:
        task = task_registry.get_task(task_name, manifest=manifest)
        for req in sorted(
                utils.as_list(utils.call_or_return(task, task.requires))):
            print("    {0}".format(task.tools.expand(req)))
        if not task.requires:
            print("    None")
        print()
    except Exception as e:
        log.exception()
        if "has not been set" in str(e):
            print("    Unavailable (parameters must be set)")
            print()
            return
        print("    Unavailable (exception during evaluation)")
        print()
        return

    if salt:
        task.taint = salt

    if artifact:
        acache = cache.ArtifactCache.get()
        builder = graph.GraphBuilder(task_registry, manifest)
        dag = builder.build([task.qualified_name])
        tasks = dag.select(lambda graph, node: node.task is task)
        assert len(tasks) == 1, "graph produced multiple tasks, one expected"
        proxy = tasks[0]
        task = proxy.task

        print("  Cache")
        print("    Identity          {0}".format(proxy.identity))
        if acache.is_available_locally(proxy):
            with acache.get_artifact(proxy) as artifact:
                print("    Location          {0}".format(artifact.path))
            print("    Local             True ({0})".format(
                utils.as_human_size(acache.get_artifact(proxy).get_size())))
        else:
            print("    Local             False")
        print("    Remote            {0}".format(
            acache.is_available_remotely(proxy)))
        print()

    if influence:
        print("  Influence")
        for string in HashInfluenceRegistry.get().get_strings(task):
            string = string.split(":", 1)
            print("    {:<18}{}".format(string[0][10:], string[1].strip()))
Esempio n. 8
0
 def set_value(self, value, expand=True):
     values = utils.as_list(value)
     super(PathEnvironmentVariable, self).set_value(fs.pathsep.join(values),
                                                    expand)