Ejemplo n.º 1
0
def main():
    opt_parser = metomi.rose.opt_parse.RoseOptionParser()
    opt_parser.add_my_options("conf_dir", "property")
    metomi.rose.macro.add_meta_paths()
    opts, args = opt_parser.parse_args()
    reporter = metomi.rose.reporter.Reporter(opts.verbosity - opts.quietness)
    if opts.conf_dir is None:
        opts.conf_dir = os.getcwd()
    opts.conf_dir = os.path.abspath(opts.conf_dir)
    try:
        meta_config = metomi.rose.config_tree.ConfigTreeLoader().load(
            opts.conf_dir, metomi.rose.META_CONFIG_NAME, list(sys.path)).node
    except IOError:
        sys.exit(ERROR_LOAD_META_CONFIG_DIR.format(opts.conf_dir))
    sections = None
    if args:
        sections = args
    properties = None
    if opts.property:
        properties = opts.property
    reports = metadata_check(meta_config,
                             meta_dir=opts.conf_dir,
                             only_these_sections=sections,
                             only_these_properties=properties)
    macro_id = metomi.rose.macro.MACRO_OUTPUT_ID.format(
        metomi.rose.macro.VALIDATE_METHOD.upper()[0],
        "rose.metadata_check.MetadataChecker")
    reports_map = {None: reports}
    text = metomi.rose.macro.get_reports_as_text(reports_map, macro_id)
    if reports:
        reporter(text, kind=reporter.KIND_ERR, level=reporter.FAIL, prefix="")
        sys.exit(1)
    reporter(metomi.rose.macro.MacroFinishNothingEvent(), level=reporter.V)
Ejemplo n.º 2
0
def print_graph(suite_data, filter_id, properties=None, max_distance=None):
    """Dump out list of graph entries relating to a suite"""
    if properties is None:
        properties = []

    reporter = metomi.rose.reporter.Reporter()

    ancestry = {}
    # Process suite_data to get ancestry tree
    for dict_row in sorted(suite_data, key=lambda _: _["revision"]):
        idx = dict_row["idx"]
        from_idx = dict_row.get("from_idx")

        if idx not in ancestry:
            ancestry[idx] = {'parent': None, 'children': []}

        if from_idx:
            ancestry[idx]['parent'] = from_idx

        for prop in properties:
            ancestry[idx][prop] = dict_row.get(prop)

        if from_idx in ancestry:
            ancestry[from_idx]['children'].append(idx)
        else:
            ancestry[from_idx] = {'parent': None, 'children': [idx]}

    # Print out info
    parent_id = ancestry[filter_id]['parent']

    if parent_id:
        reporter(
            PrintSuiteDetails(parent_id,
                              [ancestry[parent_id][p] for p in properties]),
            prefix="[parent]",
        )
    else:
        reporter(PrintSuiteDetails(None), prefix="[parent]")

    children = ancestry[filter_id]['children']
    generation = 1
    # Print out each generation of child suites
    while children:
        next_children = []
        for child in children:
            reporter(
                PrintSuiteDetails(child,
                                  [ancestry[child][p] for p in properties]),
                prefix="[child%s]" % generation,
            )
            # If a child has children add to list of next generation children
            if ancestry[child]['children']:
                next_children += ancestry[child]['children']
        if max_distance and generation >= max_distance:
            break
        generation += 1
        children = next_children
