runem 0.4.0__tar.gz → 0.5.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.
Files changed (87) hide show
  1. {runem-0.4.0 → runem-0.5.0}/HISTORY.md +41 -0
  2. {runem-0.4.0 → runem-0.5.0}/PKG-INFO +15 -6
  3. runem-0.5.0/pyproject.toml +74 -0
  4. runem-0.5.0/runem/VERSION +1 -0
  5. {runem-0.4.0 → runem-0.5.0}/runem/command_line.py +23 -1
  6. {runem-0.4.0 → runem-0.5.0}/runem/config_parse.py +21 -7
  7. {runem-0.4.0 → runem-0.5.0}/runem/job_execute.py +3 -2
  8. {runem-0.4.0 → runem-0.5.0}/runem/runem.py +9 -2
  9. {runem-0.4.0 → runem-0.5.0}/runem.egg-info/PKG-INFO +15 -6
  10. {runem-0.4.0 → runem-0.5.0}/runem.egg-info/SOURCES.txt +8 -3
  11. {runem-0.4.0 → runem-0.5.0}/runem.egg-info/requires.txt +4 -4
  12. runem-0.5.0/runem.egg-info/top_level.txt +5 -0
  13. runem-0.5.0/scripts/test_hooks/json_validators.py +32 -0
  14. runem-0.5.0/scripts/test_hooks/py.py +292 -0
  15. runem-0.5.0/scripts/test_hooks/runem_hooks.py +19 -0
  16. runem-0.5.0/scripts/test_hooks/yarn.py +48 -0
  17. runem-0.5.0/setup.cfg +7 -0
  18. runem-0.5.0/tests/__init__.py +0 -0
  19. {runem-0.4.0 → runem-0.5.0}/tests/data/help_output.3.10.txt +15 -39
  20. {runem-0.4.0 → runem-0.5.0}/tests/data/help_output.3.11.txt +14 -37
  21. {runem-0.4.0 → runem-0.5.0}/tests/test_job_execute.py +18 -8
  22. {runem-0.4.0 → runem-0.5.0}/tests/test_runem.py +51 -18
  23. runem-0.5.0/tests/test_types/__init__.py +0 -0
  24. runem-0.4.0/requirements-test.txt +0 -23
  25. runem-0.4.0/requirements.txt +0 -9
  26. runem-0.4.0/runem/VERSION +0 -1
  27. runem-0.4.0/runem.egg-info/top_level.txt +0 -2
  28. runem-0.4.0/setup.cfg +0 -4
  29. runem-0.4.0/setup.py +0 -51
  30. {runem-0.4.0 → runem-0.5.0}/Containerfile +0 -0
  31. {runem-0.4.0 → runem-0.5.0}/LICENSE +0 -0
  32. {runem-0.4.0 → runem-0.5.0}/MANIFEST.in +0 -0
  33. {runem-0.4.0 → runem-0.5.0}/README.md +0 -0
  34. {runem-0.4.0 → runem-0.5.0}/runem/__init__.py +0 -0
  35. {runem-0.4.0 → runem-0.5.0}/runem/__main__.py +0 -0
  36. {runem-0.4.0 → runem-0.5.0}/runem/base.py +0 -0
  37. {runem-0.4.0 → runem-0.5.0}/runem/blocking_print.py +0 -0
  38. {runem-0.4.0 → runem-0.5.0}/runem/cli/initialise_options.py +0 -0
  39. {runem-0.4.0 → runem-0.5.0}/runem/cli.py +0 -0
  40. {runem-0.4.0 → runem-0.5.0}/runem/config.py +0 -0
  41. {runem-0.4.0 → runem-0.5.0}/runem/config_metadata.py +0 -0
  42. {runem-0.4.0 → runem-0.5.0}/runem/files.py +0 -0
  43. {runem-0.4.0 → runem-0.5.0}/runem/hook_manager.py +0 -0
  44. {runem-0.4.0 → runem-0.5.0}/runem/informative_dict.py +0 -0
  45. {runem-0.4.0 → runem-0.5.0}/runem/job.py +0 -0
  46. {runem-0.4.0 → runem-0.5.0}/runem/job_filter.py +0 -0
  47. {runem-0.4.0 → runem-0.5.0}/runem/job_runner_simple_command.py +0 -0
  48. {runem-0.4.0 → runem-0.5.0}/runem/job_wrapper.py +0 -0
  49. {runem-0.4.0 → runem-0.5.0}/runem/job_wrapper_python.py +0 -0
  50. {runem-0.4.0 → runem-0.5.0}/runem/log.py +0 -0
  51. {runem-0.4.0 → runem-0.5.0}/runem/py.typed +0 -0
  52. {runem-0.4.0 → runem-0.5.0}/runem/report.py +0 -0
  53. {runem-0.4.0 → runem-0.5.0}/runem/run_command.py +0 -0
  54. {runem-0.4.0 → runem-0.5.0}/runem/runem_version.py +0 -0
  55. {runem-0.4.0 → runem-0.5.0}/runem/types/__init__.py +0 -0
  56. {runem-0.4.0 → runem-0.5.0}/runem/types/common.py +0 -0
  57. {runem-0.4.0 → runem-0.5.0}/runem/types/errors.py +0 -0
  58. {runem-0.4.0 → runem-0.5.0}/runem/types/filters.py +0 -0
  59. {runem-0.4.0 → runem-0.5.0}/runem/types/hooks.py +0 -0
  60. {runem-0.4.0 → runem-0.5.0}/runem/types/options.py +0 -0
  61. {runem-0.4.0 → runem-0.5.0}/runem/types/runem_config.py +0 -0
  62. {runem-0.4.0 → runem-0.5.0}/runem/types/types_jobs.py +0 -0
  63. {runem-0.4.0 → runem-0.5.0}/runem/utils.py +0 -0
  64. {runem-0.4.0 → runem-0.5.0}/runem.egg-info/dependency_links.txt +0 -0
  65. {runem-0.4.0 → runem-0.5.0}/runem.egg-info/entry_points.txt +0 -0
  66. {runem-0.4.0/tests → runem-0.5.0/scripts/test_hooks}/__init__.py +0 -0
  67. /runem-0.4.0/tests/test_types/__init__.py → /runem-0.5.0/scripts/test_hooks/py.typed +0 -0
  68. {runem-0.4.0 → runem-0.5.0}/tests/cli/test_initialise_options.py +0 -0
  69. {runem-0.4.0 → runem-0.5.0}/tests/conftest.py +0 -0
  70. {runem-0.4.0 → runem-0.5.0}/tests/intentional_test_error.py +0 -0
  71. {runem-0.4.0 → runem-0.5.0}/tests/sanitise_reports_footer.py +0 -0
  72. {runem-0.4.0 → runem-0.5.0}/tests/test_base.py +0 -0
  73. {runem-0.4.0 → runem-0.5.0}/tests/test_blocking_print.py +0 -0
  74. {runem-0.4.0 → runem-0.5.0}/tests/test_cli.py +0 -0
  75. {runem-0.4.0 → runem-0.5.0}/tests/test_config.py +0 -0
  76. {runem-0.4.0 → runem-0.5.0}/tests/test_config_parse.py +0 -0
  77. {runem-0.4.0 → runem-0.5.0}/tests/test_files.py +0 -0
  78. {runem-0.4.0 → runem-0.5.0}/tests/test_hook_manager.py +0 -0
  79. {runem-0.4.0 → runem-0.5.0}/tests/test_informative_dict.py +0 -0
  80. {runem-0.4.0 → runem-0.5.0}/tests/test_job.py +0 -0
  81. {runem-0.4.0 → runem-0.5.0}/tests/test_job_filter.py +0 -0
  82. {runem-0.4.0 → runem-0.5.0}/tests/test_job_runner_simple_command.py +0 -0
  83. {runem-0.4.0 → runem-0.5.0}/tests/test_job_wrapper.py +0 -0
  84. {runem-0.4.0 → runem-0.5.0}/tests/test_job_wrapper_python.py +0 -0
  85. {runem-0.4.0 → runem-0.5.0}/tests/test_report.py +0 -0
  86. {runem-0.4.0 → runem-0.5.0}/tests/test_run_command.py +0 -0
  87. {runem-0.4.0 → runem-0.5.0}/tests/test_types/test_public_api.py +0 -0
