Skip to content

Commit 70fda0a

Browse files
authored
Add a check for exit codes to be equal to zero and release v0.0.3. (#3)
1 parent eeb3009 commit 70fda0a

17 files changed

+218
-113
lines changed

.conda/meta.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ requirements:
2020

2121
run:
2222
- python >=3.6
23-
- pytask >=0.0.5
23+
- pytask >=0.0.7
2424

2525
test:
2626
requires:
@@ -32,11 +32,13 @@ test:
3232
commands:
3333
- pytask --version
3434
- pytask --help
35+
- pytask markers
36+
- pytask clean
3537

3638
- pytest tests
3739

3840
about:
3941
home: https://github.com/pytask-dev/pytask-r
4042
license: none
41-
summary: Compile LaTeX documents.
43+
summary: Run R scripts with pytask.
4244
dev_url: https://github.com/pytask-dev/pytask-r/

CHANGES.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ chronological order. Releases follow `semantic versioning <https://semver.org/>`
66
all releases are available on `Anaconda.org <https://anaconda.org/pytask/pytask-r>`_.
77

88

9-
0.0.3 - 2020-xx-xx
9+
0.0.3 - 2020-10-04
1010
------------------
1111

12-
:gh:`2` fixes marker description and adds some changes to the readme.
12+
- :gh:`2` fixes marker description and adds some changes to the readme.
13+
- :gh:`3` check for exit code equal to 0, preparation for pytask v0.0.7, and releases
14+
v0.0.3.
1315

1416

1517
0.0.2 - 2020-08-14

README.rst

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
:target: https://anaconda.org/pytask/pytask-r
66

77
.. image:: https://github.com/pytask-dev/pytask-r/workflows/Continuous%20Integration%20Workflow/badge.svg?branch=main
8-
:target: https://github.com/pytask-dev/pytask/actions?query=branch%3Amain
8+
:target: https://github.com/pytask-dev/pytask-r/actions?query=branch%3Amain
99

1010
.. image:: https://codecov.io/gh/pytask-dev/pytask-r/branch/main/graph/badge.svg
1111
:target: https://codecov.io/gh/pytask-dev/pytask-r
@@ -18,7 +18,7 @@
1818
pytask-r
1919
========
2020

21-
pytask-r allows you to run R scripts with pytask.
21+
Run R scripts with pytask.
2222

2323

2424
Installation
@@ -31,17 +31,17 @@ Install the plugin with
3131
$ conda config --add channels conda-forge --add channels pytask
3232
$ conda install pytask-r
3333
34-
You also need to have R installed and ``Rscript`` on your command line. To test
35-
whether it is installed, type the following on the command line
34+
You also need to have R installed and ``Rscript`` on your command line. Test it by
35+
typing the following on the command line
3636

3737
.. code-block:: console
3838
3939
$ Rscript --help
4040
4141
If an error is shown instead of a help page, you can install R with ``conda`` by
42-
choosing either the normal R or Microsoft R Open (MRO). The command is one of the two
43-
following commands. (See `here <https://docs.anaconda.com/anaconda/user-guide/tasks/
44-
using-r-language>`_ for further explanation on Anaconda, R, and MRO.)
42+
choosing either R or Microsoft R Open (MRO). Choose one of the two following commands.
43+
(See `here <https://docs.anaconda.com/anaconda/user-guide/tasks/ using-r-language>`_
44+
for further explanation on Anaconda, R, and MRO.)
4545

4646
.. code-block:: console
4747
@@ -54,9 +54,9 @@ Or install install R from the official `R Project <https://www.r-project.org/>`_
5454
Usage
5555
-----
5656

57-
Similarly to normal task functions which execute Python code, you also define tasks to
57+
Similarly to normal task functions which execute Python code, you define tasks to
5858
execute scripts written in R with Python functions. The difference is that the function
59-
body does not contain any logic, but the decorators tell pytask how to handle the task.
59+
body does not contain any logic, but the decorator tells pytask how to handle the task.
6060

6161
Here is an example where you want to run ``script.r``.
6262

@@ -72,27 +72,27 @@ Here is an example where you want to run ``script.r``.
7272
pass
7373
7474
Note that, you need to apply the ``@pytask.mark.r`` marker so that pytask-r handles the
75-
task. The first dependency is always treated as the executable script. With multiple
76-
dependencies it may look like this
75+
task. The executable script must be the first dependency. Other dependencies can be
76+
added after that.
7777

7878
.. code-block:: python
7979
8080
@pytask.mark.r
81-
@pytask.mark.depends_on("script.r", "input.rds")
81+
@pytask.mark.depends_on(["script.r", "input.rds"])
8282
@pytask.mark.produces("out.rds")
8383
def task_run_r_script():
8484
pass
8585
8686
If you are wondering why the function body is empty, know that pytask-r replaces the
87-
body with an predefined internal function. See the section on implementation details for
87+
body with a predefined internal function. See the section on implementation details for
8888
more information.
8989

9090

9191
Command Line Arguments
9292
~~~~~~~~~~~~~~~~~~~~~~
9393

94-
The decorator can be used to pass command line arguments to ``Rscript`` which is by
95-
default the only the ``--vanilla`` flag. If you want to pass arguments to the script via
94+
The decorator can be used to pass command line arguments to ``Rscript`` which is, by
95+
default, only the ``--vanilla`` flag. If you want to pass arguments to the script via
9696
the command line, use
9797

9898
.. code-block:: python
@@ -115,7 +115,7 @@ Parametrization
115115
~~~~~~~~~~~~~~~
116116

117117
You can also parametrize the execution of scripts, meaning executing multiple R scripts
118-
as well as passing different command line arguments to an R script.
118+
as well as passing different command line arguments to the same R script.
119119

120120
The following task executes two R scripts which produce different outputs.
121121

@@ -130,29 +130,30 @@ The following task executes two R scripts which produce different outputs.
130130
131131
132132
If you want to pass different command line arguments to the same R script, you have to
133-
include the R decorator in the parametrization just like with
133+
include the ``@pytask.mark.r`` decorator in the parametrization just like with
134134
``@pytask.mark.depends_on`` and ``@pytask.mark.produces``.
135135

136136
.. code-block:: python
137137
138138
@pytask.mark.depends_on("script.r")
139-
@pytask.mark.parametrize("produces, r", [("out_1.rds", 1), ("out_2.rds", 2)])
139+
@pytask.mark.parametrize(
140+
"produces, r",
141+
[("output_1.rds", ["--vanilla", 1]), ("output_2.rds", ["--vanilla", 2])],
142+
)
140143
def task_execute_r_script():
141144
pass
142145
143146
144-
.. _implementation_details:
145-
146147
Implementation Details
147148
----------------------
148149

149-
The plugin is only a convenient wrapper around
150+
The plugin is a convenient wrapper around
150151

151152
.. code-block:: python
152153
153154
import subprocess
154155
155-
subprocess.run(["Rscript", "--vanilla", "script.r"])
156+
subprocess.run(["Rscript", "--vanilla", "script.r"], check=True)
156157
157158
to which you can always resort to when the plugin does not deliver functionality you
158159
need.

environment.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ dependencies:
1313
- conda-verify
1414

1515
# Package dependencies
16-
- pytask >= 0.0.5
16+
- pytask >= 0.0.7
1717
- r-base
1818

1919
# Misc

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.0.2
2+
current_version = 0.0.3
33
parse = (?P<major>\d+)\.(?P<minor>\d+)(\.(?P<patch>\d+))(\-?((dev)?(?P<dev>\d+))?)
44
serialize =
55
{major}.{minor}.{patch}dev{dev}

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
setup(
55
name="pytask-r",
6-
version="0.0.2",
6+
version="0.0.3",
77
packages=find_packages(where="src"),
88
package_dir={"": "src"},
99
entry_points={"pytask": ["pytask_r = pytask_r.plugin"]},

src/pytask_r/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.0.2"
1+
__version__ = "0.0.3"

src/pytask_r/collect.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""Collect tasks."""
12
import copy
23
import functools
34
import subprocess
@@ -8,6 +9,7 @@
89
from _pytask.config import hookimpl
910
from _pytask.mark import get_specific_markers_from_task
1011
from _pytask.mark import has_marker
12+
from _pytask.nodes import FilePathNode
1113
from _pytask.nodes import PythonFunctionTask
1214
from _pytask.parametrize import _copy_func
1315
from _pytask.shared import to_list
@@ -30,8 +32,9 @@ def r(options: Optional[Union[str, Iterable[str]]] = None):
3032

3133

3234
def run_r_script(depends_on, r):
35+
"""Run an R script."""
3336
script = to_list(depends_on)[0]
34-
subprocess.run(["Rscript", script.as_posix(), *r])
37+
subprocess.run(["Rscript", script.as_posix(), *r], check=True)
3538

3639

3740
@hookimpl
@@ -50,26 +53,30 @@ def pytask_collect_task(session, path, name, obj):
5053
r_function = _copy_func(run_r_script)
5154
r_function.pytaskmark = copy.deepcopy(task.function.pytaskmark)
5255

53-
args = _create_command_line_arguments(task)
56+
merged_marks = _merge_all_markers(task)
57+
args = r(*merged_marks.args, **merged_marks.kwargs)
5458
r_function = functools.partial(r_function, r=args)
5559

5660
task.function = r_function
5761

58-
if task.depends_on[0].value.suffix not in [".r", ".R"]:
62+
return task
63+
64+
65+
@hookimpl
66+
def pytask_collect_task_teardown(task):
67+
if task is not None:
68+
if isinstance(task.depends_on[0], FilePathNode) and task.depends_on[
69+
0
70+
].value.suffix not in [".r", ".R"]:
5971
raise ValueError(
60-
"The first dependency of an R task must be the script which will be "
61-
"executed."
72+
"The first dependency of an R task must be the executable script."
6273
)
6374

64-
return task
6575

66-
67-
def _create_command_line_arguments(task):
76+
def _merge_all_markers(task):
77+
"""Combine all information from markers for the compile r function."""
6878
r_marks = get_specific_markers_from_task(task, "r")
6979
mark = r_marks[0]
7080
for mark_ in r_marks[1:]:
71-
mark = mark.combine_with(mark_)
72-
73-
options = r(*mark.args, **mark.kwargs)
74-
75-
return options
81+
mark = mark.combined_with(mark_)
82+
return mark

src/pytask_r/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
"""Configure pytask."""
12
from _pytask.config import hookimpl
23

34

45
@hookimpl
56
def pytask_parse_config(config):
7+
"""Register the r marker."""
68
config["markers"]["r"] = "Tasks which are executed with Rscript."

src/pytask_r/execute.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
1+
"""Execute tasks."""
12
import shutil
23

34
from _pytask.config import hookimpl
45
from _pytask.mark import get_specific_markers_from_task
5-
from _pytask.nodes import FilePathNode
66

77

88
@hookimpl
99
def pytask_execute_task_setup(task):
10+
"""Perform some checks when a task marked with the r marker is executed."""
1011
if get_specific_markers_from_task(task, "r"):
1112
if shutil.which("Rscript") is None:
1213
raise RuntimeError(
1314
"Rscript is needed to run R scripts, but it is not found on your PATH."
1415
)
15-
16-
if not (
17-
isinstance(task.depends_on[0], FilePathNode)
18-
and task.depends_on[0].value.suffix in [".r", ".R"]
19-
):
20-
raise ValueError("'depends_on' must be a path to a single .r script.")

0 commit comments

Comments
 (0)