Ejemplo n.º 3
0
def main():
    """Run rose upgrade."""
    return_objects = parse_upgrade_args()
    if return_objects is None:
        sys.exit(1)
    app_config, config_map, meta_config, _, args, opts = (
        return_objects)
    if opts.conf_dir is not None:
        os.chdir(opts.conf_dir)
    verbosity = 1 + opts.verbosity - opts.quietness
    reporter = metomi.rose.reporter.Reporter(verbosity)
    meta_opt_node = app_config.get([metomi.rose.CONFIG_SECT_TOP,
                                    metomi.rose.CONFIG_OPT_META_TYPE],
                                   no_ignore=True)
    if meta_opt_node is None or len(meta_opt_node.value.split("/")) < 2:
        reporter(metomi.rose.macro.MetaConfigFlagMissingError())
        sys.exit(1)
    try:
        upgrade_manager = MacroUpgradeManager(app_config, opts.downgrade)
    except OSError as exc:
        reporter(exc)
        sys.exit(1)
    need_all_versions = opts.all_versions or args
    ok_versions = upgrade_manager.get_tags(only_named=not need_all_versions)
    if args:
        user_choice = args[0]
    else:
        best_mark = BEST_VERSION_MARKER
        curr_mark = CURRENT_VERSION_MARKER
        all_versions = [" " * len(curr_mark) + v for v in ok_versions]
        if opts.downgrade:
            all_versions.reverse()
            if all_versions:
                all_versions[0] = best_mark + all_versions[0].lstrip()
            all_versions.append(curr_mark + upgrade_manager.tag)
        else:
            if all_versions:
                all_versions[-1] = best_mark + all_versions[-1].lstrip()
            all_versions.insert(0, curr_mark + upgrade_manager.tag)
        reporter("\n".join(all_versions) + "\n", prefix="")
        sys.exit()
    if user_choice == upgrade_manager.tag:
        reporter(UpgradeVersionSame(user_choice))
        sys.exit(1)
    elif user_choice not in ok_versions:
        reporter(UpgradeVersionError(user_choice))
        sys.exit(1)
    upgrade_manager.set_new_tag(user_choice)
    combined_config_map = metomi.rose.macro.combine_opt_config_map(config_map)
    macro_function = (
        lambda conf, meta, conf_key: upgrade_manager.transform(
            conf, meta, opts.non_interactive)
    )
    method_id = UPGRADE_METHOD.upper()[0]
    if opts.downgrade:
        method_id = DOWNGRADE_METHOD.upper()[0]
    macro_id = metomi.rose.macro.MACRO_OUTPUT_ID.format(
        method_id, upgrade_manager.get_name())
    new_config_map, changes_map = metomi.rose.macro.apply_macro_to_config_map(
        combined_config_map, meta_config, macro_function, macro_name=macro_id)
    sys.stdout.flush()  # Ensure text from macro output before next fn
    has_changes = metomi.rose.macro.handle_transform(
        config_map, new_config_map,
        changes_map, macro_id,
        opts.conf_dir, opts.output_dir,
        opts.non_interactive, reporter)
    if not has_changes:
        return
    new_meta_config = metomi.rose.macro.load_meta_config(
        new_config_map[None], directory=opts.conf_dir,
        config_type=metomi.rose.SUB_CONFIG_NAME,
        ignore_meta_error=True
    )
    config_map = new_config_map
    combined_config_map = metomi.rose.macro.combine_opt_config_map(config_map)
    macro_function = (
        lambda conf, meta, conf_key:
        metomi.rose.macros.trigger.TriggerMacro().transform(conf, meta)
    )
    new_config_map, changes_map = metomi.rose.macro.apply_macro_to_config_map(
        combined_config_map, new_meta_config, macro_function,
        macro_name=macro_id)
    trig_macro_id = metomi.rose.macro.MACRO_OUTPUT_ID.format(
        metomi.rose.macro.TRANSFORM_METHOD.upper()[0],
        MACRO_UPGRADE_TRIGGER_NAME
    )
    if any(changes_map.values()):
        metomi.rose.macro.handle_transform(
            config_map, new_config_map,
            changes_map, trig_macro_id,
            opts.conf_dir, opts.output_dir,
            opts.non_interactive, reporter)
Ejemplo n.º 4
0
def calculate_edges(graph,
                    suite_data,
                    filter_id=None,
                    properties=None,
                    max_distance=None):
    """Get all connected suites for a prefix, optionally filtered."""
    if properties is None:
        properties = []

    node_rosie_properties = {}
    edges = []
    forward_edges = {}
    back_edges = {}

    for dict_row in sorted(suite_data, key=lambda _: _["revision"]):
        idx = dict_row["idx"]
        node_rosie_properties[idx] = []
        for prop in properties:
            node_rosie_properties[idx].append(dict_row.get(prop))
        from_idx = dict_row.get("from_idx")

        if from_idx is None:
            continue

        edges.append((from_idx, idx))
        forward_edges.setdefault(from_idx, [])
        forward_edges[from_idx].append(idx)
        back_edges.setdefault(idx, [])
        back_edges[idx].append(from_idx)

    if filter_id is None:
        # Plot all the edges we've found.
        for edge in sorted(edges):
            node0, node1 = edge
            add_node(graph, node0, node_rosie_properties.get(node0))
            add_node(graph, node1, node_rosie_properties.get(node1))
            graph.add_edge(edge[0], edge[1])
    else:
        reporter = metomi.rose.reporter.Reporter()

        # Only plot the connections involving filter_id.
        node_stack = []
        node_stack = [(filter_id, 0)]
        add_node(
            graph,
            filter_id,
            node_rosie_properties.get(filter_id),
            fillcolor="lightgrey",
            style="filled",
        )

        ok_nodes = set([])
        while node_stack:
            node, distance = node_stack.pop()
            if max_distance is not None and distance > max_distance:
                continue
            ok_nodes.add(node)
            for neighbour_node in forward_edges.get(node, []) + back_edges.get(
                    node, []):
                if neighbour_node not in ok_nodes:
                    node_stack.append((neighbour_node, distance + 1))

        if len(ok_nodes) == 1:
            # There are no related suites.
            reporter(NoConnectionsEvent(filter_id))

        for edge in sorted(edges):
            node0, node1 = edge
            if node0 in ok_nodes and node1 in ok_nodes:
                add_node(graph, node0, node_rosie_properties.get(node0))
                add_node(graph, node1, node_rosie_properties.get(node1))
                graph.add_edge(node0, node1)