runem 0.4.0__tar.gz → 0.6.0__tar.gz
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-0.4.0 → runem-0.6.0}/HISTORY.md +111 -0
- runem-0.6.0/PKG-INFO +161 -0
- runem-0.6.0/README.md +117 -0
- runem-0.6.0/pyproject.toml +74 -0
- runem-0.6.0/runem/VERSION +1 -0
- {runem-0.4.0 → runem-0.6.0}/runem/blocking_print.py +10 -2
- {runem-0.4.0 → runem-0.6.0}/runem/command_line.py +23 -1
- {runem-0.4.0 → runem-0.6.0}/runem/config_parse.py +21 -7
- {runem-0.4.0 → runem-0.6.0}/runem/job_execute.py +3 -2
- runem-0.6.0/runem/log.py +43 -0
- {runem-0.4.0 → runem-0.6.0}/runem/report.py +4 -1
- {runem-0.4.0 → runem-0.6.0}/runem/run_command.py +62 -26
- {runem-0.4.0 → runem-0.6.0}/runem/runem.py +46 -60
- {runem-0.4.0 → runem-0.6.0}/runem/types/__init__.py +2 -1
- runem-0.6.0/runem/utils.py +18 -0
- runem-0.6.0/runem.egg-info/PKG-INFO +161 -0
- {runem-0.4.0 → runem-0.6.0}/runem.egg-info/SOURCES.txt +8 -3
- {runem-0.4.0 → runem-0.6.0}/runem.egg-info/requires.txt +4 -4
- runem-0.6.0/runem.egg-info/top_level.txt +5 -0
- runem-0.6.0/scripts/test_hooks/json_validators.py +32 -0
- runem-0.6.0/scripts/test_hooks/py.py +292 -0
- runem-0.6.0/scripts/test_hooks/runem_hooks.py +19 -0
- runem-0.6.0/scripts/test_hooks/yarn.py +48 -0
- runem-0.6.0/setup.cfg +7 -0
- runem-0.6.0/tests/__init__.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/data/help_output.3.10.txt +15 -39
- {runem-0.4.0 → runem-0.6.0}/tests/data/help_output.3.11.txt +14 -37
- runem-0.6.0/tests/intentional_test_error.py +8 -0
- {runem-0.4.0 → runem-0.6.0}/tests/test_hook_manager.py +2 -2
- {runem-0.4.0 → runem-0.6.0}/tests/test_job_execute.py +18 -8
- {runem-0.4.0 → runem-0.6.0}/tests/test_run_command.py +9 -9
- {runem-0.4.0 → runem-0.6.0}/tests/test_runem.py +51 -18
- runem-0.6.0/tests/test_types/__init__.py +0 -0
- runem-0.4.0/PKG-INFO +0 -155
- runem-0.4.0/README.md +0 -120
- runem-0.4.0/requirements-test.txt +0 -23
- runem-0.4.0/requirements.txt +0 -9
- runem-0.4.0/runem/VERSION +0 -1
- runem-0.4.0/runem/log.py +0 -24
- runem-0.4.0/runem/utils.py +0 -6
- runem-0.4.0/runem.egg-info/PKG-INFO +0 -155
- runem-0.4.0/runem.egg-info/top_level.txt +0 -2
- runem-0.4.0/setup.cfg +0 -4
- runem-0.4.0/setup.py +0 -51
- runem-0.4.0/tests/intentional_test_error.py +0 -5
- {runem-0.4.0 → runem-0.6.0}/Containerfile +0 -0
- {runem-0.4.0 → runem-0.6.0}/LICENSE +0 -0
- {runem-0.4.0 → runem-0.6.0}/MANIFEST.in +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/__init__.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/__main__.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/base.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/cli/initialise_options.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/cli.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/config.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/config_metadata.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/files.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/hook_manager.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/informative_dict.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/job.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/job_filter.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/job_runner_simple_command.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/job_wrapper.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/job_wrapper_python.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/py.typed +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/runem_version.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/types/common.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/types/errors.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/types/filters.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/types/hooks.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/types/options.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/types/runem_config.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem/types/types_jobs.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem.egg-info/dependency_links.txt +0 -0
- {runem-0.4.0 → runem-0.6.0}/runem.egg-info/entry_points.txt +0 -0
- {runem-0.4.0/tests → runem-0.6.0/scripts/test_hooks}/__init__.py +0 -0
- /runem-0.4.0/tests/test_types/__init__.py → /runem-0.6.0/scripts/test_hooks/py.typed +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/cli/test_initialise_options.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/conftest.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/sanitise_reports_footer.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/test_base.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/test_blocking_print.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/test_cli.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/test_config.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/test_config_parse.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/test_files.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/test_informative_dict.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/test_job.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/test_job_filter.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/test_job_runner_simple_command.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/test_job_wrapper.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/test_job_wrapper_python.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/test_report.py +0 -0
- {runem-0.4.0 → runem-0.6.0}/tests/test_types/test_public_api.py +0 -0
@@ -4,6 +4,117 @@ Changelog
|
|
4
4
|
|
5
5
|
(unreleased)
|
6
6
|
------------
|
7
|
+
- Merge pull request #78 from lursight/feat/better_error_display. [Frank
|
8
|
+
Harrison]
|
9
|
+
|
10
|
+
Feat/better error display
|
11
|
+
- Fix(spinner): fixes the Spinner show it only shows for --show-spinner.
|
12
|
+
[Frank Harrison]
|
13
|
+
|
14
|
+
Also, fixes it so that it shows only a single spinner
|
15
|
+
- Feat(colours): adds better colours to the terminal output. [Frank
|
16
|
+
Harrison]
|
17
|
+
|
18
|
+
This helps to reinfoce time-saved and other aspects of the tool.
|
19
|
+
- Feat(better-errors): makes finding the stderr in the list of errors
|
20
|
+
easier. [Frank Harrison]
|
21
|
+
|
22
|
+
We do this by colouring the text for the commands and wrapping the
|
23
|
+
errors with a red-box.
|
24
|
+
|
25
|
+
We colour:
|
26
|
+
- command-lines -> yellow
|
27
|
+
- job-labels -> blue
|
28
|
+
- errors -> red
|
29
|
+
- in-progress -> green box
|
30
|
+
- Merge pull request #77 from lursight/fix/log-verbosity. [Frank
|
31
|
+
Harrison]
|
32
|
+
|
33
|
+
fix(log-verbosity): fixes verbosity bug when not showing the spinner
|
34
|
+
- Fix(log-verbosity): fixes verbosity bug when not showing the spinner.
|
35
|
+
[Frank Harrison]
|
36
|
+
|
37
|
+
We were showing the running procs on every tick, instead of just the
|
38
|
+
changes to the running procs, if any.
|
39
|
+
- Merge pull request #76 from lursight/chore/types/job-return-type.
|
40
|
+
[Frank Harrison]
|
41
|
+
|
42
|
+
chore(types) fixes exports for JobReturn type
|
43
|
+
- Chore(types): exports the JobReturn type from the types submodule.
|
44
|
+
[Frank Harrison]
|
45
|
+
- Merge pull request #75 from lursight/chore/todos. [Frank Harrison]
|
46
|
+
|
47
|
+
chore(todos): adds TODOD.txt to track ideas for runem
|
48
|
+
- Chore(todos): adds TODOD.txt to track ideas for runem. [Frank
|
49
|
+
Harrison]
|
50
|
+
- Merge pull request #74 from lursight/chore/help_docs. [Frank Harrison]
|
51
|
+
|
52
|
+
chore(docs): removes help output from a details block
|
53
|
+
- Chore(docs): removes help output from a details block. [Frank
|
54
|
+
Harrison]
|
55
|
+
|
56
|
+
The details block broke the pre-formatted styling of the code-block.
|
57
|
+
- Merge pull request #73 from lursight/chore/update_contrib. [Frank
|
58
|
+
Harrison]
|
59
|
+
|
60
|
+
chore(docs): trying to add line-breaks to non-bulletpointed list
|
61
|
+
- Chore(docs): trying to add line-breaks to non-bulletpointed list.
|
62
|
+
[Frank Harrison]
|
63
|
+
- Merge pull request #72 from lursight/chore/update_contrib. [Frank
|
64
|
+
Harrison]
|
65
|
+
|
66
|
+
Chore/update CONTRIBUTING.md and README.md
|
67
|
+
- Chore(spell): adds 'pyenv' to dictionary. [Frank Harrison]
|
68
|
+
- Chore(docs): improves the README. [Frank Harrison]
|
69
|
+
- Docs(contrib): updates the contributing docs. [Frank Harrison]
|
70
|
+
|
71
|
+
We add some of the basics as well as some more recent changes
|
72
|
+
|
73
|
+
|
74
|
+
0.5.0 (2024-12-12)
|
75
|
+
------------------
|
76
|
+
- Release: version 0.5.0 🚀 [Frank Harrison]
|
77
|
+
- Merge pull request #71 from lursight/feat/pyproject. [Frank Harrison]
|
78
|
+
|
79
|
+
Feat/pyproject
|
80
|
+
- Feat(pyproject): changes how we chose to install deps during a runem
|
81
|
+
deps-install. [Frank Harrison]
|
82
|
+
- Feat(pyproject): tests the build works in ci/cd. [Frank Harrison]
|
83
|
+
|
84
|
+
I'd rather find out that this has failed before we get to the deploy-phase.
|
85
|
+
- Feat(pyproject): makes the version dynamic again, reading from the
|
86
|
+
VERSION file. [Frank Harrison]
|
87
|
+
- Feat(pyproject): ports setup.py to pyproject.toml, more future proof.
|
88
|
+
[Frank Harrison]
|
89
|
+
|
90
|
+
Makes the project more future-proof by moving to pyproject.
|
91
|
+
- Merge pull request #70 from lursight/chore/typo. [Frank Harrison]
|
92
|
+
|
93
|
+
chore(docs): improves the help comments for --tags options
|
94
|
+
- Chore(docs): improves the help comments for --tags options. [Frank
|
95
|
+
Harrison]
|
96
|
+
- Merge pull request #69 from lursight/feat/silent. [Frank Harrison]
|
97
|
+
|
98
|
+
Feat/silent
|
99
|
+
- Chore(pre-push): adds '--silent' option ahead of improving pre-push.
|
100
|
+
[Frank Harrison]
|
101
|
+
- Chore(pre-push): fixes typo in error. [Frank Harrison]
|
102
|
+
- Chore(help-test): updates the help text, I think after updating the
|
103
|
+
width in the test-render. [Frank Harrison]
|
104
|
+
- Merge pull request #68 from lursight/chore/yarn_update. [Frank
|
105
|
+
Harrison]
|
106
|
+
|
107
|
+
Chore/yarn update
|
108
|
+
- Chore(nodejs): try and enable corepack in ci/cd. [Frank Harrison]
|
109
|
+
- Chore(nodejs): refreshes the yarn deps lock file. [Frank Harrison]
|
110
|
+
- Chore(nodejs): removes the immutable options. [Frank Harrison]
|
111
|
+
- Chore(nodejs): updates the yarn tool version we prefer. [Frank
|
112
|
+
Harrison]
|
113
|
+
|
114
|
+
|
115
|
+
0.4.0 (2024-12-03)
|
116
|
+
------------------
|
117
|
+
- Release: version 0.4.0 🚀 [Frank Harrison]
|
7
118
|
- Merge pull request #67 from lursight/feat/prettier_logging. [Frank
|
8
119
|
Harrison]
|
9
120
|
|
runem-0.6.0/PKG-INFO
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
Metadata-Version: 2.2
|
2
|
+
Name: runem
|
3
|
+
Version: 0.6.0
|
4
|
+
Summary: Awesome runem created by lursight
|
5
|
+
Author: lursight
|
6
|
+
License: Specify your license here
|
7
|
+
Project-URL: Homepage, https://github.com/lursight/runem/
|
8
|
+
Keywords: example,runem
|
9
|
+
Classifier: Programming Language :: Python :: 3.7
|
10
|
+
Classifier: Programming Language :: Python :: 3.8
|
11
|
+
Classifier: Programming Language :: Python :: 3.9
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
14
|
+
Requires-Python: >=3.7
|
15
|
+
Description-Content-Type: text/markdown
|
16
|
+
License-File: LICENSE
|
17
|
+
Requires-Dist: packaging>=22.0
|
18
|
+
Requires-Dist: PyYAML>=5.0.0
|
19
|
+
Requires-Dist: rich>10.0.0
|
20
|
+
Requires-Dist: typing_extensions>3.0.0
|
21
|
+
Provides-Extra: tests
|
22
|
+
Requires-Dist: black==24.10.0; extra == "tests"
|
23
|
+
Requires-Dist: coverage==7.5; extra == "tests"
|
24
|
+
Requires-Dist: docformatter==1.7.5; extra == "tests"
|
25
|
+
Requires-Dist: flake8-bugbear==24.2.6; extra == "tests"
|
26
|
+
Requires-Dist: flake8==7.0.0; extra == "tests"
|
27
|
+
Requires-Dist: gitchangelog==3.0.4; extra == "tests"
|
28
|
+
Requires-Dist: isort==5.13.2; extra == "tests"
|
29
|
+
Requires-Dist: mkdocs==1.5.3; extra == "tests"
|
30
|
+
Requires-Dist: mypy==1.9.0; extra == "tests"
|
31
|
+
Requires-Dist: pydocstyle==6.3.0; extra == "tests"
|
32
|
+
Requires-Dist: pylint==3.1.0; extra == "tests"
|
33
|
+
Requires-Dist: pylama==8.4.1; extra == "tests"
|
34
|
+
Requires-Dist: pytest-cov==6.0.0; extra == "tests"
|
35
|
+
Requires-Dist: pytest-profiling==1.7.0; extra == "tests"
|
36
|
+
Requires-Dist: pytest-xdist==3.6.1; extra == "tests"
|
37
|
+
Requires-Dist: pytest==8.3.3; extra == "tests"
|
38
|
+
Requires-Dist: setuptools; extra == "tests"
|
39
|
+
Requires-Dist: termplotlib==0.3.9; extra == "tests"
|
40
|
+
Requires-Dist: tox; extra == "tests"
|
41
|
+
Requires-Dist: types-PyYAML==6.0.12.20240311; extra == "tests"
|
42
|
+
Requires-Dist: requests-mock==1.11.0; extra == "tests"
|
43
|
+
Requires-Dist: types-setuptools; extra == "tests"
|
44
|
+
|
45
|
+
<!-- [](https://codecov.io/gh/lursight/runem) -->
|
46
|
+
[](https://github.com/lursight/runem/actions/workflows/main.yml)
|
47
|
+
[](https://lursight.github.io/runem/)
|
48
|
+
|
49
|
+
# Run’em
|
50
|
+
|
51
|
+
**Your Blueprint of Commands. Your Engine of Parallel Execution.**
|
52
|
+
Run’em is your definitive blueprint of tasks and commands—instantly discoverable, effortlessly parallel, and elegantly extensible.
|
53
|
+
|
54
|
+
## Core Strengths
|
55
|
+
|
56
|
+
**Blueprint** - discover tasks and onboard smoothly\
|
57
|
+
**Parallel** - get results quicker\
|
58
|
+
**Simple** - define task easily\
|
59
|
+
**Extensible** - add tasks quickly\
|
60
|
+
**Filters** - powerful task selection\
|
61
|
+
**Reports** - see metrics on tasks
|
62
|
+
|
63
|
+
## Why Run’em?
|
64
|
+
- **Command Blueprint:** Instantly see and run all your tasks. No guesswork, no rummaging.
|
65
|
+
- **Effortless Parallelism:** Execute tasks side-by-side to obliterate downtime.
|
66
|
+
- **Simple YAML Declarations:** Define everything in one `.runem.yml`.
|
67
|
+
- **Extensible & Smart:** Adapt to monorepos, complex workflows, and evolving needs.
|
68
|
+
- **Discoverable by Design:** `runem --help` guides your team, new hires, or contributors to every defined command.
|
69
|
+
|
70
|
+
## Contents
|
71
|
+
- [Run’em](#runem)
|
72
|
+
- [Core Strengths](#core-strengths)
|
73
|
+
- [Why Run’em?](#why-runem)
|
74
|
+
- [Contents](#contents)
|
75
|
+
- [Highlights](#highlights)
|
76
|
+
- [Quick Start](#quick-start)
|
77
|
+
- [Basic Use](#basic-use)
|
78
|
+
- [Advanced Use](#advanced-use)
|
79
|
+
- [Help & Discovery](#help--discovery)
|
80
|
+
- [Troubleshooting](#troubleshooting)
|
81
|
+
- [Contribute & Support](#contribute--support)
|
82
|
+
- [About Run’em](#about-runem)
|
83
|
+
|
84
|
+
# Highlights
|
85
|
+
## Blueprint of Commands:
|
86
|
+
The blueprint (available via `--help`) gives you a manifest of all jobs and tasks in a
|
87
|
+
project. A single source of truth for all tasks.
|
88
|
+
## Parallel Execution:
|
89
|
+
Maximise speed with automatic concurrency. Runem tries to run all tasks as quickly as
|
90
|
+
possible, looking at resources, with dependencies. It is not yet a full
|
91
|
+
dependency-execution graph, but by version 1.0.0 it will be.
|
92
|
+
## Filtering:
|
93
|
+
Use powerful and flexible filtering. Select or excluded tasks by `tags`, `name` and
|
94
|
+
`phase`. Chose the task to be run based on your needs, right now.
|
95
|
+
|
96
|
+
You can also customise filtering by adding your own command `options`.
|
97
|
+
|
98
|
+
See `--tags`, `--not-tags`, `--jobs`, `--not-jobs`, `--phases` and `--not-phases`.
|
99
|
+
## Powerful Insights:** Understand what ran, how fast, and what failed.
|
100
|
+
**Quiet by Default:** Focus on what matters, and reveal detail only when needed.
|
101
|
+
|
102
|
+
# Quick Start
|
103
|
+
**Install:**
|
104
|
+
```bash
|
105
|
+
pip install runem
|
106
|
+
```
|
107
|
+
**Define a task:**
|
108
|
+
|
109
|
+
```yaml
|
110
|
+
`# .runem.yml
|
111
|
+
- job:
|
112
|
+
command: echo "hello world!"
|
113
|
+
```
|
114
|
+
|
115
|
+
**Run:**
|
116
|
+
|
117
|
+
```bash
|
118
|
+
runem
|
119
|
+
```
|
120
|
+
|
121
|
+
Run multiple commands in parallel, see timing, and keep output minimal. Need detail?
|
122
|
+
|
123
|
+
```bash
|
124
|
+
runem --verbose
|
125
|
+
```
|
126
|
+
|
127
|
+
[Quick Start Docs](https://lursight.github.io/runem/docs/quick_start.html)
|
128
|
+
|
129
|
+
# Basic Use
|
130
|
+
|
131
|
+
Get comfortable with typical workflows:
|
132
|
+
[Basic Use Docs](https://lursight.github.io/runem/docs/basic_use.html)
|
133
|
+
|
134
|
+
# Advanced Use
|
135
|
+
|
136
|
+
Scale up with multi-phase configs, filtered execution, and custom reporting:
|
137
|
+
[Advanced Configuration](https://lursight.github.io/runem/docs/configuration.html)
|
138
|
+
[Custom Reporting](https://lursight.github.io/runem/docs/reports.html)
|
139
|
+
|
140
|
+
# Help & Discovery
|
141
|
+
|
142
|
+
`runem --help` is your radar—instantly mapping out every available task:
|
143
|
+
[Help & Job Discovery](https://lursight.github.io/runem/docs/help_and_job_discovery.html)
|
144
|
+
|
145
|
+
# Troubleshooting
|
146
|
+
|
147
|
+
Swift solutions to common issues:
|
148
|
+
[Troubleshooting & Known Issues](https://lursight.github.io/runem/docs/troubleshooting_known_issues.html)
|
149
|
+
|
150
|
+
---
|
151
|
+
|
152
|
+
# Contribute & Support
|
153
|
+
|
154
|
+
Brought to you by [Lursight Ltd.](https://lursight.com) and an open community.
|
155
|
+
[CONTRIBUTING.md](CONTRIBUTING.md)
|
156
|
+
[❤️ Sponsor](https://github.com/sponsors/lursight/)
|
157
|
+
|
158
|
+
# About Run’em
|
159
|
+
|
160
|
+
Run’em exists to accelerate your team’s delivery and reduce complexity. Learn about our [Mission](https://lursight.github.io/runem/docs/mission.html).
|
161
|
+
|
runem-0.6.0/README.md
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
<!-- [](https://codecov.io/gh/lursight/runem) -->
|
2
|
+
[](https://github.com/lursight/runem/actions/workflows/main.yml)
|
3
|
+
[](https://lursight.github.io/runem/)
|
4
|
+
|
5
|
+
# Run’em
|
6
|
+
|
7
|
+
**Your Blueprint of Commands. Your Engine of Parallel Execution.**
|
8
|
+
Run’em is your definitive blueprint of tasks and commands—instantly discoverable, effortlessly parallel, and elegantly extensible.
|
9
|
+
|
10
|
+
## Core Strengths
|
11
|
+
|
12
|
+
**Blueprint** - discover tasks and onboard smoothly\
|
13
|
+
**Parallel** - get results quicker\
|
14
|
+
**Simple** - define task easily\
|
15
|
+
**Extensible** - add tasks quickly\
|
16
|
+
**Filters** - powerful task selection\
|
17
|
+
**Reports** - see metrics on tasks
|
18
|
+
|
19
|
+
## Why Run’em?
|
20
|
+
- **Command Blueprint:** Instantly see and run all your tasks. No guesswork, no rummaging.
|
21
|
+
- **Effortless Parallelism:** Execute tasks side-by-side to obliterate downtime.
|
22
|
+
- **Simple YAML Declarations:** Define everything in one `.runem.yml`.
|
23
|
+
- **Extensible & Smart:** Adapt to monorepos, complex workflows, and evolving needs.
|
24
|
+
- **Discoverable by Design:** `runem --help` guides your team, new hires, or contributors to every defined command.
|
25
|
+
|
26
|
+
## Contents
|
27
|
+
- [Run’em](#runem)
|
28
|
+
- [Core Strengths](#core-strengths)
|
29
|
+
- [Why Run’em?](#why-runem)
|
30
|
+
- [Contents](#contents)
|
31
|
+
- [Highlights](#highlights)
|
32
|
+
- [Quick Start](#quick-start)
|
33
|
+
- [Basic Use](#basic-use)
|
34
|
+
- [Advanced Use](#advanced-use)
|
35
|
+
- [Help & Discovery](#help--discovery)
|
36
|
+
- [Troubleshooting](#troubleshooting)
|
37
|
+
- [Contribute & Support](#contribute--support)
|
38
|
+
- [About Run’em](#about-runem)
|
39
|
+
|
40
|
+
# Highlights
|
41
|
+
## Blueprint of Commands:
|
42
|
+
The blueprint (available via `--help`) gives you a manifest of all jobs and tasks in a
|
43
|
+
project. A single source of truth for all tasks.
|
44
|
+
## Parallel Execution:
|
45
|
+
Maximise speed with automatic concurrency. Runem tries to run all tasks as quickly as
|
46
|
+
possible, looking at resources, with dependencies. It is not yet a full
|
47
|
+
dependency-execution graph, but by version 1.0.0 it will be.
|
48
|
+
## Filtering:
|
49
|
+
Use powerful and flexible filtering. Select or excluded tasks by `tags`, `name` and
|
50
|
+
`phase`. Chose the task to be run based on your needs, right now.
|
51
|
+
|
52
|
+
You can also customise filtering by adding your own command `options`.
|
53
|
+
|
54
|
+
See `--tags`, `--not-tags`, `--jobs`, `--not-jobs`, `--phases` and `--not-phases`.
|
55
|
+
## Powerful Insights:** Understand what ran, how fast, and what failed.
|
56
|
+
**Quiet by Default:** Focus on what matters, and reveal detail only when needed.
|
57
|
+
|
58
|
+
# Quick Start
|
59
|
+
**Install:**
|
60
|
+
```bash
|
61
|
+
pip install runem
|
62
|
+
```
|
63
|
+
**Define a task:**
|
64
|
+
|
65
|
+
```yaml
|
66
|
+
`# .runem.yml
|
67
|
+
- job:
|
68
|
+
command: echo "hello world!"
|
69
|
+
```
|
70
|
+
|
71
|
+
**Run:**
|
72
|
+
|
73
|
+
```bash
|
74
|
+
runem
|
75
|
+
```
|
76
|
+
|
77
|
+
Run multiple commands in parallel, see timing, and keep output minimal. Need detail?
|
78
|
+
|
79
|
+
```bash
|
80
|
+
runem --verbose
|
81
|
+
```
|
82
|
+
|
83
|
+
[Quick Start Docs](https://lursight.github.io/runem/docs/quick_start.html)
|
84
|
+
|
85
|
+
# Basic Use
|
86
|
+
|
87
|
+
Get comfortable with typical workflows:
|
88
|
+
[Basic Use Docs](https://lursight.github.io/runem/docs/basic_use.html)
|
89
|
+
|
90
|
+
# Advanced Use
|
91
|
+
|
92
|
+
Scale up with multi-phase configs, filtered execution, and custom reporting:
|
93
|
+
[Advanced Configuration](https://lursight.github.io/runem/docs/configuration.html)
|
94
|
+
[Custom Reporting](https://lursight.github.io/runem/docs/reports.html)
|
95
|
+
|
96
|
+
# Help & Discovery
|
97
|
+
|
98
|
+
`runem --help` is your radar—instantly mapping out every available task:
|
99
|
+
[Help & Job Discovery](https://lursight.github.io/runem/docs/help_and_job_discovery.html)
|
100
|
+
|
101
|
+
# Troubleshooting
|
102
|
+
|
103
|
+
Swift solutions to common issues:
|
104
|
+
[Troubleshooting & Known Issues](https://lursight.github.io/runem/docs/troubleshooting_known_issues.html)
|
105
|
+
|
106
|
+
---
|
107
|
+
|
108
|
+
# Contribute & Support
|
109
|
+
|
110
|
+
Brought to you by [Lursight Ltd.](https://lursight.com) and an open community.
|
111
|
+
[CONTRIBUTING.md](CONTRIBUTING.md)
|
112
|
+
[❤️ Sponsor](https://github.com/sponsors/lursight/)
|
113
|
+
|
114
|
+
# About Run’em
|
115
|
+
|
116
|
+
Run’em exists to accelerate your team’s delivery and reduce complexity. Learn about our [Mission](https://lursight.github.io/runem/docs/mission.html).
|
117
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
[build-system]
|
2
|
+
requires = ["setuptools>=42", "wheel"]
|
3
|
+
build-backend = "setuptools.build_meta"
|
4
|
+
|
5
|
+
[project]
|
6
|
+
name = "runem"
|
7
|
+
description = "Awesome runem created by lursight"
|
8
|
+
readme = "README.md"
|
9
|
+
requires-python = ">=3.7"
|
10
|
+
authors = [
|
11
|
+
{ name = "lursight" }
|
12
|
+
]
|
13
|
+
license = { text = "Specify your license here" }
|
14
|
+
keywords = ["example", "runem"]
|
15
|
+
classifiers = [
|
16
|
+
"Programming Language :: Python :: 3.7",
|
17
|
+
"Programming Language :: Python :: 3.8",
|
18
|
+
"Programming Language :: Python :: 3.9",
|
19
|
+
"Programming Language :: Python :: 3.10",
|
20
|
+
"Programming Language :: Python :: 3.11",
|
21
|
+
]
|
22
|
+
|
23
|
+
dependencies = [
|
24
|
+
# `packaging` is probably not needed after moving to pyproject.toml
|
25
|
+
"packaging>=22.0",
|
26
|
+
"PyYAML>=5.0.0",
|
27
|
+
|
28
|
+
# For UI Elements
|
29
|
+
"rich>10.0.0",
|
30
|
+
|
31
|
+
# For pre python3.12 Unpack features we need the `typing_extensions` module to
|
32
|
+
# be installed.
|
33
|
+
"typing_extensions>3.0.0",
|
34
|
+
]
|
35
|
+
dynamic = ["version"]
|
36
|
+
|
37
|
+
[project.urls]
|
38
|
+
Homepage = "https://github.com/lursight/runem/"
|
39
|
+
|
40
|
+
[tool.setuptools.packages.find]
|
41
|
+
exclude = ["tests", ".github"]
|
42
|
+
|
43
|
+
[project.scripts]
|
44
|
+
runem = "runem.__main__:main"
|
45
|
+
|
46
|
+
[tool.setuptools.package-data]
|
47
|
+
runem = ["VERSION"]
|
48
|
+
|
49
|
+
[project.optional-dependencies]
|
50
|
+
tests = [
|
51
|
+
# This requirements are for development and testing only, not for production.
|
52
|
+
"black==24.10.0",
|
53
|
+
"coverage==7.5",
|
54
|
+
"docformatter==1.7.5",
|
55
|
+
"flake8-bugbear==24.2.6",
|
56
|
+
"flake8==7.0.0",
|
57
|
+
"gitchangelog==3.0.4",
|
58
|
+
"isort==5.13.2",
|
59
|
+
"mkdocs==1.5.3",
|
60
|
+
"mypy==1.9.0",
|
61
|
+
"pydocstyle==6.3.0",
|
62
|
+
"pylint==3.1.0",
|
63
|
+
"pylama==8.4.1",
|
64
|
+
"pytest-cov==6.0.0",
|
65
|
+
"pytest-profiling==1.7.0",
|
66
|
+
"pytest-xdist==3.6.1",
|
67
|
+
"pytest==8.3.3",
|
68
|
+
"setuptools",
|
69
|
+
"termplotlib==0.3.9",
|
70
|
+
"tox",
|
71
|
+
"types-PyYAML==6.0.12.20240311",
|
72
|
+
"requests-mock==1.11.0",
|
73
|
+
"types-setuptools",
|
74
|
+
]
|
@@ -0,0 +1 @@
|
|
1
|
+
0.6.0
|
@@ -13,7 +13,14 @@ def _reset_console() -> Console:
|
|
13
13
|
|
14
14
|
RICH_CONSOLE = Console(
|
15
15
|
log_path=False, # Do NOT print the source path.
|
16
|
-
markup
|
16
|
+
# We allow markup here, BUT stdout/stderr from other procs should have
|
17
|
+
# `escape()` called on them so they don't error here.
|
18
|
+
# This means 'rich' effects/colors can be judiciously applied:
|
19
|
+
# e.g. `[blink]Don't Panic![/blink]`.
|
20
|
+
markup=True,
|
21
|
+
# `highlight` is what colourises string and number in print() calls.
|
22
|
+
# We do not want this to be auto-magic.
|
23
|
+
highlight=False,
|
17
24
|
)
|
18
25
|
return RICH_CONSOLE
|
19
26
|
|
@@ -31,7 +38,8 @@ def _reset_console_for_tests() -> None:
|
|
31
38
|
RICH_CONSOLE = Console(
|
32
39
|
log_path=False, # Do NOT print the source path.
|
33
40
|
log_time=False, # Do not prefix with log time e.g. `[time] log message`.
|
34
|
-
markup=
|
41
|
+
markup=True, # Allow some markup e.g. `[blink]Don't Panic![/blink]`.
|
42
|
+
highlight=False,
|
35
43
|
width=999, # A very wide width.
|
36
44
|
)
|
37
45
|
|
@@ -53,6 +53,14 @@ def _get_argparse_help_formatter() -> typing.Any:
|
|
53
53
|
return argparse.HelpFormatter
|
54
54
|
|
55
55
|
|
56
|
+
def error_on_log_logic(verbose: bool, silent: bool) -> None:
|
57
|
+
"""Simply errors if we get logical inconsistencies in the logging-logic."""
|
58
|
+
if verbose and silent:
|
59
|
+
log("cannot parse '--verbose' and '--silent'")
|
60
|
+
# error exit
|
61
|
+
sys.exit(1)
|
62
|
+
|
63
|
+
|
56
64
|
def parse_args(
|
57
65
|
config_metadata: ConfigMetadata, argv: typing.List[str]
|
58
66
|
) -> ConfigMetadata:
|
@@ -130,7 +138,9 @@ def parse_args(
|
|
130
138
|
nargs="+",
|
131
139
|
default=config_metadata.all_job_tags,
|
132
140
|
help=(
|
133
|
-
|
141
|
+
# TODO: clarify the logic by which we add/remove jobs based on tags
|
142
|
+
# e.g. exclusive-in, union, x-or etc.
|
143
|
+
"Only run jobs with the given tags. "
|
134
144
|
f"Defaults to '{sorted(config_metadata.all_job_tags)}'."
|
135
145
|
),
|
136
146
|
required=False,
|
@@ -238,6 +248,16 @@ def parse_args(
|
|
238
248
|
required=False,
|
239
249
|
)
|
240
250
|
|
251
|
+
parser.add_argument(
|
252
|
+
"--silent",
|
253
|
+
"-s",
|
254
|
+
dest="silent",
|
255
|
+
action=argparse.BooleanOptionalAction,
|
256
|
+
default=False,
|
257
|
+
help=("Whether to show warning messages or not. "),
|
258
|
+
required=False,
|
259
|
+
)
|
260
|
+
|
241
261
|
parser.add_argument(
|
242
262
|
"--spinner",
|
243
263
|
dest="show_spinner",
|
@@ -271,6 +291,8 @@ def parse_args(
|
|
271
291
|
|
272
292
|
args = parser.parse_args(argv[1:])
|
273
293
|
|
294
|
+
error_on_log_logic(args.verbose, args.silent)
|
295
|
+
|
274
296
|
if args.show_root_path_and_exit:
|
275
297
|
log(str(config_metadata.cfg_filepath.parent), decorate=False)
|
276
298
|
# cleanly exit
|
@@ -149,6 +149,7 @@ def parse_job_config(
|
|
149
149
|
in_out_job_names: JobNames,
|
150
150
|
in_out_phases: JobPhases,
|
151
151
|
phase_order: OrderedPhases,
|
152
|
+
silent: bool = False,
|
152
153
|
) -> None:
|
153
154
|
"""Parses and validates a job-entry read in from disk.
|
154
155
|
|
@@ -208,6 +209,7 @@ def parse_job_config(
|
|
208
209
|
in_out_job_names,
|
209
210
|
in_out_phases,
|
210
211
|
phase_order,
|
212
|
+
warn_missing_phase=(not silent),
|
211
213
|
)
|
212
214
|
except KeyError as err:
|
213
215
|
raise ValueError(
|
@@ -215,8 +217,11 @@ def parse_job_config(
|
|
215
217
|
) from err
|
216
218
|
|
217
219
|
|
218
|
-
def parse_config(
|
219
|
-
config: Config,
|
220
|
+
def parse_config( # noqa: C901
|
221
|
+
config: Config,
|
222
|
+
cfg_filepath: pathlib.Path,
|
223
|
+
silent: bool = False,
|
224
|
+
hooks_only: bool = False,
|
220
225
|
) -> typing.Tuple[
|
221
226
|
Hooks, # hooks:
|
222
227
|
OrderedPhases, # phase_order:
|
@@ -282,7 +287,10 @@ def parse_config(
|
|
282
287
|
|
283
288
|
if not phase_order:
|
284
289
|
if not hooks_only:
|
285
|
-
|
290
|
+
if silent: # pragma: no cover
|
291
|
+
pass
|
292
|
+
else:
|
293
|
+
warn("phase ordering not configured! Runs will be non-deterministic!")
|
286
294
|
phase_order = tuple(job_phases)
|
287
295
|
|
288
296
|
# now parse out the job_configs
|
@@ -301,6 +309,7 @@ def parse_config(
|
|
301
309
|
in_out_job_names=job_names,
|
302
310
|
in_out_phases=job_phases,
|
303
311
|
phase_order=phase_order,
|
312
|
+
silent=silent,
|
304
313
|
)
|
305
314
|
return (
|
306
315
|
hooks,
|
@@ -341,7 +350,9 @@ def generate_config(
|
|
341
350
|
|
342
351
|
|
343
352
|
def _load_user_hooks_from_config(
|
344
|
-
user_config: Config,
|
353
|
+
user_config: Config,
|
354
|
+
cfg_filepath: pathlib.Path,
|
355
|
+
silent: bool,
|
345
356
|
) -> Hooks:
|
346
357
|
hooks: Hooks
|
347
358
|
(
|
@@ -353,7 +364,7 @@ def _load_user_hooks_from_config(
|
|
353
364
|
_,
|
354
365
|
_,
|
355
366
|
_,
|
356
|
-
) = parse_config(user_config, cfg_filepath, hooks_only=True)
|
367
|
+
) = parse_config(user_config, cfg_filepath, silent, hooks_only=True)
|
357
368
|
return hooks
|
358
369
|
|
359
370
|
|
@@ -361,6 +372,7 @@ def load_config_metadata(
|
|
361
372
|
config: Config,
|
362
373
|
cfg_filepath: pathlib.Path,
|
363
374
|
user_configs: typing.List[typing.Tuple[Config, pathlib.Path]],
|
375
|
+
silent: bool = False,
|
364
376
|
verbose: bool = False,
|
365
377
|
) -> ConfigMetadata:
|
366
378
|
hooks: Hooks
|
@@ -380,12 +392,14 @@ def load_config_metadata(
|
|
380
392
|
job_names,
|
381
393
|
job_phases,
|
382
394
|
tags,
|
383
|
-
) = parse_config(config, cfg_filepath)
|
395
|
+
) = parse_config(config, cfg_filepath, silent)
|
384
396
|
|
385
397
|
user_config: Config
|
386
398
|
user_config_path: pathlib.Path
|
387
399
|
for user_config, user_config_path in user_configs:
|
388
|
-
user_hooks: Hooks = _load_user_hooks_from_config(
|
400
|
+
user_hooks: Hooks = _load_user_hooks_from_config(
|
401
|
+
user_config, user_config_path, silent
|
402
|
+
)
|
389
403
|
if user_hooks:
|
390
404
|
if verbose:
|
391
405
|
log(f"hooks: loading user hooks from '{str(user_config_path)}'")
|
@@ -11,7 +11,7 @@ from runem.config_metadata import ConfigMetadata
|
|
11
11
|
from runem.informative_dict import ReadOnlyInformativeDict
|
12
12
|
from runem.job import Job
|
13
13
|
from runem.job_wrapper import get_job_wrapper
|
14
|
-
from runem.log import error, log
|
14
|
+
from runem.log import error, log, warn
|
15
15
|
from runem.types.common import FilePathList, JobTags
|
16
16
|
from runem.types.filters import FilePathListLookup
|
17
17
|
from runem.types.runem_config import JobConfig
|
@@ -50,7 +50,8 @@ def job_execute_inner(
|
|
50
50
|
|
51
51
|
if not file_list:
|
52
52
|
# no files to work on
|
53
|
-
|
53
|
+
if not config_metadata.args.silent:
|
54
|
+
warn(f"skipping job '{label}', no files for job")
|
54
55
|
return {
|
55
56
|
"job": (f"{label}: no files!", timedelta(0)),
|
56
57
|
"commands": [],
|