def looks_like_a_workflow(path): """Return boolean indicating if this path looks like a workflow.""" if POTENTIAL_WORKFLOW_FILES.match(os.path.basename(path)): with open(path, "r") as f: workflow_dict = ordered_load(f) if not isinstance(workflow_dict, dict): # Not exactly right - could have a #main def - do better and sync with Galaxy. return False return workflow_dict.get("class") == "GalaxyWorkflow" or workflow_dict.get("a_galaxy_workflow") return False
def test_normalized_workflow(): # same workflow with slightly different input definitions, make sure normalize # unifies these for wf in [INTEGER_INPUT, INT_INPUT]: int_input_normalized = NormalizedWorkflow( ordered_load(INT_INPUT)).normalized_workflow_dict inputs = int_input_normalized["inputs"] assert isinstance(inputs, list) assert isinstance(inputs[0], dict) # str converted to dictionary assert inputs[0]["id"] == "input_d" assert inputs[0]["type"] == "data" # converted from File to data assert isinstance(inputs[1], dict) assert inputs[1]["type"] == "int"
def main(argv): """Script entry point for linting workflows.""" path = argv[1] with open(path, "r") as f: try: workflow_dict = ordered_load(f) except Exception: return EXIT_CODE_FILE_PARSE_FAILED workflow_class = workflow_dict.get("class") lint_func = lint_format2 if workflow_class == "GalaxyWorkflow" else lint_ga lint_context = LintContext() lint_func(lint_context, workflow_dict, path=path) lint_context.print_messages() if lint_context.found_errors: return EXIT_CODE_FORMAT_ERROR elif lint_context.found_warns: return EXIT_CODE_LINT_FAILED else: return EXIT_CODE_SUCCESS
def test_export_native_no_labels(): # Ensure outputs don't get mapped to 'null' key and ensure native_unicycler = ordered_load( open(os.path.join(TEST_PATH, "unicycler.ga"), "r").read()) before_output_count = 0 for workflow_output in native_workflow_outputs(native_unicycler): before_output_count += 1 before_step_count = len(native_unicycler["steps"]) unicycler_no_output_labels = copy_without_workflow_output_labels( native_unicycler) as_format2 = from_native(unicycler_no_output_labels) assert len(as_format2["outputs"]) == before_output_count round_trip_unicycler = to_native(as_format2) after_output_count = 0 for workflow_output in native_workflow_outputs(round_trip_unicycler): after_output_count += 1 after_step_count = len(round_trip_unicycler["steps"]) assert after_step_count == before_step_count assert after_output_count == before_output_count, round_trip_unicycler
def structure(path, lint_context): with open(path, "r") as f: workflow_dict = ordered_load(f) workflow_class = workflow_dict.get("class") lint_func = lint_format2 if workflow_class == "GalaxyWorkflow" else lint_ga lint_func(lint_context, workflow_dict, path=path)
def setup_module(module): # Setup an examples directory with examples we want to correspond to what exit codes, # do this so we can run same tests in Java. green_format2 = ordered_load(BASIC_WORKFLOW) _dump_with_exit_code(green_format2, 0, "basic_format2") green_native = to_native(BASIC_WORKFLOW) assert_valid_native(green_native) _dump_with_exit_code(green_native, 0, "basic_native") green_explicit_errors_null = _deep_copy(green_native) for step, step_def in green_explicit_errors_null["steps"].items(): step_def["errors"] = None _dump_with_exit_code(green_explicit_errors_null, 0, "basic_native_explicit_no_errors") invalid_format2_no_format_dict = _deep_copy(green_format2) del invalid_format2_no_format_dict["class"] _dump_with_exit_code(invalid_format2_no_format_dict, 2, "format2_no_class") invalid_ga_no_format_dict = _deep_copy(green_native) del invalid_ga_no_format_dict["a_galaxy_workflow"] _dump_with_exit_code(invalid_ga_no_format_dict, 2, "native_no_class") invalid_ga_steps_not_order_index_dict = _deep_copy(green_native) steps = invalid_ga_steps_not_order_index_dict["steps"] step_0 = steps.pop("0") steps["moo_0"] = step_0 _dump_with_exit_code(invalid_ga_steps_not_order_index_dict, 2, "native_step_not_order_index") invalid_ga_no_steps = _deep_copy(green_native) invalid_ga_no_steps.pop("steps") _dump_with_exit_code(invalid_ga_no_steps, 2, "native_no_steps") invalid_format2_no_steps_dict = _deep_copy(green_format2) del invalid_format2_no_steps_dict["steps"] _dump_with_exit_code(invalid_format2_no_steps_dict, 2, "format2_no_steps") red_format2_step_errors = _deep_copy(green_format2) red_format2_step_errors["steps"]["cat"]["errors"] = "Tool is not installed." _dump_with_exit_code(red_format2_step_errors, 1, "format2_step_errors") red_native_step_errors = _deep_copy(green_native) red_native_step_errors["steps"]["1"]["errors"] = "Tool is not installed." _dump_with_exit_code(red_native_step_errors, 1, "native_step_errors") red_ga_no_outputs = _deep_copy(green_native) red_ga_no_outputs_steps = red_ga_no_outputs.get("steps") for step in red_ga_no_outputs_steps.values(): step.pop("workflow_outputs", None) _dump_with_exit_code(red_ga_no_outputs, 1, "native_no_outputs") red_ga_no_output_labels = copy_without_workflow_output_labels(green_native) _dump_with_exit_code(red_ga_no_output_labels, 1, "native_no_output_labels") # gotta call this a format error to implement Process in schema... red_format2_no_outputs = _deep_copy(green_format2) del red_format2_no_outputs["outputs"] _dump_with_exit_code(red_format2_no_outputs, 2, "format2_no_output") green_format2_rules = ordered_load(RULES_TOOL) _dump_with_exit_code(green_format2_rules, 0, "format2_rules") green_native_rules = to_native(RULES_TOOL) _dump_with_exit_code(green_native_rules, 0, "native_format") green_format2_repeat = ordered_load(WORKFLOW_WITH_REPEAT) _dump_with_exit_code(green_format2_repeat, 0, "format2_repeat") green_native_rules = to_native(WORKFLOW_WITH_REPEAT) _dump_with_exit_code(green_native_rules, 0, "native_repeat") green_format2_nested = ordered_load(NESTED_WORKFLOW) _dump_with_exit_code(green_format2_nested, 0, "format2_nested") green_native_nested = to_native(NESTED_WORKFLOW) _dump_with_exit_code(green_native_nested, 0, "native_nested") invalid_format2_nested = _deep_copy(green_format2_nested) del invalid_format2_nested["steps"]["nested_workflow"]["run"]["steps"] _dump_with_exit_code(invalid_format2_nested, 2, "format2_nested_no_steps") invalid_native_nested = _deep_copy(green_native_nested) del invalid_native_nested["steps"]['2']['subworkflow']['steps'] _dump_with_exit_code(invalid_native_nested, 2, "native_nested_no_steps") green_format2_runtime_inputs = ordered_load(RUNTIME_INPUTS) _dump_with_exit_code(green_format2_runtime_inputs, 0, "format2_runtime_inputs") green_native_runtime_inputs = to_native(RUNTIME_INPUTS) _dump_with_exit_code(green_native_runtime_inputs, 0, "native_runtime_inputs") green_format2_runtime_inputs = ordered_load(RUNTIME_INPUTS) invalid_format2_runtime_inputs_type = _deep_copy(green_format2_runtime_inputs) invalid_format2_runtime_inputs_type['steps']['random']['runtime_inputs'][0] = 5 _dump_with_exit_code(invalid_format2_runtime_inputs_type, 2, "format2_runtime_inputs_invalid_type") green_format2_pja = ordered_load(PJA_1) _dump_with_exit_code(green_format2_runtime_inputs, 0, "format2_pja1") invalid_format2_pja_hide_type = _deep_copy(green_format2_pja) invalid_format2_pja_hide_type['steps']['first_cat']['out']['out_file1']['hide'] = "moocow" _dump_with_exit_code(invalid_format2_pja_hide_type, 2, "format2_pja_hide_invalid_type") green_format2_report = ordered_load(WITH_REPORT) _dump_with_exit_code(green_format2_report, 0, "format2_report") green_native_report = to_native(WITH_REPORT) _dump_with_exit_code(green_native_report, 0, "native_report") invalid_format2_report_type = _deep_copy(green_format2_report) invalid_format2_report_type["report"]["markdown"] = 5 _dump_with_exit_code(invalid_format2_report_type, 2, "format2_report_invalid_type") invalid_native_report_type = _deep_copy(green_native_report) invalid_native_report_type["report"]["markdown"] = 5 _dump_with_exit_code(invalid_native_report_type, 2, "native_report_invalid_type") invalid_format2_report_markdown = _deep_copy(green_format2_report) invalid_format2_report_markdown["report"]["markdown"] += "\n```galaxy\ncow()\n```\n" _dump_with_exit_code(invalid_format2_report_markdown, 2, "format2_report_invalid_markdown") invalid_native_report_markdown = _deep_copy(green_native_report) invalid_native_report_markdown["report"]["markdown"] += "\n```galaxy\ncow()\n```\n" _dump_with_exit_code(invalid_native_report_markdown, 2, "native_report_invalid_markdown") invalid_format2_report_missing_markdown = _deep_copy(green_format2_report) del invalid_format2_report_missing_markdown["report"]["markdown"] _dump_with_exit_code(invalid_format2_report_missing_markdown, 2, "format2_report_missing_markdown") invalid_native_report_missing_markdown = _deep_copy(green_native_report) del invalid_native_report_missing_markdown["report"]["markdown"] _dump_with_exit_code(invalid_native_report_missing_markdown, 2, "native_report_missing_markdown") green_format2_vocab_keys = ordered_load(WORKFLOW_VOCAB_KEYS) _dump_with_exit_code(green_format2_vocab_keys, 0, "format2_vocab_keys") green_format2_int_input = ordered_load(INT_INPUT) _dump_with_exit_code(green_format2_int_input, 0, "format2_int_input") valid_int_default_type = _deep_copy(green_format2_int_input) valid_int_default_type["inputs"]["num_lines"]["default"] = 5 _dump_with_exit_code(valid_int_default_type, 0, "format2_int_input_valid_default") valid_float_default_type = _deep_copy(green_format2_int_input) valid_float_default_type["inputs"]["num_lines"]["type"] = "float" valid_float_default_type["inputs"]["num_lines"]["default"] = 5.0 _dump_with_exit_code(valid_float_default_type, 0, "format2_int_input_valid_default") invalid_int_default_type = _deep_copy(green_format2_int_input) invalid_int_default_type["inputs"]["num_lines"]["default"] = "bad_default" _dump_with_exit_code(invalid_int_default_type, 2, "format2_int_input_bad_default") invalid_float_default_type = _deep_copy(green_format2_int_input) invalid_float_default_type["inputs"]["num_lines"]["type"] = "float" invalid_float_default_type["inputs"]["num_lines"]["default"] = "bad_default" _dump_with_exit_code(invalid_float_default_type, 2, "format2_float_input_bad_default") green_format2_text_input = ordered_load(STRING_INPUT) _dump_with_exit_code(green_format2_text_input, 0, "format2_string_input") invalid_string_default_type = _deep_copy(green_format2_text_input) invalid_string_default_type["inputs"]["seed"]["default"] = 6 _dump_with_exit_code(invalid_string_default_type, 2, "format2_string_input_bad_default") # ensure that round tripping all green format2 workflows still lint green. for file_name in os.listdir(TEST_LINT_EXAMPLES): if file_name.startswith("0_format2") and "roundtrip" not in file_name: roundtrip_contents = round_trip(open(os.path.join(TEST_LINT_EXAMPLES, file_name), "r").read()) base = os.path.splitext(file_name)[0][len("0_"):] _dump_with_exit_code(roundtrip_contents, 0, base + "_roundtrip")
def test_nested_workflow(): path = _examples_path_for("nested_format2.cwl") _run_example(ordered_load(NESTED_WORKFLOW), out=path)
def _run_example_path(path): out = _examples_path_for(path) with open(path, "r") as f: return _run_example(ordered_load(f), out)
def _both_formats(contents): return [ordered_load(contents), to_native(contents)]