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)
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
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)
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)