Skip to content

Commit 8a5672a

Browse files
committed
fix: add a test for test: under multiple outputs: and adjust parsing accordingly
1 parent c14bda6 commit 8a5672a

3 files changed

Lines changed: 101 additions & 21 deletions

File tree

bioconda_utils/lint/check_completeness.py

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"""
55

66
import os
7-
from . import LintCheck, ERROR, WARNING, INFO
7+
from . import LintCheck, ERROR, WARNING, INFO, _recipe
88

99

1010
class missing_build_number(LintCheck):
@@ -85,29 +85,40 @@ class missing_tests(LintCheck):
8585
your meta.yaml file; or if you use an ``outputs:`` section
8686
to specify multiple outputs, add a test to each of your
8787
``outputs:`` entries.
88-
8988
"""
9089
test_files = ['run_test.py', 'run_test.sh', 'run_test.pl']
9190

9291
def check_recipe(self, recipe):
9392
if any(os.path.exists(os.path.join(recipe.dir, f))
94-
for f in self.test_files):
93+
for f in self.test_files):
9594
return
96-
# if multiple `outputs:` are specified, we have to go
97-
# through one level of the resulting list at a time and
98-
# check that all of them have a test specified
95+
# if multiple `outputs:` are specified, we check that
96+
# all subpackages have `test:` specified, but ignore
97+
# top-level tests, as top-level package outputs will
98+
# become incompatible with multiple `outputs:` in the
99+
# future, see:
100+
# https://conda.org/learn/ceps/cep-0014/#outputs-section
99101
if recipe.get('outputs', ''):
100-
if all(t.get('commands', '') or t.get('imports', '')
101-
for t in [
102-
p.get('test', '') for p in recipe.get('outputs')
103-
]):
104-
return
105-
if recipe.get('test/commands', '') or recipe.get('test/imports', ''):
106-
return
107-
if recipe.get('test', ''):
108-
self.message(section='test')
102+
packages = recipe.get('outputs')
109103
else:
110-
self.message()
104+
packages = [ recipe, ]
105+
# can't use the Recipe.get function, as we might have plain dicts
106+
# here; so we need to go one level of the resulting dicts at
107+
# a time and check that all of them have a test specified
108+
tests_specified = [
109+
t.get('commands', '') or t.get('imports', '')
110+
for t in [ p.get('test', {}) for p in packages ]
111+
]
112+
if all(tests_specified):
113+
return
114+
for i in range(len(packages)):
115+
if not tests_specified[i]:
116+
if not isinstance(packages[i], _recipe.Recipe) and packages[i].get(f'outputs/{i}/test', ''):
117+
self.message(section=f'outputs/{i}/test')
118+
elif packages[i].get('test', ''):
119+
self.message(section='test')
120+
else:
121+
self.message()
111122

112123

113124
class missing_hash(LintCheck):

test/conftest.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,23 @@ def recipe_dir(recipes_folder: py.path.local, tmpdir: py.path.local,
139139
for remove in utils.ensure_list(case['remove']):
140140
path = remove.split('/')
141141
cont = recipe
142+
select_by_name = False
142143
for p in path[:-1]:
143-
cont = cont[p]
144+
if select_by_name:
145+
for subpackage in cont:
146+
if subpackage['name'] == p:
147+
cont = subpackage
148+
select_by_name = False
149+
else:
150+
cont = cont.get(p, {})
151+
if p == "outputs":
152+
select_by_name = True
144153
if isinstance(cont, list):
145154
for n in range(len(cont)):
146155
del cont[n][path[-1]]
147156
else:
148-
del cont[path[-1]]
157+
if cont.get(path[-1], ""):
158+
del cont[path[-1]]
149159
if 'add' in case:
150160
dict_merge(recipe, case['add'])
151161

test/lint_cases.yaml

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,56 @@ setup:
5252
license: BSD
5353
home: https://elsewhere
5454
summary: the_summary
55+
meta:
56+
folder: meta_package
57+
meta.yaml:
58+
package:
59+
name: meta_package
60+
version: 0.1
61+
source:
62+
- url: https://somewhere
63+
sha256: 123
64+
- url: https://elsewhere
65+
sha256: abc
66+
build:
67+
noarch: True
68+
number: 0
69+
run_exports:
70+
# add a run export
71+
# (note that jinja templating as in reality is not
72+
# supported by our test system to the same
73+
# extend as in conda build)
74+
- "{{ pin_subpackage('meta_package') }}"
75+
outputs:
76+
- name: meta_one
77+
build:
78+
noarch: True
79+
run_exports:
80+
# add a run export
81+
# (note that jinja templating as in reality is not
82+
# supported by our test system to the same
83+
# extend as in conda build)
84+
- "{{ pin_subpackage('meta_one') }}"
85+
test:
86+
commands:
87+
- do nothing
88+
- name: meta_two
89+
build:
90+
noarch: True
91+
number: 0
92+
run_exports:
93+
# add a run export
94+
# (note that jinja templating as in reality is not
95+
# supported by our test system to the same
96+
# extend as in conda build)
97+
- "{{ pin_subpackage('meta_two') }}"
98+
test:
99+
imports:
100+
- no imports to see here
101+
about:
102+
license: MIT
103+
home: https://elsewhere
104+
summary: another_summary
55105
repodata:
56106
bioconda:
57107
one:
@@ -60,6 +110,8 @@ setup:
60110
- version: 0.0.1
61111
four:
62112
- version: 0.0.1
113+
meta_package:
114+
- version: 0.0.1
63115
conda-forge:
64116
three:
65117
- version: 1.0
@@ -123,11 +175,14 @@ tests:
123175
add: { about: { license: "" } }
124176
expect: missing_license
125177
- name: missing_tests
126-
remove: test
178+
remove:
179+
- test
180+
- outputs/meta_one/test
127181
expect: missing_tests
128182
- name: missing_tests_empty_section
129183
remove:
130184
- test/commands
185+
- outputs/meta_two/test/imports
131186
expect: missing_tests
132187
- name: missing_tests_but_runtest_py
133188
remove: test
@@ -142,7 +197,10 @@ tests:
142197
add_files:
143198
run_test.pl: ""
144199
- name: missing_tests_but_runtst_sh
145-
remove: test
200+
remove:
201+
- test
202+
- outputs/meta_one/test
203+
- outputs/meta_two/test
146204
add_files:
147205
run_tst.sh: ""
148206
expect: missing_tests
@@ -369,7 +427,7 @@ tests:
369427
add: { package: { version: "v0.1" } }
370428
- name: in_other_channels
371429
expect: in_other_channels
372-
repodata: { conda-forge: { one: [{ version: 0.1 }], two: [version: 0.1] } }
430+
repodata: { conda-forge: { one: [{ version: 0.1 }], two: [version: 0.1], meta_package: [version: 0.1] } }
373431
- name: long_summary
374432
expect: long_summary
375433
add:
@@ -383,6 +441,7 @@ tests:
383441
blacklist: |
384442
recipes/one
385443
recipes/two
444+
recipes/meta_package
386445
config:
387446
blacklists:
388447
- blacklist

0 commit comments

Comments
 (0)