Skip to content

Commit 89500fb

Browse files
Refactor taskipy into Task, PyProject, and TaskRunner (#15)
* Run `poetry update` * Sort test imports & convert unused f strings to strings There were some f strings that weren't interpolating anything. * Create custom exceptions * Refactor taskipi package into task, pyproject, and task_runner * Add docstrings & types to task & task_runner. Also, a small refactoring of __bail_on_first_fail() in task_runner.py. * Remove docstrings * Add MissingTaskipySettingsSectionError * Make path & items in PyProject private * Check runner is string rather than catching AttributeError * Add default exception case to cli * Add exit_code class variable to exceptions * Change PyProject to take in the file_path This also converts the instance variables to be private and has __load_toml_file convert the file_path to a Path if it is a str. We also no longer store the file_path since __load_toml_file is the only place it is needed so it is just passed in. * Task now builds the commands & takes in args + project I think args could possibly be moved over to commands since that is the only place it is used and that would reduce the amount of things we are passing in to Task. commands would just have to be converted to a method instead of a property then. * TaskRunner only runs the commands now with the project passed in Instead of putting the commands together, that is now delegated to Task. The run_commands_and_bail_on_first_fail method is now gone as that is what `run` does now. Furthermore, the instance variables of TaskRunner are private now. A single instance of the TaskRunner can now run many tasks now, since it is not tied to any particular task. * Update cli to use updated TaskRunner The pyproject.toml path is now passed in with the command name and args being passed to `run`. * Use single quotes * Extract pre_task & post_task to use __find_hooks They are basically the same method, with a one word difference.
1 parent 79f669a commit 89500fb

File tree

10 files changed

+293
-150
lines changed

10 files changed

+293
-150
lines changed

.hooks/make_release_commit.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
#!/usr/bin/env python3
22
import toml
33
import subprocess
4-
import os
5-
from os import path
4+
from pathlib import Path
65

76
def create_release_commit():
8-
pyproject = toml.load(path.join(os.curdir, 'pyproject.toml'))
7+
cwd = Path.cwd()
8+
pyproject = toml.load(cwd / 'pyproject.toml')
99
version = pyproject['tool']['poetry']['version']
1010

1111
p = subprocess.Popen(f'git add . && git commit -m "Release version {version}" && git tag -a "{version}" -m "Release version {version}" && git push && git push --tags',
1212
shell=True,
13-
cwd=os.curdir)
13+
cwd=cwd)
1414

1515
p.wait()
1616

.pylintrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ disable=
55
W0702,
66
C0411,
77
R0903,
8-
R0915
8+
R0915,
9+
W0703
910

1011
[FORMAT]
1112
max-line-length=1000

poetry.lock

Lines changed: 59 additions & 58 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

taskipy/cli.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,33 @@
11
#!/usr/bin/env python3
22
import argparse
3-
from taskipy.run import run_task
3+
import sys
4+
from pathlib import Path
5+
6+
from taskipy.exceptions import TaskipyError
7+
from taskipy.task_runner import TaskRunner
8+
49

510
def main():
6-
parser = argparse.ArgumentParser(prog='task', description='runs a task specified in your pyproject.toml under [tool.taskipy.tasks]')
11+
parser = argparse.ArgumentParser(
12+
prog='task',
13+
description='runs a task specified in your pyproject.toml under [tool.taskipy.tasks]',
14+
)
715
parser.add_argument('name', help='name of the task')
8-
parser.add_argument('args', nargs=argparse.REMAINDER, help='arguments to pass to the task')
16+
parser.add_argument(
17+
'args', nargs=argparse.REMAINDER, help='arguments to pass to the task'
18+
)
919
args = parser.parse_args()
1020

11-
run_task(args.name, args.args)
21+
try:
22+
exit_code = TaskRunner(Path.cwd() / 'pyproject.toml').run(args.name, args.args)
23+
sys.exit(exit_code)
24+
except TaskipyError as e:
25+
print(e)
26+
sys.exit(e.exit_code)
27+
except Exception as e:
28+
print(e)
29+
sys.exit(1)
30+
1231

1332
if __name__ == '__main__':
1433
main()

taskipy/exceptions.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
class TaskipyError(Exception):
2+
exit_code = 1
3+
4+
5+
class InvalidRunnerTypeError(TaskipyError):
6+
def __str__(self):
7+
return (
8+
'invalid value: runner is not a string. '
9+
'please check [tool.taskipy.settings.runner]'
10+
)
11+
12+
13+
class MissingPyProjectFileError(TaskipyError):
14+
def __str__(self):
15+
return 'no pyproject.toml file found in this directory'
16+
17+
18+
class MalformedPyProjectError(TaskipyError):
19+
def __str__(self):
20+
return 'pyproject.toml file is malformed and could not be read'
21+
22+
23+
class TaskNotFoundError(TaskipyError):
24+
exit_code = 127
25+
26+
def __init__(self, task_name: str):
27+
super().__init__()
28+
self.task = task_name
29+
30+
def __str__(self):
31+
return f'could not find task "{self.task}"'
32+
33+
34+
class MissingTaskipySettingsSectionError(TaskipyError):
35+
exit_code = 127
36+
37+
def __str__(self):
38+
return (
39+
'no settings found. add a [tools.taskipy.settings]'
40+
'section to your pyproject.toml'
41+
)
42+
43+
44+
class MissingTaskipyTasksSectionError(TaskipyError):
45+
exit_code = 127
46+
47+
def __str__(self):
48+
return (
49+
'no tasks found. add a [tool.taskipy.tasks] '
50+
'section to your pyproject.toml'
51+
)

taskipy/pyproject.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from pathlib import Path
2+
from typing import Any, MutableMapping, Union
3+
4+
import toml
5+
6+
from taskipy.exceptions import (
7+
MalformedPyProjectError,
8+
MissingPyProjectFileError,
9+
MissingTaskipyTasksSectionError,
10+
MissingTaskipySettingsSectionError
11+
)
12+
13+
14+
class PyProject:
15+
def __init__(self, file_path: Union[str, Path]):
16+
self.__items = PyProject.__load_toml_file(file_path)
17+
18+
@property
19+
def tasks(self) -> dict:
20+
try:
21+
return self.__items['tool']['taskipy']['tasks']
22+
except KeyError:
23+
raise MissingTaskipyTasksSectionError()
24+
25+
@property
26+
def settings(self) -> dict:
27+
try:
28+
return self.__items['tool']['taskipy']['settings']
29+
except KeyError:
30+
raise MissingTaskipySettingsSectionError()
31+
32+
@staticmethod
33+
def __load_toml_file(file_path: Union[str, Path]) -> MutableMapping[str, Any]:
34+
try:
35+
if isinstance(file_path, str):
36+
file_path = Path(file_path).resolve()
37+
38+
return toml.load(file_path)
39+
except FileNotFoundError:
40+
raise MissingPyProjectFileError()
41+
except toml.TomlDecodeError:
42+
raise MalformedPyProjectError()

0 commit comments

Comments
 (0)