Skip to content

Commit ebd5cab

Browse files
authored
v0.10.1 (#69)
* Close #62 * Update CHANGELOG * Update pre-commit config in project template * Close #68 * Update CHANGELOG * Close #64 * Close #65
1 parent 6de46a8 commit ebd5cab

File tree

9 files changed

+127
-10
lines changed

9 files changed

+127
-10
lines changed

CHANGELOG.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,20 @@ and this project adheres to [Semantic Versioning][].
88
[keep a changelog]: https://keepachangelog.com/en/1.0.0/
99
[semantic versioning]: https://semver.org/spec/v2.0.0.html
1010

11-
## [Unreleased]
11+
## v0.10.1
12+
13+
### Fixes
14+
15+
- Take comments into account when linting for `DSO001` ([#69](https://github.com/Boehringer-Ingelheim/dso/pull/69))
16+
- Make it possible to override watermarks/disclaimers with a simple `null` ([#69](https://github.com/Boehringer-Ingelheim/dso/pull/69)).
17+
- Compile *all* configs on `dso repro`, not just the ones relvant to the specified stage. This is required because we don't
18+
know which other stages dvc might compile ([#69](https://github.com/Boehringer-Ingelheim/dso/pull/69)).
19+
- Make `get-config` compatible with dvc matrix stages ([#69](https://github.com/Boehringer-Ingelheim/dso/pull/69)).
1220

1321
### Template updates
1422

15-
- Do not ignore gitignore files in output/report directories of template ([#63](https://github.com/Boehringer-Ingelheim/dso/pull/63))
23+
- Do not ignore the `.gitignore` files in output/report directories of template ([#63](https://github.com/Boehringer-Ingelheim/dso/pull/63))
24+
- Update `.pre-commit-config.yaml` for pre-commit 4.x ([#63](https://github.com/Boehringer-Ingelheim/dso/pull/63))
1625

1726
## v0.10.0
1827

src/dso/get_config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ def get_config(stage: str, *, all: bool = False, skip_compile: bool = False) ->
9999

100100
# We want to include parameters mentioned in either `params`, `deps`, `outs`.
101101
# The parameters in `deps`/`outs` are encapsulated in `${ <param> }`
102+
is_matrix_stage = "matrix" in dvc_stage_config
102103
keep_params = set(dvc_stage_config.get("params", []))
103104
dvc_param_pat = re.compile(r"\$\{\s*(.*?)\s*\}")
104105
for dep in dvc_stage_config.get("deps", []):
@@ -112,6 +113,9 @@ def get_config(stage: str, *, all: bool = False, skip_compile: bool = False) ->
112113
f"Only including the following parameters which are listed in `dvc.yaml`: [green]{', '.join(keep_params)}"
113114
)
114115

116+
if is_matrix_stage:
117+
keep_params = {p for p in keep_params if not (p.startswith("item.") or p == "item")}
118+
115119
return _filter_nested_dict(config, keep_params)
116120

117121

src/dso/lint.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,15 @@ def check(cls, file):
8787
# .parent to remove the dvc.yaml filename
8888
stage_path_expected = str(stage_path_expected.parent.relative_to(root_path))
8989
content = file.read_text()
90+
91+
# remove comments
92+
# TODO there are still edge cases, e.g. a `#` within a string doesn't initiate a comment
93+
# However this is hard/impossible (?) to solve with a regular expression alone, we'd need a proper
94+
# R parse to address all edge cases. See also https://github.com/Boehringer-Ingelheim/dso/issues/66
95+
pattern_is_comment = re.compile(r"#.*$")
96+
content = "\n".join([re.sub(pattern_is_comment, "", line) for line in content.split("\n")])
97+
98+
# detect pattern
9099
pattern = r"[\s\S]*?(dso::)?read_params\s*\(([\s\S]*?)(\s*,.*)?\)"
91100
res = re.findall(pattern, content, flags=re.MULTILINE)
92101
if len(res) == 0:

src/dso/pandocfilter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def _sanitize_watermark_config(config):
7575
def action(elem, doc):
7676
"""Panflutes action"""
7777
watermark_config = _sanitize_watermark_config(doc.get_metadata("watermark"))
78-
if watermark_config is not None:
78+
if watermark_config: # could be "" or None, both which evaluate to False
7979
if "text" not in watermark_config:
8080
log.error("Need to specify at least `watermark.text`")
8181
sys.exit(1)

src/dso/repro.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import rich_click as click
77

88
from dso._logging import log
9-
from dso._util import check_ask_pre_commit
9+
from dso._util import check_ask_pre_commit, get_project_root
1010
from dso.compile_config import compile_all_configs
1111

1212

@@ -18,7 +18,7 @@
1818
def cli(args):
1919
"""Wrapper around dvc repro, compiling configuration before running."""
2020
check_ask_pre_commit(Path.cwd())
21-
compile_all_configs([Path.cwd()])
21+
compile_all_configs([get_project_root(Path.cwd())])
2222
os.environ["DSO_SKIP_COMPILE"] = "1"
2323
cmd = ["dvc", "repro", *args]
2424
log.info(f"Running `{' '.join(cmd)}`")

src/dso/templates/init/default/.pre-commit-config.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ repos:
4343
- id: dvc-pre-commit
4444
language_version: python3
4545
stages:
46-
- commit
46+
- pre-commit
4747
- id: dvc-pre-push
4848
additional_dependencies: ["s3"]
4949
language_version: python3
5050
stages:
51-
- push
51+
- pre-push
5252
verbose: true
5353
- id: dvc-post-checkout
5454
always_run: true
@@ -62,9 +62,9 @@ repos:
6262
name: Run dso compile-config
6363
entry: dso compile-config
6464
language: system
65-
stages: [commit]
65+
stages: [pre-commit]
6666
- id: lint
6767
name: Run dso lint
6868
entry: dso lint --skip-compile
6969
language: system
70-
stages: [commit]
70+
stages: [pre-commit]

tests/test_get_config.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,44 @@ def test_get_config_order(dso_project):
142142
assert list(config["B1"]) == ["C", "A", "D", "B", "Z", "X"]
143143

144144

145+
def test_get_config_matrix(dso_project):
146+
"""Test that get-config is compatible with dvc's matrix feature"""
147+
chdir(dso_project)
148+
stage = dso_project / "mystage"
149+
stage.mkdir()
150+
(stage / "params.in.yaml").touch()
151+
152+
(dso_project / "params.in.yaml").write_text(
153+
dedent(
154+
"""\
155+
matrix_param: ['p1', 'p2']
156+
A: "aaa"
157+
B: "bbb"
158+
"""
159+
)
160+
)
161+
162+
(stage / "dvc.yaml").write_text(
163+
dedent(
164+
"""\
165+
stages:
166+
mystage01:
167+
matrix:
168+
mp: ${ matrix_param }
169+
params:
170+
- A
171+
- item.mp
172+
outs:
173+
- output/${ item.mp }
174+
cmd: "echo Hello World!"
175+
"""
176+
)
177+
)
178+
179+
config = get_config("mystage")
180+
assert list(config) == ["A"]
181+
182+
145183
def test_get_config_path_relative_to_root_dir(quarto_stage):
146184
chdir(quarto_stage)
147185
config1 = get_config("quarto_stage")

tests/test_lint.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,21 @@ class MockQuartoRule(QuartoRule):
116116
""",
117117
LintError,
118118
),
119+
(
120+
"""\
121+
params = read_params("quarto_stage")
122+
# params = read_params("quarto_stage")
123+
""",
124+
None,
125+
),
126+
# TODO no good way to cover that with regex alone, see https://github.com/Boehringer-Ingelheim/dso/issues/66
127+
# (
128+
# """\
129+
# params = read_params("quarto_stage")
130+
# print(" foo # no comment"); params = read_params("quarto_stage")
131+
# """,
132+
# LintError,
133+
# ),
119134
(
120135
"""\
121136
params = read_params("wrong_path")

tests/test_pandocfilter.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
from os import chdir
12
from shutil import copyfile
23
from textwrap import dedent
34

4-
from dso.exec import _render_quarto
5+
from click.testing import CliRunner
6+
7+
from dso.exec import _render_quarto, cli
58
from tests.conftest import TESTDATA
69

710

@@ -63,3 +66,42 @@ def test_pandocfilter(quarto_stage):
6366
assert "Disclaimer" in out_html
6467
assert "This is a disclaimer" in out_html
6568
assert "callout-important" in out_html
69+
70+
71+
def test_override_config(quarto_stage):
72+
"""Test that it's possible to remove a watermark/disclaimer by overriding the config with null"""
73+
# I didn't find a straightforward way of testing programmatically that there's really no watermark.
74+
# this test still guarantees that it doesn't fail with an error when overring the watermark config (which it did previously)
75+
(quarto_stage / ".." / "params.in.yaml").write_text(
76+
dedent(
77+
"""\
78+
dso:
79+
quarto:
80+
watermark:
81+
text: test
82+
disclaimer:
83+
title: test disclaimer
84+
text: lorem ipsum
85+
"""
86+
)
87+
)
88+
(quarto_stage / "params.in.yaml").write_text(
89+
dedent(
90+
"""\
91+
dso:
92+
quarto:
93+
watermark: null
94+
disclaimer: null
95+
"""
96+
)
97+
)
98+
99+
runner = CliRunner()
100+
chdir(quarto_stage)
101+
stage_path = "."
102+
103+
result = runner.invoke(cli, ["quarto", stage_path])
104+
assert result.exit_code == 0
105+
106+
out_html = (quarto_stage / "report" / "quarto_stage.html").read_text()
107+
assert "test disclaimer" not in out_html

0 commit comments

Comments
 (0)