runem 0.0.30__py3-none-any.whl → 0.0.32__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- runem/VERSION +1 -1
- runem/command_line.py +48 -6
- runem/files.py +61 -17
- runem-0.0.32.dist-info/METADATA +154 -0
- {runem-0.0.30.dist-info → runem-0.0.32.dist-info}/RECORD +9 -9
- {runem-0.0.30.dist-info → runem-0.0.32.dist-info}/WHEEL +1 -1
- runem-0.0.30.dist-info/METADATA +0 -689
- {runem-0.0.30.dist-info → runem-0.0.32.dist-info}/LICENSE +0 -0
- {runem-0.0.30.dist-info → runem-0.0.32.dist-info}/entry_points.txt +0 -0
- {runem-0.0.30.dist-info → runem-0.0.32.dist-info}/top_level.txt +0 -0
runem/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.32
|
runem/command_line.py
CHANGED
@@ -119,8 +119,8 @@ def parse_args(
|
|
119
119
|
|
120
120
|
parser.add_argument(
|
121
121
|
"-f",
|
122
|
-
"--modified-files
|
123
|
-
dest="
|
122
|
+
"--modified-files",
|
123
|
+
dest="check_modified_files",
|
124
124
|
help="only use files that have changed",
|
125
125
|
action=argparse.BooleanOptionalAction,
|
126
126
|
default=False,
|
@@ -129,13 +129,36 @@ def parse_args(
|
|
129
129
|
|
130
130
|
parser.add_argument(
|
131
131
|
"-h",
|
132
|
-
"--git-head-files
|
133
|
-
dest="
|
132
|
+
"--git-head-files",
|
133
|
+
dest="check_head_files",
|
134
134
|
help="fast run of files",
|
135
135
|
action=argparse.BooleanOptionalAction,
|
136
136
|
default=False,
|
137
137
|
required=False,
|
138
138
|
)
|
139
|
+
parser.add_argument(
|
140
|
+
"--always-files",
|
141
|
+
dest="always_files",
|
142
|
+
help=(
|
143
|
+
"list of paths/files to always check (overriding -f/-h), if the path "
|
144
|
+
"matches the filter regex and if file-paths exist"
|
145
|
+
),
|
146
|
+
nargs="+",
|
147
|
+
default=None,
|
148
|
+
required=False,
|
149
|
+
)
|
150
|
+
|
151
|
+
parser.add_argument(
|
152
|
+
"--git-files-since-branch",
|
153
|
+
dest="git_since_branch",
|
154
|
+
help=(
|
155
|
+
"Get the list of paths/files changed between a branch, e.g., since "
|
156
|
+
"'origin/main'. Useful for checking files changed before pushing."
|
157
|
+
),
|
158
|
+
default=None, # Default to None if no branch is specified
|
159
|
+
required=False, # Not required, users may not want to specify a branch
|
160
|
+
type=str, # Accepts a string input representing the branch name
|
161
|
+
)
|
139
162
|
|
140
163
|
parser.add_argument(
|
141
164
|
"--procs",
|
@@ -151,7 +174,7 @@ def parse_args(
|
|
151
174
|
type=int,
|
152
175
|
)
|
153
176
|
|
154
|
-
config_dir: pathlib.Path = config_metadata
|
177
|
+
config_dir: pathlib.Path = _get_config_dir(config_metadata)
|
155
178
|
parser.add_argument(
|
156
179
|
"--root",
|
157
180
|
dest="root_dir",
|
@@ -163,6 +186,15 @@ def parse_args(
|
|
163
186
|
required=False,
|
164
187
|
)
|
165
188
|
|
189
|
+
parser.add_argument(
|
190
|
+
"--root-show",
|
191
|
+
dest="show_root_path_and_exit",
|
192
|
+
help="show the root-path of runem and exit",
|
193
|
+
action=argparse.BooleanOptionalAction,
|
194
|
+
default=False,
|
195
|
+
required=False,
|
196
|
+
)
|
197
|
+
|
166
198
|
parser.add_argument(
|
167
199
|
"--spinner",
|
168
200
|
dest="show_spinner",
|
@@ -196,6 +228,11 @@ def parse_args(
|
|
196
228
|
|
197
229
|
args = parser.parse_args(argv[1:])
|
198
230
|
|
231
|
+
if args.show_root_path_and_exit:
|
232
|
+
log(str(config_metadata.cfg_filepath.parent), decorate=False)
|
233
|
+
# cleanly exit
|
234
|
+
sys.exit(0)
|
235
|
+
|
199
236
|
if args.show_version_and_exit:
|
200
237
|
log(str(get_runem_version()), decorate=False)
|
201
238
|
# cleanly exit
|
@@ -219,6 +256,11 @@ def parse_args(
|
|
219
256
|
return config_metadata
|
220
257
|
|
221
258
|
|
259
|
+
def _get_config_dir(config_metadata: ConfigMetadata) -> pathlib.Path:
|
260
|
+
"""A function to get the path, that we can mock in tests."""
|
261
|
+
return config_metadata.cfg_filepath.parent
|
262
|
+
|
263
|
+
|
222
264
|
def _validate_filters(
|
223
265
|
config_metadata: ConfigMetadata,
|
224
266
|
args: argparse.Namespace,
|
@@ -338,7 +380,7 @@ def _define_option_args(
|
|
338
380
|
|
339
381
|
|
340
382
|
def _alias_to_switch(switch_name_alias: str, negatise: bool = False) -> str:
|
341
|
-
"""Util function to generate a alias switch for
|
383
|
+
"""Util function to generate a alias switch for argparse."""
|
342
384
|
single_letter_variant = not negatise and len(switch_name_alias) == 1
|
343
385
|
if single_letter_variant:
|
344
386
|
return f"-{switch_name_alias}"
|
runem/files.py
CHANGED
@@ -26,26 +26,60 @@ def find_files(config_metadata: ConfigMetadata) -> FilePathListLookup:
|
|
26
26
|
|
27
27
|
file_paths: typing.List[str] = []
|
28
28
|
|
29
|
-
if
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
if (
|
30
|
+
config_metadata.args.check_modified_files
|
31
|
+
or config_metadata.args.check_head_files
|
32
|
+
or (config_metadata.args.git_since_branch is not None)
|
33
|
+
):
|
34
|
+
if config_metadata.args.check_modified_files:
|
35
|
+
# get modified, un-staged files first
|
36
|
+
file_paths.extend(
|
37
|
+
subprocess_check_output(
|
38
|
+
"git diff --name-only",
|
39
|
+
shell=True,
|
40
|
+
)
|
41
|
+
.decode("utf-8")
|
42
|
+
.splitlines()
|
34
43
|
)
|
35
|
-
|
36
|
-
.
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
shell=True,
|
44
|
+
# now get modified, staged files first
|
45
|
+
file_paths.extend(
|
46
|
+
subprocess_check_output(
|
47
|
+
"git diff --name-only --staged",
|
48
|
+
shell=True,
|
49
|
+
)
|
50
|
+
.decode("utf-8")
|
51
|
+
.splitlines()
|
44
52
|
)
|
45
|
-
|
46
|
-
|
53
|
+
|
54
|
+
if config_metadata.args.check_head_files:
|
55
|
+
# Fetching modified and added files from the HEAD commit
|
56
|
+
file_paths.extend(
|
57
|
+
subprocess_check_output(
|
58
|
+
"git diff-tree --no-commit-id --name-only -r HEAD",
|
59
|
+
shell=True,
|
60
|
+
)
|
61
|
+
.decode("utf-8")
|
62
|
+
.splitlines()
|
63
|
+
)
|
64
|
+
|
65
|
+
if config_metadata.args.git_since_branch is not None:
|
66
|
+
# Add all files changed since a particular branch e..g `origin/main`
|
67
|
+
# Useful for quickly checking branches before pushing.
|
68
|
+
# NOTE: without dependency checking this might report false-positives.
|
69
|
+
target_branch: str = config_metadata.args.git_since_branch
|
70
|
+
file_paths.extend(
|
71
|
+
subprocess_check_output(
|
72
|
+
f"git diff --name-only {target_branch}...HEAD",
|
73
|
+
shell=True,
|
74
|
+
)
|
75
|
+
.decode("utf-8")
|
76
|
+
.splitlines()
|
77
|
+
)
|
78
|
+
# ensure files are unique, and still on disk i.e. filter-out deleted files
|
79
|
+
file_paths = list(
|
80
|
+
{file_path for file_path in file_paths if Path(file_path).exists()}
|
47
81
|
)
|
48
|
-
|
82
|
+
|
49
83
|
else:
|
50
84
|
# fall-back to all files
|
51
85
|
file_paths = (
|
@@ -56,6 +90,16 @@ def find_files(config_metadata: ConfigMetadata) -> FilePathListLookup:
|
|
56
90
|
.decode("utf-8")
|
57
91
|
.splitlines()
|
58
92
|
)
|
93
|
+
|
94
|
+
if config_metadata.args.always_files is not None:
|
95
|
+
# a poor-man's version of adding path-regex's
|
96
|
+
existent_files = [
|
97
|
+
filepath
|
98
|
+
for filepath in config_metadata.args.always_files
|
99
|
+
if Path(filepath).exists()
|
100
|
+
]
|
101
|
+
file_paths.extend(existent_files)
|
102
|
+
|
59
103
|
_bucket_file_by_tag(
|
60
104
|
file_paths,
|
61
105
|
config_metadata,
|
@@ -0,0 +1,154 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: runem
|
3
|
+
Version: 0.0.32
|
4
|
+
Summary: Awesome runem created by lursight
|
5
|
+
Home-page: https://github.com/lursight/runem/
|
6
|
+
Author: lursight
|
7
|
+
Description-Content-Type: text/markdown
|
8
|
+
License-File: LICENSE
|
9
|
+
Requires-Dist: halo
|
10
|
+
Requires-Dist: packaging
|
11
|
+
Requires-Dist: PyYAML
|
12
|
+
Provides-Extra: tests
|
13
|
+
Requires-Dist: black==24.3.0; extra == "tests"
|
14
|
+
Requires-Dist: coverage==7.4.4; extra == "tests"
|
15
|
+
Requires-Dist: docformatter==1.7.5; extra == "tests"
|
16
|
+
Requires-Dist: flake8-bugbear==24.2.6; extra == "tests"
|
17
|
+
Requires-Dist: flake8==7.0.0; extra == "tests"
|
18
|
+
Requires-Dist: gitchangelog==3.0.4; extra == "tests"
|
19
|
+
Requires-Dist: isort==5.13.2; extra == "tests"
|
20
|
+
Requires-Dist: mkdocs==1.5.3; extra == "tests"
|
21
|
+
Requires-Dist: mypy==1.9.0; extra == "tests"
|
22
|
+
Requires-Dist: pydocstyle==6.3.0; extra == "tests"
|
23
|
+
Requires-Dist: pylint==3.1.0; extra == "tests"
|
24
|
+
Requires-Dist: pylama==8.4.1; extra == "tests"
|
25
|
+
Requires-Dist: pytest-cov==4.1.0; extra == "tests"
|
26
|
+
Requires-Dist: pytest-profiling==1.7.0; extra == "tests"
|
27
|
+
Requires-Dist: pytest-xdist==3.5.0; extra == "tests"
|
28
|
+
Requires-Dist: pytest==8.1.1; extra == "tests"
|
29
|
+
Requires-Dist: setuptools; extra == "tests"
|
30
|
+
Requires-Dist: termplotlib==0.3.9; extra == "tests"
|
31
|
+
Requires-Dist: tox; extra == "tests"
|
32
|
+
Requires-Dist: types-PyYAML==6.0.12.20240311; extra == "tests"
|
33
|
+
Requires-Dist: requests-mock==1.11.0; extra == "tests"
|
34
|
+
Requires-Dist: types-setuptools; extra == "tests"
|
35
|
+
|
36
|
+
<!-- [](https://codecov.io/gh/lursight/runem) -->
|
37
|
+
[](https://github.com/lursight/runem/actions/workflows/main.yml)
|
38
|
+
[](https://lursight.github.io/runem/)
|
39
|
+
|
40
|
+
# Run'em: Accelerate Your Development Workflow
|
41
|
+
**Boost Efficiency and Save Time**
|
42
|
+
Runem is a flexible, multi-process tool designed to speed up your everyday tasks by running them in parallel. Whether you're testing, linting, or deploying, runem helps you work smarter and faster.
|
43
|
+
|
44
|
+
## Why Choose Run'em?
|
45
|
+
- **Streamlined Task Management**: Configure tasks with ease using declarative .runem.yml files.
|
46
|
+
- **Multiprocess Execution**: Run multiple tasks simultaneously, minimizing wall-clock time.
|
47
|
+
- **Optimized for Monorepos**: Supports multiple projects and task types, with easy filtering and configuration.
|
48
|
+
- **Detailed Reporting**: Get insights into task execution time and efficiency gains.
|
49
|
+
|
50
|
+
## Contents
|
51
|
+
- [Run'em: Accelerate Your Development Workflow](#runem-accelerate-your-development-workflow)
|
52
|
+
- [Why Choose Run'em?](#why-choose-runem)
|
53
|
+
- [Contents](#contents)
|
54
|
+
- [Features At A Glance:](#features-at-a-glance)
|
55
|
+
- [Using Run'em](#using-runem)
|
56
|
+
- [Installation](#installation)
|
57
|
+
- [Quick-start](#quick-start)
|
58
|
+
- [Basic quick-start](#basic-quick-start)
|
59
|
+
- [A more complete quick-start](#a-more-complete-quick-start)
|
60
|
+
- [Basic Use](#basic-use)
|
61
|
+
- [Advanced Use](#advanced-use)
|
62
|
+
- [Advanced configuration options](#advanced-configuration-options)
|
63
|
+
- [Custom reports](#custom-reports)
|
64
|
+
- [Help and job discovery](#help-and-job-discovery)
|
65
|
+
- [Troubleshooting](#troubleshooting)
|
66
|
+
- [Contributing to and supporting runem](#contributing-to-and-supporting-runem)
|
67
|
+
- [Development](#development)
|
68
|
+
- [Sponsor](#sponsor)
|
69
|
+
- [About runem](#about-runem)
|
70
|
+
|
71
|
+
|
72
|
+
# Features At A Glance:
|
73
|
+
- **Tagging**: Easily run specific job groups (e.g., lint, test, python).
|
74
|
+
- **Phases**: Organize tasks by phase (e.g., edit, test, deploy).
|
75
|
+
- **Configurable Options**: Customize how jobs are executed using simple options.
|
76
|
+
- **Declarative**: Jobs are define using simple YAML in [.runem.yml](https://lursight.github.io/runem/docs/configuration.html) .
|
77
|
+
|
78
|
+
# Using Run'em
|
79
|
+
|
80
|
+
## Installation
|
81
|
+
|
82
|
+
```bash
|
83
|
+
pip install runem
|
84
|
+
```
|
85
|
+
|
86
|
+
## Quick-start
|
87
|
+
|
88
|
+
## Basic quick-start
|
89
|
+
Create the following `.runem.yml` file at the root of your project:
|
90
|
+
|
91
|
+
```yml
|
92
|
+
- job:
|
93
|
+
command: echo "hello world!"
|
94
|
+
```
|
95
|
+
|
96
|
+
Then anywhere in your project run `runem` to see how and when that task is run, and how long it took:
|
97
|
+
```bash
|
98
|
+
runem
|
99
|
+
```
|
100
|
+
|
101
|
+
To see the actual log output you will need to use `--verbose` as `runem` hides anything that isn't important. Only failures and reports are considered important.
|
102
|
+
```bash
|
103
|
+
# Or, to see "hello world!", use --verbose
|
104
|
+
runem --verbose # add --verbose to see the actual output
|
105
|
+
```
|
106
|
+
|
107
|
+
To see how you can control your job use `--help`:
|
108
|
+
```bash
|
109
|
+
runem --help
|
110
|
+
```
|
111
|
+
|
112
|
+
### A more complete quick-start
|
113
|
+
|
114
|
+
See [quick-start docs](https://lursight.github.io/runem/docs/quick_start.html) for more quick-start tips.
|
115
|
+
|
116
|
+
## Basic Use
|
117
|
+
|
118
|
+
See [docs on basic use and use-cases](https://lursight.github.io/runem/docs/basic_use.html) for a comprehensive introduction.
|
119
|
+
|
120
|
+
## Advanced Use
|
121
|
+
|
122
|
+
### Advanced configuration options
|
123
|
+
See [configuration docs](https://lursight.github.io/runem/docs/configuration.html) for advanced configuration and use.
|
124
|
+
|
125
|
+
### Custom reports
|
126
|
+
See [reporting docs](https://lursight.github.io/runem/docs/reports.html) for more information on how reporting works.
|
127
|
+
|
128
|
+
|
129
|
+
# Help and job discovery
|
130
|
+
|
131
|
+
`--help` is designed to help your team discover what jobs and tasks they can automated. Read more at
|
132
|
+
[help and discovery docs](https://lursight.github.io/runem/docs/help_and_job_discovery.html).
|
133
|
+
|
134
|
+
# Troubleshooting
|
135
|
+
|
136
|
+
See [troubleshooting and known issues docs](https://lursight.github.io/runem/docs/troubleshooting_known_issues.html).
|
137
|
+
|
138
|
+
---
|
139
|
+
# Contributing to and supporting runem
|
140
|
+
|
141
|
+
Awesome runem created by lursight
|
142
|
+
|
143
|
+
## Development
|
144
|
+
|
145
|
+
Read the [CONTRIBUTING.md](CONTRIBUTING.md) file.
|
146
|
+
|
147
|
+
## Sponsor
|
148
|
+
|
149
|
+
[❤️ Sponsor this project](https://github.com/sponsors/lursight/)
|
150
|
+
|
151
|
+
# About runem
|
152
|
+
The runem mission is to improve developer velocity at
|
153
|
+
[Lursight Ltd.](https://lursight.com), read more about the runem
|
154
|
+
[mission](https://lursight.github.io/runem/docs/mission.html).
|
@@ -1,14 +1,14 @@
|
|
1
|
-
runem/VERSION,sha256
|
1
|
+
runem/VERSION,sha256=-h82hZtjHMX-cbkdelMOLC62FvWkuDkAAR466UOFbEc,7
|
2
2
|
runem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
3
|
runem/__main__.py,sha256=dsOiVZegpfK9JOs5n7UmbX5iwwbj7iFkEbLoVeEgAn4,136
|
4
4
|
runem/base.py,sha256=EZfR7FIlwEdU9Vfe47Wk2DOO8GQqpKxxLNKp6YHueZ4,316
|
5
5
|
runem/blocking_print.py,sha256=S9dtgAeuTzc2-ht-vk9Wl6l-0PwS2tYbHDHDQQitrlA,841
|
6
6
|
runem/cli.py,sha256=wEt_Jnumhl8SiOdKdSJzLkJpWv6n3_Odhi_HeIixr1k,134
|
7
|
-
runem/command_line.py,sha256=
|
7
|
+
runem/command_line.py,sha256=QwtmDTx2BJ1OfMpULUzOcWBibwgEiRHfz58prZgkEyo,12402
|
8
8
|
runem/config.py,sha256=y-e6j84FDiLSKKw9ShDzRlnS5t2e81MW8fKSKtxtJtg,5935
|
9
9
|
runem/config_metadata.py,sha256=Vy7dx8F-Z5jEp16OP2y6vHHoGkyhoCaTG4KIVkMWR7M,3232
|
10
10
|
runem/config_parse.py,sha256=6mCamzWu7HTotmqFJmLZg9FFE6qe1-rpmo8_v5ESPW8,13401
|
11
|
-
runem/files.py,sha256=
|
11
|
+
runem/files.py,sha256=QZqPS7OA98lEwlhJNtnaSWlEeTlI8_yn-zjf3QAPoJk,4384
|
12
12
|
runem/hook_manager.py,sha256=9T-4omyjBPZ6ua_37UWpT1dwNMbb4SKwvxYcN6fVxLE,4163
|
13
13
|
runem/informative_dict.py,sha256=U7p9z78UwOT4TAfng1iDXCEyeYz6C-XZlx9Z1pWNVrI,1548
|
14
14
|
runem/job.py,sha256=QVXvzz67fJk__-h0womFQsB80-w41E3XRcHpxmRnv3o,2912
|
@@ -25,9 +25,9 @@ runem/runem.py,sha256=RIKF-l_ziGs0oKEueVkfygmnc_xiIdQo2qNDpiA-2Zs,13013
|
|
25
25
|
runem/runem_version.py,sha256=MbETwZO2Tb1Y3hX_OYZjKepEMKA1cjNvr-7Cqhz6e3s,271
|
26
26
|
runem/types.py,sha256=TLagRdB6-4gKqETAeJzo7-HFwBqQWGTwHcw2slSKN0U,7445
|
27
27
|
runem/utils.py,sha256=3N_kel9LsriiMq7kOjT14XhfxUOgz4hdDg97wlLKm3U,221
|
28
|
-
runem-0.0.
|
29
|
-
runem-0.0.
|
30
|
-
runem-0.0.
|
31
|
-
runem-0.0.
|
32
|
-
runem-0.0.
|
33
|
-
runem-0.0.
|
28
|
+
runem-0.0.32.dist-info/LICENSE,sha256=awOCsWJ58m_2kBQwBUGWejVqZm6wuRtCL2hi9rfa0X4,1211
|
29
|
+
runem-0.0.32.dist-info/METADATA,sha256=Xa7dVT07j4ihVpqFouck31Exs4691zseqaqbnCdcY8c,5811
|
30
|
+
runem-0.0.32.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
|
31
|
+
runem-0.0.32.dist-info/entry_points.txt,sha256=nu0g_vBeuPihYtimbtlNusxWovylMppvJ8UxdJlJfvM,46
|
32
|
+
runem-0.0.32.dist-info/top_level.txt,sha256=gK6iqh9OfHDDpErioCC9ul_zx2Q5zWTALtcuGU7Vil4,6
|
33
|
+
runem-0.0.32.dist-info/RECORD,,
|
runem-0.0.30.dist-info/METADATA
DELETED
@@ -1,689 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: runem
|
3
|
-
Version: 0.0.30
|
4
|
-
Summary: Awesome runem created by lursight
|
5
|
-
Home-page: https://github.com/lursight/runem/
|
6
|
-
Author: lursight
|
7
|
-
Description-Content-Type: text/markdown
|
8
|
-
License-File: LICENSE
|
9
|
-
Requires-Dist: halo
|
10
|
-
Requires-Dist: packaging
|
11
|
-
Requires-Dist: PyYAML
|
12
|
-
Provides-Extra: test
|
13
|
-
Requires-Dist: black ==24.3.0 ; extra == 'test'
|
14
|
-
Requires-Dist: coverage ==7.4.4 ; extra == 'test'
|
15
|
-
Requires-Dist: docformatter ==1.7.5 ; extra == 'test'
|
16
|
-
Requires-Dist: flake8-bugbear ==24.2.6 ; extra == 'test'
|
17
|
-
Requires-Dist: flake8 ==7.0.0 ; extra == 'test'
|
18
|
-
Requires-Dist: gitchangelog ==3.0.4 ; extra == 'test'
|
19
|
-
Requires-Dist: isort ==5.13.2 ; extra == 'test'
|
20
|
-
Requires-Dist: mkdocs ==1.5.3 ; extra == 'test'
|
21
|
-
Requires-Dist: mypy ==1.9.0 ; extra == 'test'
|
22
|
-
Requires-Dist: pydocstyle ==6.3.0 ; extra == 'test'
|
23
|
-
Requires-Dist: pylint ==3.1.0 ; extra == 'test'
|
24
|
-
Requires-Dist: pylama ==8.4.1 ; extra == 'test'
|
25
|
-
Requires-Dist: pytest-cov ==4.1.0 ; extra == 'test'
|
26
|
-
Requires-Dist: pytest-profiling ==1.7.0 ; extra == 'test'
|
27
|
-
Requires-Dist: pytest-xdist ==3.5.0 ; extra == 'test'
|
28
|
-
Requires-Dist: pytest ==8.1.1 ; extra == 'test'
|
29
|
-
Requires-Dist: setuptools ; extra == 'test'
|
30
|
-
Requires-Dist: termplotlib ==0.3.9 ; extra == 'test'
|
31
|
-
Requires-Dist: types-PyYAML ==6.0.12.20240311 ; extra == 'test'
|
32
|
-
Requires-Dist: requests-mock ==1.11.0 ; extra == 'test'
|
33
|
-
Requires-Dist: types-setuptools ; extra == 'test'
|
34
|
-
|
35
|
-
# Run 'em
|
36
|
-
|
37
|
-
## Reducing the wall-clock time running your developer-local tasks
|
38
|
-
|
39
|
-
`runem` (run 'em) is an unopinionated way to declare and run the many command-line tools developers use regularly.
|
40
|
-
|
41
|
-
## 1. Overview
|
42
|
-
|
43
|
-
The core objective of Run'em's is to minimize the wall-clock time required for running checks, supporting [shift-left](https://en.wikipedia.org/wiki/Shift-left_testing). Overall it is designed to enhance iteration speed and boost developer productivity.
|
44
|
-
|
45
|
-
`runem` is also designed to be easy to learn and simple to use, but `runem` also has many powerful tools for advanced users.
|
46
|
-
|
47
|
-
Job definitions are declarative and simple.
|
48
|
-
|
49
|
-
The in-built reports show how long each job took and how much time `runem` saved you.
|
50
|
-
|
51
|
-
Jobs can be filtered in or out very easily.
|
52
|
-
|
53
|
-
Multiple projects can be supported in a single `.runem.yml` config, support workspaces and mono-repos. Also multiple task types, working on multiple file-types can be supported.
|
54
|
-
|
55
|
-
Finally, because of how it's built, job definitions are auto-documented via `runem --help`. This help onboarding new developers by making tool-discovery easier. Therefore it also helps maintenance of developer tools.
|
56
|
-
|
57
|
-
### 1.1. Why is it called `runem`?
|
58
|
-
|
59
|
-
Primarily `runem`, as a command line tool, is quick to type and tries to just get out of the way when running your developer-local tools.
|
60
|
-
|
61
|
-
The name "runem" is a portmanteau of "run" and "them", encapsulating that runem "runs them", but slightly faster.
|
62
|
-
|
63
|
-
## 2. Contents
|
64
|
-
- [Run 'em](#run-em)
|
65
|
-
- [Reducing the wall-clock time running your developer-local tasks](#reducing-the-wall-clock-time-running-your-developer-local-tasks)
|
66
|
-
- [1. Overview](#1-overview)
|
67
|
-
- [1.1. Why is it called `runem`?](#11-why-is-it-called-runem)
|
68
|
-
- [2. Contents](#2-contents)
|
69
|
-
- [3. Feature overview](#3-feature-overview)
|
70
|
-
- [4. Installation](#4-installation)
|
71
|
-
- [5. Quick-start](#5-quick-start)
|
72
|
-
- [5.1. Basic quick-start](#51-basic-quick-start)
|
73
|
-
- [5.2. A more complete quick-start](#52-a-more-complete-quick-start)
|
74
|
-
- [5.2.1. A simple `.runem.yml`](#521-a-simple-runemyml)
|
75
|
-
- [5.2.2. A simple python task](#522-a-simple-python-task)
|
76
|
-
- [6. Basic usage](#6-basic-usage)
|
77
|
-
- [6.1. Tag filters](#61-tag-filters)
|
78
|
-
- [6.1.1. Run jobs only with the 'lint' tag:](#611-run-jobs-only-with-the-lint-tag)
|
79
|
-
- [6.1.2. If you want to lint all code _except_ nodejs code (and you have the appropriate tags):](#612-if-you-want-to-lint-all-code-except-nodejs-code-and-you-have-the-appropriate-tags)
|
80
|
-
- [6.1.3. Run fast checks on `pre-commit`](#613-run-fast-checks-on-pre-commit)
|
81
|
-
- [6.2. Phase filters](#62-phase-filters)
|
82
|
-
- [6.2.1. Focus on a phase](#621-focus-on-a-phase)
|
83
|
-
- [6.2.2. Exclude slow phases temporarily](#622-exclude-slow-phases-temporarily)
|
84
|
-
- [7. Reports on your tasks](#7-reports-on-your-tasks)
|
85
|
-
- [7.1. Task timings report](#71-task-timings-report)
|
86
|
-
- [7.2. Bar-graphs with `termplotlib`](#72-bar-graphs-with-termplotlib)
|
87
|
-
- [8. Using \`--help\`\` to get an overview of your Jobs](#8-using---help-to-get-an-overview-of-your-jobs)
|
88
|
-
- [9. Configuration](#9-configuration)
|
89
|
-
- [9.1. `config` - Run 'em global config](#91-config---run-em-global-config)
|
90
|
-
- [9.2. `job` - Job config](#92-job---job-config)
|
91
|
-
- [10. Troubleshooting \& Known issues](#10-troubleshooting--known-issues)
|
92
|
-
- [9.1. I don't see bar graph timing reports!](#91-i-dont-see-bar-graph-timing-reports)
|
93
|
-
- [Solution:](#solution)
|
94
|
-
- [10.2. I can't specify a dependency!](#102-i-cant-specify-a-dependency)
|
95
|
-
- [Solution](#solution-1)
|
96
|
-
- [10.3. Why is there so much output on errors, it looks duplicated?](#103-why-is-there-so-much-output-on-errors-it-looks-duplicated)
|
97
|
-
- [Solution](#solution-2)
|
98
|
-
- [10.4. When errors happen I don't see reports for jobs!](#104-when-errors-happen-i-dont-see-reports-for-jobs)
|
99
|
-
- [Solution](#solution-3)
|
100
|
-
- [10.5. I want to see log output for tasks in real-time, as they're happening!](#105-i-want-to-see-log-output-for-tasks-in-real-time-as-theyre-happening)
|
101
|
-
- [Solution](#solution-4)
|
102
|
-
- [Contributing to and supporting runem](#contributing-to-and-supporting-runem)
|
103
|
-
- [Development](#development)
|
104
|
-
- [Sponsor](#sponsor)
|
105
|
-
|
106
|
-
|
107
|
-
## 3. Feature overview
|
108
|
-
|
109
|
-
- **Declarative Tasks** Describe all your tasks once, and optionally describe how and when to run them.
|
110
|
-
|
111
|
-
- **Tagged Jobs:** Use tagging to define which type of jobs you want to run, be it `pre-commit`, `lint`, `test` or in multi-project codebases to split between running `python`, `node.js` or `c++` jobs, depending on the context you are working in!
|
112
|
-
|
113
|
-
- **Multiprocess Execution:** Leverage the power of multiprocessing for concurrent test job execution, optimizing efficiency and reducing runtime.
|
114
|
-
|
115
|
-
- **Data-Driven Test Management:** Drive your tests with data, making it easy to adapt and scale your testing suite to various scenarios, allowing you to execute, track, and analyze your dev-ops suite with ease.
|
116
|
-
|
117
|
-
## 4. Installation
|
118
|
-
|
119
|
-
```bash
|
120
|
-
pip install runem
|
121
|
-
```
|
122
|
-
|
123
|
-
## 5. Quick-start
|
124
|
-
|
125
|
-
## 5.1. Basic quick-start
|
126
|
-
Create the following `.runem.yml` file at the root of your project:
|
127
|
-
|
128
|
-
```yml
|
129
|
-
- job:
|
130
|
-
command: echo "hello world!"
|
131
|
-
```
|
132
|
-
|
133
|
-
Then anywhere in your project run `runem` to see how and when that task is run, and how long it took:
|
134
|
-
```bash
|
135
|
-
runem
|
136
|
-
```
|
137
|
-
|
138
|
-
To see the actual log output you will need to use `--verbose` as `runem` hides anything that isn't important. Only failures and reports are considered important.
|
139
|
-
```bash
|
140
|
-
# Or, to see "hello world!", use --verbose
|
141
|
-
runem --verbose # add --verbose to see the actual output
|
142
|
-
```
|
143
|
-
|
144
|
-
To see how you can control your job use `--help`:
|
145
|
-
```bash
|
146
|
-
runem --help
|
147
|
-
```
|
148
|
-
|
149
|
-
### 5.2. A more complete quick-start
|
150
|
-
|
151
|
-
Here's a simple setup for a python project.
|
152
|
-
|
153
|
-
#### 5.2.1. A simple `.runem.yml`
|
154
|
-
|
155
|
-
```yml
|
156
|
-
- config:
|
157
|
-
phases:
|
158
|
-
- edit
|
159
|
-
- analysis
|
160
|
-
files:
|
161
|
-
- filter:
|
162
|
-
tag: py
|
163
|
-
regex: ".*\\.py$"
|
164
|
-
options:
|
165
|
-
- option:
|
166
|
-
name: black
|
167
|
-
default: true
|
168
|
-
type: bool
|
169
|
-
desc: allow/disallows py-black from running
|
170
|
-
- option:
|
171
|
-
name: docformatter
|
172
|
-
default: true
|
173
|
-
type: bool
|
174
|
-
desc: formats docs and comments in whatever job can do so
|
175
|
-
- option:
|
176
|
-
name: check-only
|
177
|
-
alias: check
|
178
|
-
default: false
|
179
|
-
type: bool
|
180
|
-
desc: runs in check-mode, erroring if isort, black or any text-edits would occur
|
181
|
-
- job:
|
182
|
-
command: pytest tests/
|
183
|
-
when:
|
184
|
-
phase: analysis
|
185
|
-
tags:
|
186
|
-
- py
|
187
|
-
- job:
|
188
|
-
command: mypy my_project/ tests/
|
189
|
-
when:
|
190
|
-
phase: analysis
|
191
|
-
tags:
|
192
|
-
- py
|
193
|
-
- job:
|
194
|
-
addr:
|
195
|
-
file: runem_hooks/py.py
|
196
|
-
function: _job_py_code_reformat
|
197
|
-
label: reformat py
|
198
|
-
when:
|
199
|
-
phase: edit
|
200
|
-
tags:
|
201
|
-
- py
|
202
|
-
- format
|
203
|
-
- py format
|
204
|
-
```
|
205
|
-
|
206
|
-
Notice that this specifies:
|
207
|
-
- The `phases` to use, and their order:
|
208
|
-
- This shows how we can control tasks that edit the files can go before analysis
|
209
|
-
- This reduces any false-negatives the jobs may generate from running multiple jobs that may contend for write-access on the same files
|
210
|
-
- NOTE: `phases` are an early-stage way:
|
211
|
-
- To implement dependency chaining
|
212
|
-
- There is no dependency linking between jobs, yet.
|
213
|
-
- To manage resources
|
214
|
-
- For example, if you have a task which is threaded and/or memory heavy, you may want to put that into its own phase to get faster output.
|
215
|
-
- `tags` to allow control over which jobs to run.
|
216
|
-
- Also which files to pass to jobs.
|
217
|
-
- File-filters to detect which files the job operate on.
|
218
|
-
- NOTE: this is a WIP feature
|
219
|
-
- Uses job-options:
|
220
|
-
- Allowing a python-function-job to control it's sub-task/processes.
|
221
|
-
- If you use `--help` you will see a summary of all controls available.
|
222
|
-
|
223
|
-
#### 5.2.2. A simple python task
|
224
|
-
|
225
|
-
Here's a simple python file describing a job. This accompanies the above `.runem.yml`.
|
226
|
-
|
227
|
-
```py
|
228
|
-
# runem_hooks/py.py
|
229
|
-
# A file to do more advanced and conditional checking using the `runem` infrastructure.
|
230
|
-
import typing
|
231
|
-
|
232
|
-
from runem.log import log
|
233
|
-
from runem.run_command import RunCommandUnhandledError, run_command
|
234
|
-
from runem.types import FilePathList, JobName, JobReturnData, Options
|
235
|
-
|
236
|
-
|
237
|
-
def _job_py_code_reformat(
|
238
|
-
**kwargs: typing.Any,
|
239
|
-
) -> None:
|
240
|
-
"""Runs python formatting code in serial order as one influences the other."""
|
241
|
-
label: JobName = kwargs["label"]
|
242
|
-
options: Options = kwargs["options"]
|
243
|
-
python_files: FilePathList = kwargs["file_list"]
|
244
|
-
|
245
|
-
# put into 'check' mode if requested on the command line
|
246
|
-
extra_args = []
|
247
|
-
docformatter_extra_args = [
|
248
|
-
"--in-place",
|
249
|
-
]
|
250
|
-
if options["check-only"]:
|
251
|
-
extra_args.append("--check")
|
252
|
-
docformatter_extra_args = [] # --inplace is not compatible with --check
|
253
|
-
|
254
|
-
if options["black"]:
|
255
|
-
black_cmd = [
|
256
|
-
"python3",
|
257
|
-
"-m",
|
258
|
-
"black",
|
259
|
-
*extra_args,
|
260
|
-
*python_files,
|
261
|
-
]
|
262
|
-
kwargs["label"] = f"{label} black"
|
263
|
-
run_command(cmd=black_cmd, **kwargs)
|
264
|
-
|
265
|
-
if options["docformatter"]:
|
266
|
-
docformatter_cmd = [
|
267
|
-
"python3",
|
268
|
-
"-m",
|
269
|
-
"docformatter",
|
270
|
-
"--wrap-summaries",
|
271
|
-
"88",
|
272
|
-
"--wrap-descriptions",
|
273
|
-
"88",
|
274
|
-
*docformatter_extra_args,
|
275
|
-
*extra_args,
|
276
|
-
*python_files,
|
277
|
-
]
|
278
|
-
allowed_exits: typing.Tuple[int, ...] = (
|
279
|
-
0, # no work/change required
|
280
|
-
3, # no errors, but code was reformatted
|
281
|
-
)
|
282
|
-
if options["check-only"]:
|
283
|
-
# in check it is ONLY ok if no work/change was required
|
284
|
-
allowed_exits = (0,)
|
285
|
-
kwargs["label"] = f"{label} docformatter"
|
286
|
-
run_command(
|
287
|
-
cmd=docformatter_cmd,
|
288
|
-
ignore_fails=False,
|
289
|
-
valid_exit_ids=allowed_exits,
|
290
|
-
**kwargs,
|
291
|
-
)
|
292
|
-
```
|
293
|
-
The above python file accompanies the above `.runem.yml` configuration and does slightly more advanced work. The file contains:
|
294
|
-
- a single job.
|
295
|
-
- the job itself linearises edit tasks that would otherwise contend for write-access to the files they operate on.
|
296
|
-
- formatting and doc-generation both edit files, conforming them to the coding standard.
|
297
|
-
- uses `options` (see the config section) to control whether to:
|
298
|
-
- use `check-only` mode for CiCd, modifying the command-line switched passed down to the sub-commands.
|
299
|
-
- control whether `python-black` and/or/nor `docformatter` is run.
|
300
|
-
- modifies the allowed-exit codes for `docformatter` to be `0` or `3`, matching the designed behaviour of that tool.
|
301
|
-
|
302
|
-
## 6. Basic usage
|
303
|
-
|
304
|
-
```bash
|
305
|
-
# run all configured default jobs
|
306
|
-
runem
|
307
|
-
|
308
|
-
# ---- or ----
|
309
|
-
|
310
|
-
# apply filters and controls
|
311
|
-
runem [--tags tag1,tag2,tag3] [--not-tags tag1,tag2,tag3] \
|
312
|
-
[--phases phaseX, phaseY] \
|
313
|
-
[--MY-OPTION] [--not-MY-OPTION]
|
314
|
-
|
315
|
-
# ---- or ----
|
316
|
-
|
317
|
-
# run as a module
|
318
|
-
python3 -m runem [--tags tag1,tag2,tag3] [--not-tags tag1,tag2,tag3] \
|
319
|
-
[--phases phaseX, phaseY] \
|
320
|
-
[--MY-OPTION] [--not-MY-OPTION]
|
321
|
-
```
|
322
|
-
|
323
|
-
### 6.1. Tag filters
|
324
|
-
Jobs are tagged in the .runem.yml config file. Each unique tags is made available on the command-line. To see which tags are available use `--help`. To add a new tag extend the `tags` field in the `job` config.
|
325
|
-
|
326
|
-
You can control which types of jobs to run via tags. Just tag the job in the config and then from the command-line you can add `--tags` or `--not-tags` to refine exactly which jobs will be run.
|
327
|
-
|
328
|
-
To debug why a job is not selected pass `--verbose`.
|
329
|
-
|
330
|
-
For example, if you have a `python` tagged job or jobs, to run only run those jobs you would do the following:
|
331
|
-
|
332
|
-
```bash
|
333
|
-
runem --tags python
|
334
|
-
```
|
335
|
-
|
336
|
-
`--tags` are exclusive filter in, that is the tags passed in replace are the only tags that are run. This allows one to focus on running just a subset of tags.
|
337
|
-
|
338
|
-
`--not-tags` are subtractive filter out, that is any job with these tags are not run, even if they have tags set via the `--tags` switch. Meaning you can choose to run `python` tagged job but not run the `lint` jobs with `--tags python --not-tags lint`, and so on.
|
339
|
-
|
340
|
-
#### 6.1.1. Run jobs only with the 'lint' tag:
|
341
|
-
|
342
|
-
```bash
|
343
|
-
runem --tags lint
|
344
|
-
```
|
345
|
-
|
346
|
-
#### 6.1.2. If you want to lint all code _except_ nodejs code (and you have the appropriate tags):
|
347
|
-
|
348
|
-
```bash
|
349
|
-
runem --tags lint --not-tags deprecated
|
350
|
-
```
|
351
|
-
|
352
|
-
#### 6.1.3. Run fast checks on `pre-commit`
|
353
|
-
|
354
|
-
If you have fast jobs that tagged as appropriate for pre-commit hooks.
|
355
|
-
|
356
|
-
```bash
|
357
|
-
mkdir scripts/git-hooks
|
358
|
-
echo "runem --tags pre-commit" > scripts/git-hooks/pre-commit
|
359
|
-
# add the following to .git/config
|
360
|
-
# [core]
|
361
|
-
# # ... existing config ...
|
362
|
-
# hooksPath = ./scripts/git-hooks/husky/
|
363
|
-
```
|
364
|
-
|
365
|
-
### 6.2. Phase filters
|
366
|
-
|
367
|
-
Sometimes just want to run a specific phase, so you can focus on it and iterate quickly, within that context.
|
368
|
-
|
369
|
-
#### 6.2.1. Focus on a phase
|
370
|
-
|
371
|
-
For example, if you have a `reformat` phase, you might want to run just `reformat` jobs phase whilst preparing a commit and are just preparing cosmetic changes e.g. updating comments, syntax, or docs.
|
372
|
-
|
373
|
-
```bash
|
374
|
-
runem --phase reformat
|
375
|
-
```
|
376
|
-
|
377
|
-
#### 6.2.2. Exclude slow phases temporarily
|
378
|
-
|
379
|
-
If you have 4 stages `bootstrap`, `pre-run`, `reformat`, `test` and `verify` phase, and are tightly iterating and focusing on the 'test-coverage' aspect of the test-phase, then you do not care about formatting as long as you can see your coverage results ASAP. However if your test-coverage starts passing then you will care about subsequent stages, so you can exclude the slower reformat-stage with the following and everything else will run.
|
380
|
-
|
381
|
-
```bash
|
382
|
-
runem --not-phase pre-run reformat
|
383
|
-
```
|
384
|
-
|
385
|
-
**Note:** The `--tags` and `--not-tags` options can be used in combination to further refine task execution based on your requirements.
|
386
|
-
|
387
|
-
## 7. Reports on your tasks
|
388
|
-
|
389
|
-
Runem has a built-in support for reporting on tasks
|
390
|
-
|
391
|
-
### 7.1. Task timings report
|
392
|
-
|
393
|
-
Runem will run the task and report how long the task took and whether it saved you any time, for example:
|
394
|
-
|
395
|
-
```text
|
396
|
-
# output from runem when run on runem's project, without `termplotlib`
|
397
|
-
runem: Running 'pre-run' with 2 workers (of 8 max) processing 2 jobs
|
398
|
-
runem: Running 'edit' with 1 workers (of 8 max) processing 1 jobs
|
399
|
-
runem: Running 'analysis' with 7 workers (of 8 max) processing 7 jobs
|
400
|
-
runem: reports:
|
401
|
-
runem: runem: 8.820488s
|
402
|
-
runem: ├runem.pre-build: 0.019031s
|
403
|
-
runem: ├runem.run-phases: 8.801317s
|
404
|
-
runem: ├pre-run (user-time): 0.00498s
|
405
|
-
runem: │├pre-run.install python requirements: 2.6e-05s
|
406
|
-
runem: │├pre-run.ls -alh runem: 0.004954s
|
407
|
-
runem: ├edit (user-time): 0.557559s
|
408
|
-
runem: │├edit.reformat py: 0.557559s
|
409
|
-
runem: ├analysis (user-time): 21.526145s
|
410
|
-
runem: │├analysis.pylint py: 7.457029s
|
411
|
-
runem: │├analysis.flake8 py: 0.693754s
|
412
|
-
runem: │├analysis.mypy py: 1.071956s
|
413
|
-
runem: │├analysis.pytest: 6.780303s
|
414
|
-
runem: │├analysis.json validate: 0.035359s
|
415
|
-
runem: │├analysis.yarn run spellCheck: 4.482992s
|
416
|
-
runem: │├analysis.prettier: 1.004752s
|
417
|
-
runem: report: coverage html: ./reports/coverage_python/index.html
|
418
|
-
runem: report: coverage cobertura: ./reports/coverage_python/cobertura.xml
|
419
|
-
runem: DONE: runem took: 8.820488s, saving you 13.268196s
|
420
|
-
```
|
421
|
-
|
422
|
-
### 7.2. Bar-graphs with `termplotlib`
|
423
|
-
|
424
|
-
If you have `termplotlib` installed you will see something like:
|
425
|
-
|
426
|
-
```text
|
427
|
-
runem: Running 'pre-run' with 2 workers (of 8 max) processing 2 jobs
|
428
|
-
runem: Running 'edit' with 1 workers (of 8 max) processing 1 jobs
|
429
|
-
runem: Running 'analysis' with 7 workers (of 8 max) processing 7 jobs
|
430
|
-
runem: reports:
|
431
|
-
runem [14.174612] ███████████████▋
|
432
|
-
├runem.pre-build [ 0.025858]
|
433
|
-
├runem.run-phases [14.148587] ███████████████▋
|
434
|
-
├pre-run (user-time) [ 0.005825]
|
435
|
-
│├pre-run.install python requirements [ 0.000028]
|
436
|
-
│├pre-run.ls -alh runem [ 0.005797]
|
437
|
-
├edit (user-time) [ 0.579153] ▋
|
438
|
-
│├edit.reformat py [ 0.579153] ▋
|
439
|
-
├analysis (user-time) [36.231034] ████████████████████████████████████████
|
440
|
-
│├analysis.pylint py [12.738303] ██████████████▏
|
441
|
-
│├analysis.flake8 py [ 0.798575] ▉
|
442
|
-
│├analysis.mypy py [ 0.335984] ▍
|
443
|
-
│├analysis.pytest [11.996717] █████████████▎
|
444
|
-
│├analysis.json validate [ 0.050847]
|
445
|
-
│├analysis.yarn run spellCheck [ 8.809372] █████████▊
|
446
|
-
│├analysis.prettier [ 1.501236] █▋
|
447
|
-
runem: report: coverage html: ./reports/coverage_python/index.html
|
448
|
-
runem: report: coverage cobertura: ./reports/coverage_python/cobertura.xml
|
449
|
-
runem: DONE: runem took: 14.174612s, saving you 22.6414s
|
450
|
-
```
|
451
|
-
|
452
|
-
NOTE: each phase's total system-time is reported above the timing for the individual jobs ran in that phase. This is NOT wall-clock time.
|
453
|
-
|
454
|
-
## 8. Using `--help`` to get an overview of your Jobs
|
455
|
-
|
456
|
-
The `--help` switch will show you a full list of all the configured job-tasks, the tags, and the override options. `--help` describes how to configure a specific run for *your* `.runem.yml` setup, and does NOT just document `runem` itself; it documents *your* workflow.
|
457
|
-
|
458
|
-
```bash
|
459
|
-
$ python -m runem --help
|
460
|
-
#or
|
461
|
-
$ runem --help
|
462
|
-
```
|
463
|
-
|
464
|
-
<details>
|
465
|
-
<summary>For example</summary>
|
466
|
-
|
467
|
-
```
|
468
|
-
usage: runem.py [-h] [--jobs JOBS [JOBS ...]] [--not-jobs JOBS_EXCLUDED [JOBS_EXCLUDED ...]] [--phases PHASES [PHASES ...]]
|
469
|
-
[--not-phases PHASES_EXCLUDED [PHASES_EXCLUDED ...]] [--tags TAGS [TAGS ...]] [--not-tags TAGS_EXCLUDED [TAGS_EXCLUDED ...]]
|
470
|
-
[--black] [--no-black] [--check-only] [--no-check-only] [--coverage] [--no-coverage] [--docformatter] [--no-docformatter]
|
471
|
-
[--generate-call-graphs] [--no-generate-call-graphs] [--install-deps] [--no-install-deps] [--isort] [--no-isort] [--profile]
|
472
|
-
[--no-profile] [--unit-test] [--no-unit-test]
|
473
|
-
[--call-graphs | --no-call-graphs]
|
474
|
-
[--procs PROCS] [--root ROOT_DIR] [--verbose | --no-verbose | -v]
|
475
|
-
|
476
|
-
Runs the Lursight Lang test-suite
|
477
|
-
|
478
|
-
options:
|
479
|
-
-h, --help show this help message and exit
|
480
|
-
--call-graphs, --no-call-graphs
|
481
|
-
--procs PROCS, -j PROCS
|
482
|
-
the number of concurrent test jobs to run, -1 runs all test jobs at the same time (8 cores available)
|
483
|
-
--root ROOT_DIR which dir to use as the base-dir for testing, defaults to checkout root
|
484
|
-
--verbose, --no-verbose, -v
|
485
|
-
|
486
|
-
jobs:
|
487
|
-
--jobs JOBS [JOBS ...]
|
488
|
-
List of job-names to run the given jobs. Other filters will modify this list. Defaults to '['flake8 py', 'install
|
489
|
-
python requirements', 'json validate', 'mypy py', 'pylint py', 'reformat py', 'spell check']'
|
490
|
-
--not-jobs JOBS_EXCLUDED [JOBS_EXCLUDED ...]
|
491
|
-
List of job-names to NOT run. Defaults to empty. Available options are: '['flake8 py', 'install python requirements',
|
492
|
-
'json validate', 'mypy py', 'pylint py', 'reformat py', 'spell check']'
|
493
|
-
|
494
|
-
phases:
|
495
|
-
--phases PHASES [PHASES ...]
|
496
|
-
Run only the phases passed in, and can be used to change the phase order. Phases are run in the order given. Defaults
|
497
|
-
to '{'edit', 'pre-run', 'analysis'}'.
|
498
|
-
--not-phases PHASES_EXCLUDED [PHASES_EXCLUDED ...]
|
499
|
-
List of phases to NOT run. This option does not change the phase run order. Options are '['analysis', 'edit', 'pre-
|
500
|
-
run']'.
|
501
|
-
|
502
|
-
tags:
|
503
|
-
--tags TAGS [TAGS ...]
|
504
|
-
Only jobs with the given tags. Defaults to '['json', 'lint', 'py', 'spell', 'type']'.
|
505
|
-
--not-tags TAGS_EXCLUDED [TAGS_EXCLUDED ...]
|
506
|
-
Removes one or more tags from the list of job tags to be run. Options are '['json', 'lint', 'py', 'spell', 'type']'.
|
507
|
-
|
508
|
-
job-param overrides:
|
509
|
-
--black allow/disallows py-black from running
|
510
|
-
--no-black turn off allow/disallows py-black from running
|
511
|
-
--check-only runs in check-mode, erroring if isort, black or any text-edits would occur
|
512
|
-
--no-check-only turn off runs in check-mode, erroring if isort, black or any text-edits would occur
|
513
|
-
--coverage generates coverage reports for whatever can generate coverage info when added
|
514
|
-
--no-coverage turn off generates coverage reports for whatever can generate coverage info when added
|
515
|
-
--docformatter formats docs and comments in whatever job can do so
|
516
|
-
--no-docformatter turn off formats docs and comments in whatever job can do so
|
517
|
-
--generate-call-graphs
|
518
|
-
Generates call-graphs in jobs that can
|
519
|
-
--no-generate-call-graphs
|
520
|
-
turn off Generates call-graphs in jobs that can
|
521
|
-
--install-deps gets dep-installing job to run
|
522
|
-
--no-install-deps turn off gets dep-installing job to run
|
523
|
-
--isort allow/disallows isort from running on python files
|
524
|
-
--no-isort turn off allow/disallows isort from running on python files
|
525
|
-
--profile generate profile information in jobs that can
|
526
|
-
--no-profile turn off generate profile information in jobs that can
|
527
|
-
--unit-test run unit tests
|
528
|
-
--no-unit-test turn off run unit tests
|
529
|
-
```
|
530
|
-
</details>
|
531
|
-
|
532
|
-
## 9. Configuration
|
533
|
-
|
534
|
-
`runem` searches for `.runem.yml` and will pre-load the command-line options with
|
535
|
-
|
536
|
-
Configuration is Yaml and consists of two main configurations, `config` and `job`:
|
537
|
-
|
538
|
-
- `config` describes how the jobs should be run.
|
539
|
-
- each `job` entry describe a job-task, such and running unit-tests, linting or running any other type of command.
|
540
|
-
|
541
|
-
### 9.1. `config` - Run 'em global config
|
542
|
-
|
543
|
-
- **phases:**
|
544
|
-
- *Description:* Specifies the different phases of the testing process, in the order they are to be run. Each job will be run under a specific phase.
|
545
|
-
- *Values:* A list of strings representing "phases" such as pre-run (e.g. bootstrapping), edit (running py-black or prettifier or clang-tools), and analysis (unit-tests, coverage, linting).
|
546
|
-
|
547
|
-
- **files:**
|
548
|
-
- *Description:* Defines filters for categorizing files based on tags and regular expressions. Maps tags to files-to-be tested. If a job has one or more tags that map to file-filters that job will receive all files that match those filters.
|
549
|
-
- *Values:* A list of dictionaries, each containing a 'filter' key with 'tag' and 'regex' subkeys.
|
550
|
-
|
551
|
-
- **options:**
|
552
|
-
- *Description:* Configures various option-overrides for the job-tasks. Overrides can be set on the command line and accessed by jobs to turn on or off features such as 'check-only' or to opt out of sub-tasks.
|
553
|
-
- *Values:* A list of dictionaries, each containing an 'option' key with 'default' boolean value, a 'name', a 'type', a 'desc', and optional 'alias' subkeys. NOTE: only 'bool' types are currently supported.
|
554
|
-
|
555
|
-
- **default:** Specifies the default value of the option.
|
556
|
-
- **name:** Represents the name of the option.
|
557
|
-
- **type:** Indicates the data type of the option (e.g., bool for boolean).
|
558
|
-
- **desc:** Provides a description of the option.
|
559
|
-
- **alias:** (Optional) Provides an alias for the option if specified.
|
560
|
-
|
561
|
-
### 9.2. `job` - Job config
|
562
|
-
- **job:**
|
563
|
-
- *Description:* Represents a specific job task that is to be run asynchronously.
|
564
|
-
- *Fields:*
|
565
|
-
- **command:**
|
566
|
-
- *Description:* a simple command line to be run. Commands will be run by the system exactly as they are written. Use `addr` for more complicated jobs. Commands are run in their associate `context`.
|
567
|
-
- *Example:
|
568
|
-
```yaml
|
569
|
-
command: yarn run pretty
|
570
|
-
```
|
571
|
-
```yaml
|
572
|
-
command: python3 -m pylint **/*.py
|
573
|
-
```
|
574
|
-
```yaml
|
575
|
-
command: bash scripts/build_wrapper.sh
|
576
|
-
```
|
577
|
-
```yaml
|
578
|
-
command: clang-tidy -checks='*' -fix -header-filter='.*' your_file.cpp
|
579
|
-
```
|
580
|
-
|
581
|
-
- **addr:**
|
582
|
-
- *Description:* Specifies where a python function can be found. The python function will be loaded at runtime by `runem` and called with the `context`. The function receives all information needed to run the job, including `label`, `JobConfig`, `verbose`, `options` and other run-time context.
|
583
|
-
- *Subkeys:*
|
584
|
-
- **file:** Indicates the file path of the job.
|
585
|
-
- **function:** Indicates the function within the file that represents the job.
|
586
|
-
- *Example:*
|
587
|
-
```yaml
|
588
|
-
file: scripts/test-hooks/rust_wrappers.py
|
589
|
-
function: _job_rust_code_reformat
|
590
|
-
```
|
591
|
-
|
592
|
-
- **ctx:**
|
593
|
-
- *Description:* Provides the execution context for the job, including the working directory and parameters.
|
594
|
-
- *Subkeys:*
|
595
|
-
- **cwd:** Specifies the working directory for the job.
|
596
|
-
- **params:** Specifies parameters for the job.
|
597
|
-
- *Example:*
|
598
|
-
```yaml
|
599
|
-
cwd: .
|
600
|
-
params:
|
601
|
-
limitFilesToGroup: true
|
602
|
-
```
|
603
|
-
|
604
|
-
- **label:**
|
605
|
-
- *Description:* Assigns a label to the job for identification.
|
606
|
-
- *Example:*
|
607
|
-
```yaml
|
608
|
-
label: reformat py
|
609
|
-
```
|
610
|
-
|
611
|
-
- **when:**
|
612
|
-
- *Description:* Defines the conditions under which the job should run.
|
613
|
-
- *Subkeys:*
|
614
|
-
- **phase:** Specifies the testing phase in which the job should run.
|
615
|
-
- **tags:** Specifies the tags associated with the job.
|
616
|
-
- *Example:*
|
617
|
-
```yaml
|
618
|
-
when:
|
619
|
-
phase: edit
|
620
|
-
tags:
|
621
|
-
- py
|
622
|
-
- format
|
623
|
-
```
|
624
|
-
|
625
|
-
- *Example:*
|
626
|
-
```yaml
|
627
|
-
- job:
|
628
|
-
addr:
|
629
|
-
file: scripts/test-hooks/nodejs.py
|
630
|
-
function: _job_js_code_reformat
|
631
|
-
ctx:
|
632
|
-
cwd: src/subproject_4
|
633
|
-
params:
|
634
|
-
limitFilesToGroup: true
|
635
|
-
label: reformat
|
636
|
-
when:
|
637
|
-
phase: edit
|
638
|
-
tags:
|
639
|
-
- js
|
640
|
-
- subproject4
|
641
|
-
- pretty
|
642
|
-
|
643
|
-
## 10. Troubleshooting & Known issues
|
644
|
-
|
645
|
-
### 9.1. I don't see bar graph timing reports!
|
646
|
-
We don't specify it in the output to reduce dependency installation for ci/cd. We may change this decision, especially as `halo` is a first-order dependency now.
|
647
|
-
|
648
|
-
#### Solution:
|
649
|
-
install `termplotlib`,
|
650
|
-
|
651
|
-
### 10.2. I can't specify a dependency!
|
652
|
-
Outside of `phases` we don't support direct dependency-chaining between tasks. We would like to do this at some point. PRs gladly accepted for this.
|
653
|
-
|
654
|
-
#### Solution
|
655
|
-
Use `phases` instead, or contribute a PR.
|
656
|
-
|
657
|
-
### 10.3. Why is there so much output on errors, it looks duplicated?
|
658
|
-
We haven't looked at how we manage exception-handling with the python `multiprocessing` library, yet. Errors in `multiprocessing` procs tend to be re-reported in the calling process. PRs welcome.
|
659
|
-
|
660
|
-
#### Solution
|
661
|
-
Just look at one of the outputs.
|
662
|
-
|
663
|
-
### 10.4. When errors happen I don't see reports for jobs!
|
664
|
-
We try to show reports for completed tasks. If the task you're interested in doesn't show, it probably hasn't been executed yet. Otherwise scroll up and you should see the reports and timings of *completed* tasks, if not, you may need to increase your terminal's view-buffer size.
|
665
|
-
|
666
|
-
#### Solution
|
667
|
-
If you are focusing on one task and are only interested in how that task is performing/operating, use one of the many filtering options e.g. `--jobs "your job name" "another job name"` or `--tags unittest`.
|
668
|
-
|
669
|
-
### 10.5. I want to see log output for tasks in real-time, as they're happening!
|
670
|
-
We don't stream stdout/stderr direct to console, or provide functionality for doing so, yet. However, we also believe that it would be a nice feature and welcome PRs.
|
671
|
-
|
672
|
-
#### Solution
|
673
|
-
On failure and with `--verbose` mode, the exact command is logged to console along with the environment that job was run in. You can copy/paste that command line to a terminal and run the command manually. The stdout/stderr will then be as you would get for that command. Refer to the documentation for that command.
|
674
|
-
|
675
|
-
---
|
676
|
-
# Contributing to and supporting runem
|
677
|
-
|
678
|
-
[](https://codecov.io/gh/lursight/runem)
|
679
|
-
[](https://github.com/lursight/runem/actions/workflows/main.yml)
|
680
|
-
|
681
|
-
Awesome runem created by lursight
|
682
|
-
|
683
|
-
## Development
|
684
|
-
|
685
|
-
Read the [CONTRIBUTING.md](CONTRIBUTING.md) file.
|
686
|
-
|
687
|
-
## Sponsor
|
688
|
-
|
689
|
-
[❤️ Sponsor this project](https://github.com/sponsors/lursight/)
|
File without changes
|
File without changes
|
File without changes
|