@@ -4,6 +4,47 @@ Changelog
4
4
 
5
5
  (unreleased)
6
6
  ------------
7
+ - Merge pull request #71 from lursight/feat/pyproject. [Frank Harrison]
8
+
9
+ Feat/pyproject
10
+ - Feat(pyproject): changes how we chose to install deps during a runem
11
+ deps-install. [Frank Harrison]
12
+ - Feat(pyproject): tests the build works in ci/cd. [Frank Harrison]
13
+
14
+ I'd rather find out that this has failed before we get to the deploy-phase.
15
+ - Feat(pyproject): makes the version dynamic again, reading from the
16
+ VERSION file. [Frank Harrison]
17
+ - Feat(pyproject): ports setup.py to pyproject.toml, more future proof.
18
+ [Frank Harrison]
19
+
20
+ Makes the project more future-proof by moving to pyproject.
21
+ - Merge pull request #70 from lursight/chore/typo. [Frank Harrison]
22
+
23
+ chore(docs): improves the help comments for --tags options
24
+ - Chore(docs): improves the help comments for --tags options. [Frank
25
+ Harrison]
26
+ - Merge pull request #69 from lursight/feat/silent. [Frank Harrison]
27
+
28
+ Feat/silent
29
+ - Chore(pre-push): adds '--silent' option ahead of improving pre-push.
30
+ [Frank Harrison]
31
+ - Chore(pre-push): fixes typo in error. [Frank Harrison]
32
+ - Chore(help-test): updates the help text, I think after updating the
33
+ width in the test-render. [Frank Harrison]
34
+ - Merge pull request #68 from lursight/chore/yarn_update. [Frank
35
+ Harrison]
36
+
37
+ Chore/yarn update
38
+ - Chore(nodejs): try and enable corepack in ci/cd. [Frank Harrison]
39
+ - Chore(nodejs): refreshes the yarn deps lock file. [Frank Harrison]
40
+ - Chore(nodejs): removes the immutable options. [Frank Harrison]
41
+ - Chore(nodejs): updates the yarn tool version we prefer. [Frank
42
+ Harrison]
43
+
44
+
45
+ 0.4.0 (2024-12-03)
46
+ ------------------
47
+ - Release: version 0.4.0 🚀 [Frank Harrison]
7
48
  - Merge pull request #67 from lursight/feat/prettier_logging. [Frank
