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 CHANGED
@@ -1 +1 @@
1
- 0.0.30
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-only",
123
- dest="check_modified_files_only",
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-only",
133
- dest="check_head_files_only",
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.cfg_filepath.parent
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 argsparse."""
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 config_metadata.args.check_modified_files_only:
30
- file_paths = (
31
- subprocess_check_output(
32
- "git diff --name-only",
33
- shell=True,
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
- .decode("utf-8")
36
- .splitlines()
37
- )
38
- elif config_metadata.args.check_head_files_only:
39
- # Fetching modified and added files from the HEAD commit that are still on disk
40
- file_paths = (
41
- subprocess_check_output(
42
- "git diff-tree --no-commit-id --name-only -r HEAD",
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
- .decode("utf-8")
46
- .splitlines()
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
- file_paths = [file_path for file_path in file_paths if Path(file_path).exists()]
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
+ <!-- [![codecov](https://codecov.io/gh/lursight/runem/branch/main/graph/badge.svg?token=run-test_token_here)](https://codecov.io/gh/lursight/runem) -->
37
+ [![CI](https://github.com/lursight/runem/actions/workflows/main.yml/badge.svg)](https://github.com/lursight/runem/actions/workflows/main.yml)
38
+ [![DOCS](https://lursight.github.io/runem/docs/VIEW-DOCS-31c553.svg)](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=gEtWWt0L1z5lxa4WmXDkvO_ucp0v_0QZPdvkbSU-bNs,7
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=1H1wZDfJrNCRly5yUBodYDvvKw8-4uLd3q-tcCvk1jM,11019
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=CrwEiwPV0ZrrU3Ve0RWTTw9AtOQLekNXua347YYqcqQ,2748
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.30.dist-info/LICENSE,sha256=awOCsWJ58m_2kBQwBUGWejVqZm6wuRtCL2hi9rfa0X4,1211
29
- runem-0.0.30.dist-info/METADATA,sha256=HVftDpbRdnyeVk3Xi1c3VtWIcyVJH_2CUCkJy4qoKFs,29789
30
- runem-0.0.30.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
31
- runem-0.0.30.dist-info/entry_points.txt,sha256=nu0g_vBeuPihYtimbtlNusxWovylMppvJ8UxdJlJfvM,46
32
- runem-0.0.30.dist-info/top_level.txt,sha256=gK6iqh9OfHDDpErioCC9ul_zx2Q5zWTALtcuGU7Vil4,6
33
- runem-0.0.30.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (75.5.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -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
- [![codecov](https://codecov.io/gh/lursight/runem/branch/main/graph/badge.svg?token=run-test_token_here)](https://codecov.io/gh/lursight/runem)
679
- [![CI](https://github.com/lursight/runem/actions/workflows/main.yml/badge.svg)](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/)