Skip to content

Commit 48323d8

Browse files
authored
Add pytask_add_hooks to register plugins and hooks. (#5)
1 parent 407ac65 commit 48323d8

File tree

18 files changed

+179
-125
lines changed

18 files changed

+179
-125
lines changed

.conda/meta.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ build:
1818
requirements:
1919
host:
2020
- python
21+
- pip
2122
- setuptools
2223

2324
run:
2425
- python >=3.6
26+
- setuptools
2527
- attrs >=17.4.0
2628
- click
2729
- networkx
@@ -30,6 +32,8 @@ requirements:
3032
- pytest
3133

3234
test:
35+
imports:
36+
- pytask
3337
requires:
3438
- pexpect
3539
- pytest
@@ -45,6 +49,6 @@ test:
4549
about:
4650
home: https://github.com/pytask-dev/pytask
4751
license: none
48-
summary: In its highest aspirations, **pytask** tries to be pytest as a build system.
52+
summary: In its highest aspirations, pytask tries to be pytest as a build system.
4953
doc_url: https://pytask-dev.readthedocs.io/en/latest
5054
dev_url: https://github.com/pytask-dev/pytask/

.github/ISSUE_TEMPLATE/documentation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ labels: "documentation"
1212
Provide the location of the documentation, e.g. an URL of the documentation.
1313

1414
**Note**: You can check the latest versions of the docs on `main`
15-
[here](https://pytask.readthedocs.io/en/latest).
15+
[here](https://pytask-dev.readthedocs.io/en/latest).
1616

1717
#### Documentation problem
1818

.github/workflows/continuous-integration-workflow.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535

3636
- name: Run unit tests and doctests.
3737
shell: bash -l {0}
38-
run: tox -e pytest -- -m "unit or (not integration and not end_to_end)" --cov=./ --cov-report=xml
38+
run: tox -e pytest -- -m "unit or (not integration and not end_to_end)" --cov=./ --cov-report=xml -n auto
3939

4040
- name: Upload coverage report for unit tests and doctests.
4141
if: runner.os == 'Linux' && matrix.python-version == '3.8'
@@ -44,7 +44,7 @@ jobs:
4444

4545
- name: Run integration tests.
4646
shell: bash -l {0}
47-
run: tox -e pytest -- -m integration --cov=./ --cov-report=xml
47+
run: tox -e pytest -- -m integration --cov=./ --cov-report=xml -n auto
4848

4949
- name: Upload coverage reports of integration tests.
5050
if: runner.os == 'Linux' && matrix.python-version == '3.8'
@@ -53,7 +53,7 @@ jobs:
5353

5454
- name: Run end-to-end tests.
5555
shell: bash -l {0}
56-
run: tox -e pytest -- -m end_to_end --cov=./ --cov-report=xml
56+
run: tox -e pytest -- -m end_to_end --cov=./ --cov-report=xml -n auto
5757

5858
- name: Upload coverage reports of end-to-end tests.
5959
if: runner.os == 'Linux' && matrix.python-version == '3.8'

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ include:
4646
Installation
4747
------------
4848

49-
**pytask** is available on `Anaconda.org <https://anaconda.org/pytask/pytask>`_. Install
50-
the package with
49+
pytask is available on `Anaconda.org <https://anaconda.org/pytask/pytask>`_. Install the
50+
package with
5151

5252
.. code-block:: bash
5353

docs/changes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ all releases are available on `Anaconda.org <https://anaconda.org/pytask/pytask>
1212
- :gh:`2` provided multiple small changes.
1313
- :gh:`3` implements a class which holds the execution report of one task.
1414
- :gh:`4` makes adjustments after moving to ``main`` as the default branch.
15+
- :gh:`5` adds ``pytask_add_hooks`` to add more hook specifications and register hooks.
1516

1617

1718
0.0.1 - 2020-06-29

docs/index.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ pytask
1010
.. image:: https://readthedocs.org/projects/pytask-dev/badge/?version=latest
1111
:target: https://pytask-dev.readthedocs.io/en/latest
1212

13+
.. image:: https://github.com/pytask-dev/pytask/workflows/Continuous%20Integration%20Workflow/badge.svg?branch=main
14+
:target: https://github.com/pytask-dev/pytask/actions?query=branch%3Amain
15+
16+
1317
.. image:: https://codecov.io/gh/pytask-dev/pytask/branch/main/graph/badge.svg
1418
:target: https://codecov.io/gh/pytask-dev/pytask
1519

environment.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ dependencies:
1818
- pytest
1919

2020
# Misc
21+
- bump2version
2122
- jupyterlab
2223
- matplotlib
2324
- pdbpp

setup.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
current_version = 0.0.1
33
parse = (?P<major>\d+)\.(?P<minor>\d+)(\.(?P<patch>\d+))(\-?((dev)?(?P<dev>\d+))?)
44
serialize =
5-
{major}.{minor}.{patch}dev{dev}
6-
{major}.{minor}.{patch}
5+
{major}.{minor}.{patch}dev{dev}
6+
{major}.{minor}.{patch}
77

88
[bumpversion:file:setup.py]
99

src/pytask/cli.py

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
from pathlib import Path
33

44
import click
5-
from pytask import debugging
6-
from pytask import hookimpl
5+
import pytask
76
from pytask.main import main
87
from pytask.pluginmanager import get_plugin_manager
98

@@ -15,17 +14,26 @@ def add_parameters(func):
1514
"""Add parameters from plugins to the commandline interface."""
1615
pm = get_plugin_manager()
1716
pm.register(sys.modules[__name__])
18-
pm.register(debugging)
17+
pm.hook.pytask_add_hooks(pm=pm)
1918
pm.hook.pytask_add_parameters_to_cli(command=func)
2019

2120
return func
2221

2322

23+
@pytask.hookimpl
24+
def pytask_add_hooks(pm):
25+
from pytask import database
26+
from pytask import debugging
27+
28+
pm.register(database)
29+
pm.register(debugging)
30+
31+
2432
def _to_path(ctx, param, value): # noqa: U100
2533
return [Path(i).resolve() for i in value]
2634

2735

28-
@hookimpl
36+
@pytask.hookimpl
2937
def pytask_add_parameters_to_cli(command):
3038
additional_parameters = [
3139
click.Argument(
@@ -38,24 +46,6 @@ def pytask_add_parameters_to_cli(command):
3846
help="Ignore path (globs and multi allowed).",
3947
),
4048
click.Option(["--debug-pytask"], is_flag=True, help="Debug pytask."),
41-
click.Option(
42-
["--database-provider"],
43-
type=click.Choice(["sqlite", "postgres", "mysql", "oracle", "cockroach"]),
44-
help="Database provider.",
45-
),
46-
click.Option(
47-
["--database-filename"], type=click.Path(), help="Path to database.",
48-
),
49-
click.Option(
50-
["--database-create-db"],
51-
type=bool,
52-
help="Create database if it does not exist.",
53-
),
54-
click.Option(
55-
["--database-create-tables"],
56-
type=bool,
57-
help="Create tables if they do not exist.",
58-
),
5949
]
6050
command.params.extend(additional_parameters)
6151

src/pytask/config.py

Lines changed: 5 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99
import click
1010
import pytask
11+
from pytask.shared import get_first_not_none_value
1112
from pytask.shared import to_list
1213

13-
1414
IGNORED_FILES_AND_FOLDERS = [
1515
"*/.git/*",
1616
"*/__pycache__/*",
@@ -23,7 +23,7 @@
2323
def pytask_configure(pm, config_from_cli):
2424
config = {"pm": pm, "terminal_width": _get_terminal_width()}
2525

26-
paths = _get_first_not_none_value(config_from_cli, key="paths", callback=to_list)
26+
paths = get_first_not_none_value(config_from_cli, key="paths", callback=to_list)
2727
paths = [Path(p).resolve() for path in paths for p in glob.glob(path.as_posix())]
2828
config["paths"] = paths if paths else [Path.cwd().resolve()]
2929

@@ -44,7 +44,7 @@ def pytask_configure(pm, config_from_cli):
4444
@pytask.hookimpl
4545
def pytask_parse_config(config, config_from_cli, config_from_file):
4646
config["ignore"] = (
47-
_get_first_not_none_value(
47+
get_first_not_none_value(
4848
config_from_cli,
4949
config_from_file,
5050
key="ignore",
@@ -54,35 +54,13 @@ def pytask_parse_config(config, config_from_cli, config_from_file):
5454
+ IGNORED_FILES_AND_FOLDERS
5555
)
5656

57-
config["debug_pytask"] = _get_first_not_none_value(
57+
config["debug_pytask"] = get_first_not_none_value(
5858
config_from_cli, config_from_file, key="debug_pytask", default=False
5959
)
6060
if config["debug_pytask"]:
6161
config["pm"].trace.root.setwriter(click.echo)
6262
config["pm"].enable_tracing()
6363

64-
provider = _get_first_not_none_value(
65-
config_from_cli, config_from_file, key="database_provider", default="sqlite"
66-
)
67-
filename = _get_first_not_none_value(
68-
config_from_cli,
69-
config_from_file,
70-
key="database_filename",
71-
default=".pytask.sqlite3",
72-
)
73-
create_db = _get_first_not_none_value(
74-
config_from_cli, config_from_file, key="database_create_db", default=True
75-
)
76-
create_tables = _get_first_not_none_value(
77-
config_from_cli, config_from_file, key="database_create_tables", default=True
78-
)
79-
config["database"] = {
80-
"provider": provider,
81-
"filename": Path(config["root"], filename).resolve().as_posix(),
82-
"create_db": create_db,
83-
"create_tables": create_tables,
84-
}
85-
8664

8765
def _find_project_root_and_ini(paths):
8866
try:
@@ -126,42 +104,11 @@ def _read_config(path):
126104
return dict(config["pytask"])
127105

128106

129-
def _get_first_not_none_value(*configs, key, default=None, callback=None):
130-
"""Get the first non-None value for a key from a list of dictionaries.
131-
132-
This function allows to prioritize information from many configurations by changing
133-
the order of the inputs while also providing a default.
134-
135-
Examples
136-
--------
137-
>>> _get_first_not_none_value({"a": None}, {"a": 1}, key="a")
138-
1
139-
140-
>>> _get_first_not_none_value({"a": None}, {"a": None}, key="a", default="default")
141-
'default'
142-
143-
>>> _get_first_not_none_value({}, {}, key="a", default="default")
144-
'default'
145-
146-
>>> _get_first_not_none_value({"a": None}, {"a": "b"}, key="a", callback=to_list)
147-
['b']
148-
149-
"""
150-
return next(
151-
(
152-
config[key] if callback is None else callback(config[key])
153-
for config in configs
154-
if config.get(key, None) is not None
155-
),
156-
default,
157-
)
158-
159-
160107
def _get_terminal_width() -> int:
161108
"""Get the window width of the terminal."""
162109
width, _ = shutil.get_terminal_size(fallback=(80, 24))
163110

164-
# The Windows get_terminal_size may be bogus, let's sanify a bit.
111+
# The Windows get_terminal_size may be bogus, let's sanitize a bit.
165112
if width < 40:
166113
width = 80
167114

src/pytask/database.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
from pathlib import Path
2+
3+
import click
4+
import pytask
15
from pony import orm
6+
from pytask.shared import get_first_not_none_value
27

38

49
db = orm.Database()
@@ -28,3 +33,57 @@ def create_or_update_state(first_key, second_key, state):
2833
State(task=first_key, node=second_key, state=state)
2934
else:
3035
state_in_db.state = state
36+
37+
38+
@pytask.hookimpl
39+
def pytask_add_parameters_to_cli(command):
40+
additional_parameters = [
41+
click.Option(
42+
["--database-provider"],
43+
type=click.Choice(["sqlite", "postgres", "mysql", "oracle", "cockroach"]),
44+
help="Database provider. [default: sqlite]",
45+
),
46+
click.Option(
47+
["--database-filename"], type=click.Path(), help="Path to database.",
48+
),
49+
click.Option(
50+
["--database-create-db"],
51+
type=bool,
52+
help="Create database if it does not exist.",
53+
),
54+
click.Option(
55+
["--database-create-tables"],
56+
type=bool,
57+
help="Create tables if they do not exist.",
58+
),
59+
]
60+
command.params.extend(additional_parameters)
61+
62+
63+
@pytask.hookimpl
64+
def pytask_parse_config(config, config_from_cli, config_from_file):
65+
provider = get_first_not_none_value(
66+
config_from_cli, config_from_file, key="database_provider", default="sqlite"
67+
)
68+
filename = get_first_not_none_value(
69+
config_from_cli,
70+
config_from_file,
71+
key="database_filename",
72+
default=".pytask.sqlite3",
73+
)
74+
filename = Path(filename)
75+
if not filename.is_absolute():
76+
filename = Path(config["root"], filename).resolve().as_posix()
77+
78+
create_db = get_first_not_none_value(
79+
config_from_cli, config_from_file, key="database_create_db", default=True
80+
)
81+
create_tables = get_first_not_none_value(
82+
config_from_cli, config_from_file, key="database_create_tables", default=True
83+
)
84+
config["database"] = {
85+
"provider": provider,
86+
"filename": filename,
87+
"create_db": create_db,
88+
"create_tables": create_tables,
89+
}

src/pytask/debugging.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,33 @@
44

55
import click
66
import pytask
7-
from pytask.config import _get_first_not_none_value
87
from pytask.nodes import PythonFunctionTask
8+
from pytask.shared import get_first_not_none_value
99

1010

1111
@pytask.hookimpl
1212
def pytask_add_parameters_to_cli(command):
1313
additional_parameters = [
14-
click.Option(["--pdb"], help="Enter debugger on errors.", is_flag=True),
15-
click.Option(["--trace"], help="Enter debugger at test start.", is_flag=True),
14+
click.Option(
15+
["--pdb"], help="Enter debugger on errors.", is_flag=True, default=None
16+
),
17+
click.Option(
18+
["--trace"],
19+
help="Enter debugger when starting each task.",
20+
is_flag=True,
21+
default=None,
22+
),
1623
]
1724
command.params.extend(additional_parameters)
1825

1926

2027
@pytask.hookimpl
21-
def pytask_parse_config(config, config_from_cli):
22-
config["pdb"] = _get_first_not_none_value(config_from_cli, key="pdb", default=False)
23-
config["trace"] = _get_first_not_none_value(
24-
config_from_cli, key="trace", default=False
28+
def pytask_parse_config(config, config_from_cli, config_from_file):
29+
config["pdb"] = get_first_not_none_value(
30+
config_from_cli, config_from_file, key="pdb", default=False
31+
)
32+
config["trace"] = get_first_not_none_value(
33+
config_from_cli, config_from_file, key="trace", default=False
2534
)
2635

2736

0 commit comments

Comments
 (0)