Skip to content

Commit 9da8387

Browse files
committed
Implement --conda_requirements flag on lint.
``` Applying linter requirements_in_conda... WARNING .. WARNING: Requirement [[email protected]] doesn't exactly match available version [0.7.15] in best practice Conda channel [bioconda]. .. INFO: Requirement [[email protected]] matches target in best practice Conda channel [bioconda]. ```
1 parent 19b2ee9 commit 9da8387

File tree

5 files changed

+57
-7
lines changed

5 files changed

+57
-7
lines changed

planemo/commands/cmd_lint.py

+6
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727
default=False,
2828
help="Check validity of DOIs in XML files",
2929
)
30+
@click.option(
31+
"--conda_requirements",
32+
is_flag=True,
33+
default=False,
34+
help="Check tool requirements for availability in best practice Conda channels.",
35+
)
3036
# @click.option(
3137
# "--verify",
3238
# is_flag=True,

planemo/conda.py

+16-5
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
import os
88

99
from galaxy.tools.deps import conda_util
10-
from galaxy.tools.deps.requirements import parse_requirements_from_xml
11-
from galaxy.tools.loader_directory import load_tool_elements_from_path
10+
from galaxy.tools.loader_directory import load_tool_sources_from_path
1211

1312
from planemo.io import shell
1413

@@ -33,9 +32,21 @@ def build_conda_context(ctx, **kwds):
3332
def collect_conda_targets(path, found_tool_callback=None, conda_context=None):
3433
"""Load CondaTarget objects from supplied artifact sources."""
3534
conda_targets = []
36-
for (tool_path, tool_xml) in load_tool_elements_from_path(path):
35+
for (tool_path, tool_source) in load_tool_sources_from_path(path):
3736
if found_tool_callback:
3837
found_tool_callback(tool_path)
39-
requirements, containers = parse_requirements_from_xml(tool_xml)
40-
conda_targets.extend(conda_util.requirements_to_conda_targets(requirements))
38+
conda_targets.extend(tool_source_conda_targets(tool_source))
4139
return conda_targets
40+
41+
42+
def tool_source_conda_targets(tool_source):
43+
"""Load CondaTarget object from supplied abstract tool source."""
44+
requirements, _ = tool_source.parse_requirements_and_containers()
45+
return conda_util.requirements_to_conda_targets(requirements)
46+
47+
48+
__all__ = [
49+
"build_conda_context",
50+
"collect_conda_targets",
51+
"tool_source_conda_targets",
52+
]

planemo/lint.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
urlopen,
1515
)
1616

17+
import planemo.linters.conda_requirements
1718
import planemo.linters.doi
1819
import planemo.linters.urls
1920
import planemo.linters.xsd
@@ -55,6 +56,9 @@ def _lint_extra_modules(**kwds):
5556
if kwds.get("urls", False):
5657
linters.append(planemo.linters.urls)
5758

59+
if kwds.get("conda_requirements", False):
60+
linters.append(planemo.linters.conda_requirements)
61+
5862
return linters
5963

6064

@@ -117,7 +121,7 @@ def lint_xsd(lint_ctx, schema_path, path):
117121
msg = msg % (name, validation_result.output)
118122
lint_ctx.error(msg)
119123
else:
120-
lint_ctx.info("%s found and appears to be valid XML" % name)
124+
lint_ctx.info("File validates against XML schema.")
121125

122126

123127
def lint_urls(root, lint_ctx):

planemo/linters/conda_requirements.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""Ensure requirements are matched in best practice conda channels."""
2+
3+
from galaxy.tools.deps.conda_util import best_search_result
4+
5+
from planemo.conda import tool_source_conda_targets
6+
7+
BEST_PRACTICE_CHANNELS = ["conda-forge", "anaconda", "r", "bioconda"]
8+
9+
10+
def lint_requirements_in_conda(tool_source, lint_ctx):
11+
"""Check requirements of tool source against best practice Conda channels."""
12+
conda_targets = tool_source_conda_targets(tool_source)
13+
for conda_target in conda_targets:
14+
(best_hit, exact) = best_search_result(conda_target, channels_override=BEST_PRACTICE_CHANNELS)
15+
conda_target_str = conda_target.package
16+
if conda_target.version:
17+
conda_target_str += "@%s" % (conda_target.version)
18+
if best_hit and exact:
19+
template = "Requirement [%s] matches target in best practice Conda channel [%s]."
20+
message = template % (conda_target_str, best_hit.get("channel"))
21+
lint_ctx.info(message)
22+
elif best_hit:
23+
template = "Requirement [%s] doesn't exactly match available version [%s] in best practice Conda channel [%s]."
24+
message = template % (conda_target_str, best_hit['version'], best_hit.get("channel"))
25+
lint_ctx.warn(message)
26+
else:
27+
template = "Requirement [%s] doesn't match any recipe in a best practice conda channel [%s]."
28+
message = template % (conda_target_str, BEST_PRACTICE_CHANNELS)
29+
lint_ctx.warn(message)

requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ virtualenv
1010
lxml
1111
gxformat2>=0.1.1
1212
ephemeris>=0.2.0
13-
galaxy-lib>=16.10.2
13+
galaxy-lib>=16.10.3
1414
html5lib>=0.9999999,!=0.99999999,!=0.999999999,!=1.0b10,!=1.0b09 ; python_version == '2.7'
1515
cwltool==1.0.20160726135535 ; python_version == '2.7'

0 commit comments

Comments
 (0)