8
49
  Harrison]
9
50
 
@@ -1,15 +1,23 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: runem
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: Awesome runem created by lursight
5
- Home-page: https://github.com/lursight/runem/
6
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
7
15
  Description-Content-Type: text/markdown
8
16
  License-File: LICENSE
9
- Requires-Dist: packaging
10
- Requires-Dist: PyYAML
11
- Requires-Dist: rich
12
- Requires-Dist: typing_extensions
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
13
21
  Provides-Extra: tests
14
22
  Requires-Dist: black==24.10.0; extra == "tests"
15
23
  Requires-Dist: coverage==7.5; extra == "tests"
@@ -153,3 +161,4 @@ Read the [CONTRIBUTING.md](CONTRIBUTING.md) file.
153
161
  The runem mission is to improve developer velocity at
154
162
  [Lursight Ltd.](https://lursight.com), read more about the runem
155
163
  [mission](https://lursight.github.io/runem/docs/mission.html).
164
+
@@ -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.5.0
@@ -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
- "Only jobs with the given tags. "
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, cfg_filepath: pathlib.Path, hooks_only: bool = False
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
- warn("phase ordering not configured! Runs will be non-deterministic!")
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, cfg_filepath: pathlib.Path
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(user_config, user_config_path)
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
- log(f"WARNING: skipping job '{label}', no files for job")
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": [],
@@ -37,7 +37,7 @@ from rich.spinner import Spinner
37
37
  from rich.text import Text
38
38
 
39
39
  from runem.blocking_print import RICH_CONSOLE
40
- from runem.command_line import parse_args
40
+ from runem.command_line import error_on_log_logic, parse_args
41
41
  from runem.config import load_project_config, load_user_configs
42
42
  from runem.config_metadata import ConfigMetadata
43
43
  from runem.config_parse import load_config_metadata
@@ -67,12 +67,19 @@ def _determine_run_parameters(argv: typing.List[str]) -> ConfigMetadata:
67
67
 
68
68
  Return a ConfigMetadata object with all the required information.
69
69
  """
70
+
71
+ # Because we want to be able to show logging whilst parsing .runem.yml config, we
72
+ # need to check the state of the logging-verbosity switches here, manually, as well.
73
+ verbose = "--verbose" in argv
74
+ silent = ("--silent" in argv) or ("-s" in argv)
75
+ error_on_log_logic(verbose, silent)
76
+
70
77
  config: Config
71
78
  cfg_filepath: pathlib.Path
72
79
  config, cfg_filepath = load_project_config()
73
80
  user_configs: typing.List[typing.Tuple[Config, pathlib.Path]] = load_user_configs()
74
81
  config_metadata: ConfigMetadata = load_config_metadata(
75
- config, cfg_filepath, user_configs, verbose=("--verbose" in argv)
82
+ config, cfg_filepath, user_configs, silent, verbose=("--verbose" in argv)
76
83
  )
77
84
 
78
85
  # Now we parse the cli arguments extending them with information from the
@@ -1,15 +1,23 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: runem
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: Awesome runem created by lursight
5
- Home-page: https://github.com/lursight/runem/
6
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
7
15
  Description-Content-Type: text/markdown
8
16
  License-File: LICENSE
9
- Requires-Dist: packaging
10
- Requires-Dist: PyYAML
11
- Requires-Dist: rich
12
- Requires-Dist: typing_extensions
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
13
21
  Provides-Extra: tests
14
22
  Requires-Dist: black==24.10.0; extra == "tests"
15
23
  Requires-Dist: coverage==7.5; extra == "tests"
@@ -153,3 +161,4 @@ Read the [CONTRIBUTING.md](CONTRIBUTING.md) file.
153
161
  The runem mission is to improve developer velocity at
154
162
  [Lursight Ltd.](https://lursight.com), read more about the runem
155
163
  [mission](https://lursight.github.io/runem/docs/mission.html).
164
+
@@ -3,9 +3,8 @@ HISTORY.md
3
3
  LICENSE
4
4
  MANIFEST.in
5
5
  README.md
6
- requirements-test.txt
7
- requirements.txt
8
- setup.py
6
+ pyproject.toml
7
+ setup.cfg
9
8
  runem/VERSION
10
9
  runem/__init__.py
11
10
  runem/__main__.py
@@ -47,6 +46,12 @@ runem/types/hooks.py
47
46
  runem/types/options.py
48
47
  runem/types/runem_config.py
49
48
  runem/types/types_jobs.py
49
+ scripts/test_hooks/__init__.py
50
+ scripts/test_hooks/json_validators.py
51
+ scripts/test_hooks/py.py
52
+ scripts/test_hooks/py.typed
53
+ scripts/test_hooks/runem_hooks.py
54
+ scripts/test_hooks/yarn.py
50
55
  tests/__init__.py
51
56
  tests/conftest.py
52
57
  tests/intentional_test_error.py
@@ -1,7 +1,7 @@
1
- packaging
2
- PyYAML
3
- rich
4
- typing_extensions
1
+ packaging>=22.0
2
+ PyYAML>=5.0.0
3
+ rich>10.0.0
4
+ typing_extensions>3.0.0
5
5
 
6
6
  [tests]
7
7
  black==24.10.0
@@ -0,0 +1,5 @@
1
+ dist
2
+ docs
3
+ runem
4
+ scripts
5
+ tests
@@ -0,0 +1,32 @@
1
+ import pathlib
2
+
3
+ from typing_extensions import Unpack
4
+
5
+ from runem.run_command import run_command
6
+ from runem.types import FilePathList, JobKwargs
7
+
8
+
9
+ def _json_validate(
10
+ **kwargs: Unpack[JobKwargs],
11
+ ) -> None:
12
+ label = kwargs["label"]
13
+ json_files: FilePathList = kwargs["file_list"]
14
+ json_with_comments = (
15
+ "cspell.json",
16
+ "tsconfig.spec.json",
17
+ "launch.json",
18
+ "settings.json",
19
+ )
20
+ for json_file in json_files:
21
+ json_path = pathlib.Path(json_file)
22
+ if not json_path.exists():
23
+ raise RuntimeError(
24
+ f"could not find '{str(json_path)}, in {pathlib.Path('.').absolute()}"
25
+ )
26
+ if json_path.name in json_with_comments:
27
+ # until we use a validator that allows comments in json, skip these
28
+ continue
29
+
30
+ cmd = ["python", "-m", "json.tool", f"{json_file}"]
31
+ kwargs["label"] = f"{label} {json_file}"
32
+ run_command(cmd=cmd, **kwargs)