/
meta_yml.py
88 lines (76 loc) · 3.58 KB
/
meta_yml.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#!/usr/bin/env python
from pathlib import Path
import yaml
from nf_core.modules.modules_differ import ModulesDiffer
def meta_yml(module_lint_object, module):
"""
Lint a ``meta.yml`` file
The lint test checks that the module has
a ``meta.yml`` file and that it contains
the required keys: ``name``, input`` and
``output``.
In addition it checks that the module name
and module input is consistent between the
``meta.yml`` and the ``main.nf``.
"""
required_keys = ["name", "output"]
required_keys_lists = ["input", "output"]
# Check if we have a patch file, get original file in that case
meta_yaml = None
if module.is_patched:
lines = ModulesDiffer.try_apply_patch(
module.module_name,
module_lint_object.modules_repo.fullname,
module.patch_path,
Path(module.module_dir).relative_to(module.base_dir),
reverse=True,
).get("meta.yml")
if lines is not None:
meta_yaml = yaml.safe_load("".join(lines))
if meta_yaml is None:
try:
with open(module.meta_yml, "r") as fh:
meta_yaml = yaml.safe_load(fh)
module.passed.append(("meta_yml_exists", "Module `meta.yml` exists", module.meta_yml))
except FileNotFoundError:
module.failed.append(("meta_yml_exists", "Module `meta.yml` does not exist", module.meta_yml))
return
# Confirm that all required keys are given
contains_required_keys = True
all_list_children = True
for rk in required_keys:
if rk not in meta_yaml.keys():
module.failed.append(("meta_required_keys", f"`{rk}` not specified in YAML", module.meta_yml))
contains_required_keys = False
elif rk in meta_yaml.keys() and not isinstance(meta_yaml[rk], list) and rk in required_keys_lists:
module.failed.append(("meta_required_keys", f"`{rk}` is not a list", module.meta_yml))
all_list_children = False
if contains_required_keys:
module.passed.append(("meta_required_keys", "`meta.yml` contains all required keys", module.meta_yml))
# Confirm that all input and output channels are specified
if contains_required_keys and all_list_children:
if "input" in meta_yaml:
meta_input = [list(x.keys())[0] for x in meta_yaml["input"]]
for input in module.inputs:
if input in meta_input:
module.passed.append(("meta_input", f"`{input}` specified", module.meta_yml))
else:
module.failed.append(("meta_input", f"`{input}` missing in `meta.yml`", module.meta_yml))
if "output" in meta_yaml:
meta_output = [list(x.keys())[0] for x in meta_yaml["output"]]
for output in module.outputs:
if output in meta_output:
module.passed.append(("meta_output", f"`{output}` specified", module.meta_yml))
else:
module.failed.append(("meta_output", f"`{output}` missing in `meta.yml`", module.meta_yml))
# confirm that the name matches the process name in main.nf
if meta_yaml["name"].upper() == module.process_name:
module.passed.append(("meta_name", "Correct name specified in `meta.yml`", module.meta_yml))
else:
module.failed.append(
(
"meta_name",
f"Conflicting process name between meta.yml (`{meta_yaml['name']}`) and main.nf (`{module.process_name}`)",
module.meta_yml,
)
)