runem 0.1.0__tar.gz → 0.1.2__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 (79) hide show
  1. {runem-0.1.0 → runem-0.1.2}/HISTORY.md +71 -0
  2. {runem-0.1.0 → runem-0.1.2}/PKG-INFO +1 -1
  3. runem-0.1.2/runem/VERSION +1 -0
  4. {runem-0.1.0 → runem-0.1.2}/runem/cli/initialise_options.py +1 -1
  5. {runem-0.1.0 → runem-0.1.2}/runem/command_line.py +3 -1
  6. {runem-0.1.0 → runem-0.1.2}/runem/config.py +6 -1
  7. {runem-0.1.0 → runem-0.1.2}/runem/config_metadata.py +4 -10
  8. {runem-0.1.0 → runem-0.1.2}/runem/config_parse.py +5 -10
  9. {runem-0.1.0 → runem-0.1.2}/runem/files.py +1 -1
  10. {runem-0.1.0 → runem-0.1.2}/runem/hook_manager.py +5 -9
  11. {runem-0.1.0 → runem-0.1.2}/runem/job.py +3 -1
  12. {runem-0.1.0 → runem-0.1.2}/runem/job_execute.py +28 -17
  13. {runem-0.1.0 → runem-0.1.2}/runem/job_filter.py +2 -8
  14. {runem-0.1.0 → runem-0.1.2}/runem/job_runner_simple_command.py +1 -1
  15. {runem-0.1.0 → runem-0.1.2}/runem/job_wrapper.py +2 -1
  16. {runem-0.1.0 → runem-0.1.2}/runem/job_wrapper_python.py +3 -1
  17. {runem-0.1.0 → runem-0.1.2}/runem/report.py +2 -3
  18. {runem-0.1.0 → runem-0.1.2}/runem/runem.py +22 -48
  19. runem-0.1.2/runem/types/__init__.py +12 -0
  20. runem-0.1.2/runem/types/common.py +12 -0
  21. runem-0.1.2/runem/types/errors.py +4 -0
  22. runem-0.1.2/runem/types/filters.py +12 -0
  23. runem-0.1.2/runem/types/hooks.py +15 -0
  24. runem-0.1.2/runem/types/options.py +7 -0
  25. runem-0.1.2/runem/types/runem_config.py +164 -0
  26. runem-0.1.2/runem/types/types_jobs.py +156 -0
  27. {runem-0.1.0 → runem-0.1.2}/runem.egg-info/PKG-INFO +1 -1
  28. {runem-0.1.0 → runem-0.1.2}/runem.egg-info/SOURCES.txt +11 -2
  29. {runem-0.1.0 → runem-0.1.2}/runem.egg-info/top_level.txt +1 -0
  30. {runem-0.1.0 → runem-0.1.2}/tests/cli/test_initialise_options.py +1 -1
  31. {runem-0.1.0 → runem-0.1.2}/tests/test_config.py +1 -1
  32. {runem-0.1.0 → runem-0.1.2}/tests/test_config_parse.py +4 -7
  33. {runem-0.1.0 → runem-0.1.2}/tests/test_files.py +1 -1
  34. {runem-0.1.0 → runem-0.1.2}/tests/test_hook_manager.py +2 -1
  35. {runem-0.1.0 → runem-0.1.2}/tests/test_job.py +3 -1
  36. {runem-0.1.0 → runem-0.1.2}/tests/test_job_execute.py +3 -2
  37. {runem-0.1.0 → runem-0.1.2}/tests/test_job_filter.py +2 -1
  38. {runem-0.1.0 → runem-0.1.2}/tests/test_job_runner_simple_command.py +1 -1
  39. {runem-0.1.0 → runem-0.1.2}/tests/test_job_wrapper.py +2 -1
  40. {runem-0.1.0 → runem-0.1.2}/tests/test_job_wrapper_python.py +3 -1
  41. {runem-0.1.0 → runem-0.1.2}/tests/test_report.py +2 -2
  42. {runem-0.1.0 → runem-0.1.2}/tests/test_runem.py +13 -10
  43. runem-0.1.2/tests/test_types/__init__.py +0 -0
  44. runem-0.1.2/tests/test_types/test_public_api.py +3 -0
  45. runem-0.1.0/runem/VERSION +0 -1
  46. runem-0.1.0/runem/types.py +0 -357
  47. {runem-0.1.0 → runem-0.1.2}/Containerfile +0 -0
  48. {runem-0.1.0 → runem-0.1.2}/LICENSE +0 -0
  49. {runem-0.1.0 → runem-0.1.2}/MANIFEST.in +0 -0
  50. {runem-0.1.0 → runem-0.1.2}/README.md +0 -0
  51. {runem-0.1.0 → runem-0.1.2}/requirements-test.txt +0 -0
  52. {runem-0.1.0 → runem-0.1.2}/requirements.txt +0 -0
  53. {runem-0.1.0 → runem-0.1.2}/runem/__init__.py +0 -0
  54. {runem-0.1.0 → runem-0.1.2}/runem/__main__.py +0 -0
  55. {runem-0.1.0 → runem-0.1.2}/runem/base.py +0 -0
  56. {runem-0.1.0 → runem-0.1.2}/runem/blocking_print.py +0 -0
  57. {runem-0.1.0 → runem-0.1.2}/runem/cli.py +0 -0
  58. {runem-0.1.0 → runem-0.1.2}/runem/informative_dict.py +0 -0
  59. {runem-0.1.0 → runem-0.1.2}/runem/log.py +0 -0
  60. {runem-0.1.0 → runem-0.1.2}/runem/py.typed +0 -0
  61. {runem-0.1.0 → runem-0.1.2}/runem/run_command.py +0 -0
  62. {runem-0.1.0 → runem-0.1.2}/runem/runem_version.py +0 -0
  63. {runem-0.1.0 → runem-0.1.2}/runem/utils.py +0 -0
  64. {runem-0.1.0 → runem-0.1.2}/runem.egg-info/dependency_links.txt +0 -0
  65. {runem-0.1.0 → runem-0.1.2}/runem.egg-info/entry_points.txt +0 -0
  66. {runem-0.1.0 → runem-0.1.2}/runem.egg-info/requires.txt +0 -0
  67. {runem-0.1.0 → runem-0.1.2}/setup.cfg +0 -0
  68. {runem-0.1.0 → runem-0.1.2}/setup.py +0 -0
  69. {runem-0.1.0 → runem-0.1.2}/tests/__init__.py +0 -0
  70. {runem-0.1.0 → runem-0.1.2}/tests/conftest.py +0 -0
  71. {runem-0.1.0 → runem-0.1.2}/tests/data/help_output.3.10.txt +0 -0
  72. {runem-0.1.0 → runem-0.1.2}/tests/data/help_output.3.11.txt +0 -0
  73. {runem-0.1.0 → runem-0.1.2}/tests/intentional_test_error.py +0 -0
  74. {runem-0.1.0 → runem-0.1.2}/tests/sanitise_reports_footer.py +0 -0
  75. {runem-0.1.0 → runem-0.1.2}/tests/test_base.py +0 -0
  76. {runem-0.1.0 → runem-0.1.2}/tests/test_blocking_print.py +0 -0
  77. {runem-0.1.0 → runem-0.1.2}/tests/test_cli.py +0 -0
  78. {runem-0.1.0 → runem-0.1.2}/tests/test_informative_dict.py +0 -0
  79. {runem-0.1.0 → runem-0.1.2}/tests/test_run_command.py +0 -0
@@ -4,6 +4,77 @@ Changelog
4
4
 
5
5
  (unreleased)
6
6
  ------------
7
+ - Chore(actions): simplifies code paths for actions. [Frank Harrison]
8
+ - Chore(contrib): removes the Makefile commands that have been removed.
9
+ [Frank Harrison]
10
+
11
+ .. this should have been in the last PR.
12
+ - Chore(contrib): update the CONTRIBUTING docs and removes defunct
13
+ scripts from Makefile. [Frank Harrison]
14
+ - Chore(faster-actions): removes redundant github actions. [Frank
15
+ Harrison]
16
+
17
+ This should speed up github actions, but it may lead to more false-positives as we are relying on runem to be working and realiabel to run our own checks....
18
+
19
+ This could come back to bite us.
20
+ - Chore(extra-ctx): adds config_metadata to job kw-args. [Frank
21
+ Harrison]
22
+
23
+ This allows much greater depth of testing based on other jobs-inclusion and metadata.
24
+ - Chore(extra-ctx): moves the job-task calling to use kwargs explicitly.
25
+ [Frank Harrison]
26
+ - Chore(extra-ctx): sort kwargs passed to jobs. [Frank Harrison]
27
+ - Merge pull request #59 from lursight/chore/cleaner_type_exports.
28
+ [Frank Harrison]
29
+
30
+ Chore/cleaner type exports
31
+ - Chore(clean-types): fixes false-negative from 'isort --check' [Frank
32
+ Harrison]
33
+ - Chore(clean-types): makes the public_api the actual exported api of
34
+ the types module. [Frank Harrison]
35
+
36
+ I think this could be better
37
+ - Chore(clean-types): renames type_wip -> types. [Frank Harrison]
38
+ - Chore(clean-types): fixes up more of the test-hooks (badly named) for
39
+ runem itself. [Frank Harrison]
40
+ - Chore(clean-types): splits out the rest of the types. [Frank Harrison]
41
+ - Chore(clean-types): moves config and serialisationtypes to own file.
42
+ [Frank Harrison]
43
+ - Chore(clean-types): moves error into new errors.py types file. [Frank
44
+ Harrison]
45
+ - Chore(clean-types): starts moving some types into 'common' [Frank
46
+ Harrison]
47
+ - Chore(clean-types): moves the types into types/wip whilst I work out
48
+ the public API. [Frank Harrison]
49
+ - Chore(clean-types): splits out the job and hook execution types, ahead
50
+ of building a better public api for type exports. [Frank Harrison]
51
+ - Chore(clean-types): sorts the job kwargs. [Frank Harrison]
52
+
53
+
54
+ 0.1.1 (2024-11-17)
55
+ ------------------
56
+ - Release: version 0.1.1 🚀 [Frank Harrison]
57
+ - Merge pull request #58 from lursight/fix/completed_job_counts. [Frank
58
+ Harrison]
59
+
60
+ fix(complete-job-count): fixes and simplifies the in-progress report code
61
+ - Fix(complete-job-count): fixes and simplifies the in-progress report
62
+ code. [Frank Harrison]
63
+
64
+ The core problem was that the remaining-job-count didn't match the
65
+ number of job-labels that were being shown.
66
+
67
+ The root-cause was due to some of the job-tasks completing before the
68
+ `_update_progress()` thread had started monitoring the jobs.
69
+
70
+ We fix this by adding a new parameter to the job-executer that tracks
71
+ when job completed. It's a very simple fix and reduces the overall
72
+ complexity for about the same cost of threading-primitives.
73
+
74
+
75
+ 0.1.0 (2024-11-17)
76
+ ------------------
77
+ - Release: version 0.1.0 🚀 [Frank Harrison]
7
78
  - Merge pull request #57 from lursight/feat/replace_halo_with_rich.
8
79
  [Frank Harrison]
9
80
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: runem
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Awesome runem created by lursight
5
5
  Home-page: https://github.com/lursight/runem/
6
6
  Author: lursight
@@ -0,0 +1 @@
1
+ 0.1.2
@@ -2,7 +2,7 @@ import argparse
2
2
 
3
3
  from runem.config_metadata import ConfigMetadata
4
4
  from runem.informative_dict import InformativeDict
5
- from runem.types import OptionsWritable
5
+ from runem.types.options import OptionsWritable
6
6
 
7
7
 
8
8
  def initialise_options(
@@ -8,7 +8,9 @@ from runem.config_metadata import ConfigMetadata
8
8
  from runem.informative_dict import InformativeDict
9
9
  from runem.log import error, log
10
10
  from runem.runem_version import get_runem_version
11
- from runem.types import JobNames, OptionConfig, OptionsWritable
11
+ from runem.types.common import JobNames
12
+ from runem.types.options import OptionsWritable
13
+ from runem.types.runem_config import OptionConfig
12
14
  from runem.utils import printable_set
13
15
 
14
16
 
@@ -7,7 +7,12 @@ from packaging.version import Version
7
7
 
8
8
  from runem.log import error, log
9
9
  from runem.runem_version import get_runem_version
10
- from runem.types import Config, GlobalConfig, GlobalSerialisedConfig, UserConfigMetadata
10
+ from runem.types.runem_config import (
11
+ Config,
12
+ GlobalConfig,
13
+ GlobalSerialisedConfig,
14
+ UserConfigMetadata,
15
+ )
11
16
 
12
17
  CFG_FILE_YAML = pathlib.Path(".runem.yml")
13
18
 
@@ -3,16 +3,10 @@ import pathlib
3
3
  import typing
4
4
 
5
5
  from runem.informative_dict import InformativeDict
6
- from runem.types import (
7
- JobNames,
8
- JobPhases,
9
- JobTags,
10
- OptionConfigs,
11
- OptionsWritable,
12
- OrderedPhases,
13
- PhaseGroupedJobs,
14
- TagFileFilters,
15
- )
6
+ from runem.types.common import JobNames, JobPhases, JobTags, OrderedPhases
7
+ from runem.types.filters import TagFileFilters
8
+ from runem.types.options import OptionsWritable
9
+ from runem.types.runem_config import OptionConfigs, PhaseGroupedJobs
16
10
 
17
11
  if typing.TYPE_CHECKING: # pragma: no cover
18
12
  from runem.hook_manager import HookManager
@@ -10,28 +10,23 @@ from runem.hook_manager import HookManager
10
10
  from runem.job import Job
11
11
  from runem.job_wrapper import get_job_wrapper
12
12
  from runem.log import error, log, warn
13
- from runem.types import (
13
+ from runem.types.common import JobNames, JobPhases, JobTags, OrderedPhases, PhaseName
14
+ from runem.types.errors import FunctionNotFound
15
+ from runem.types.filters import TagFileFilter, TagFileFilters
16
+ from runem.types.hooks import HookName
17
+ from runem.types.runem_config import (
14
18
  Config,
15
19
  ConfigNodes,
16
- FunctionNotFound,
17
20
  GlobalConfig,
18
21
  GlobalSerialisedConfig,
19
22
  HookConfig,
20
- HookName,
21
23
  Hooks,
22
24
  HookSerialisedConfig,
23
25
  JobConfig,
24
- JobNames,
25
- JobPhases,
26
26
  JobSerialisedConfig,
27
- JobTags,
28
27
  JobWhen,
29
28
  OptionConfigs,
30
- OrderedPhases,
31
29
  PhaseGroupedJobs,
32
- PhaseName,
33
- TagFileFilter,
34
- TagFileFilters,
35
30
  TagFileFilterSerialised,
36
31
  )
37
32
 
@@ -5,7 +5,7 @@ from pathlib import Path
5
5
  from subprocess import check_output as subprocess_check_output
6
6
 
7
7
  from runem.config_metadata import ConfigMetadata
8
- from runem.types import FilePathListLookup
8
+ from runem.types.filters import FilePathListLookup
9
9
 
10
10
 
11
11
  def find_files(config_metadata: ConfigMetadata) -> FilePathListLookup:
@@ -7,15 +7,10 @@ from runem.config_metadata import ConfigMetadata
7
7
  from runem.job import Job
8
8
  from runem.job_execute import job_execute
9
9
  from runem.log import log
10
- from runem.types import (
11
- FilePathListLookup,
12
- HookConfig,
13
- HookName,
14
- Hooks,
15
- HookSpecificKwargs,
16
- HooksStore,
17
- JobConfig,
18
- )
10
+ from runem.types.filters import FilePathListLookup
11
+ from runem.types.hooks import HookName
12
+ from runem.types.runem_config import HookConfig, Hooks, HooksStore, JobConfig
13
+ from runem.types.types_jobs import HookSpecificKwargs
19
14
 
20
15
 
21
16
  class HookManager:
@@ -95,6 +90,7 @@ class HookManager:
95
90
  job_execute(
96
91
  job_config,
97
92
  running_jobs={},
93
+ completed_jobs={},
98
94
  config_metadata=config_metadata,
99
95
  file_lists=file_lists,
100
96
  **kwargs,
@@ -1,6 +1,8 @@
1
1
  import typing
2
2
 
3
- from runem.types import FilePathList, FilePathListLookup, JobConfig, JobTags, JobWhen
3
+ from runem.types.common import FilePathList, JobTags
4
+ from runem.types.filters import FilePathListLookup
5
+ from runem.types.runem_config import JobConfig, JobWhen
4
6
 
5
7
 
6
8
  class NoJobName(ValueError):
@@ -12,14 +12,15 @@ from runem.informative_dict import ReadOnlyInformativeDict
12
12
  from runem.job import Job
13
13
  from runem.job_wrapper import get_job_wrapper
14
14
  from runem.log import error, log
15
- from runem.types import (
16
- FilePathList,
17
- FilePathListLookup,
15
+ from runem.types.common import FilePathList, JobTags
16
+ from runem.types.filters import FilePathListLookup
17
+ from runem.types.runem_config import JobConfig
18
+ from runem.types.types_jobs import (
19
+ AllKwargs,
18
20
  HookSpecificKwargs,
19
- JobConfig,
20
21
  JobFunction,
22
+ JobKwargs,
21
23
  JobReturn,
22
- JobTags,
23
24
  JobTiming,
24
25
  TimingEntries,
25
26
  TimingEntry,
@@ -80,19 +81,27 @@ def job_execute_inner(
80
81
  log(f"job: running: '{Job.get_job_name(job_config)}'")
81
82
  reports: JobReturn
82
83
  try:
83
- assert isinstance(function, JobFunction)
84
- reports = function(
85
- options=ReadOnlyInformativeDict(config_metadata.options),
86
- file_list=file_list,
87
- procs=config_metadata.args.procs,
88
- root_path=root_path,
89
- verbose=config_metadata.args.verbose,
90
- # unpack useful data points from the job_config
91
- label=Job.get_job_name(job_config),
92
- job=job_config,
93
- record_sub_job_time=_record_sub_job_time,
84
+ # Define the common args for all jobs and hooks.
85
+ job_k_args: JobKwargs = {
86
+ "config_metadata": config_metadata,
87
+ "file_list": file_list,
88
+ "job": job_config,
89
+ "label": Job.get_job_name(job_config),
90
+ "options": ReadOnlyInformativeDict(config_metadata.options),
91
+ "procs": config_metadata.args.procs,
92
+ "record_sub_job_time": _record_sub_job_time,
93
+ "root_path": root_path,
94
+ "verbose": config_metadata.args.verbose,
95
+ }
96
+ # Merge in the hook-specific kwargs (if any) for situations where we are
97
+ # calling hooks.
98
+ all_k_args: AllKwargs = {
99
+ **job_k_args,
94
100
  **kwargs,
95
- )
101
+ }
102
+
103
+ assert isinstance(function, JobFunction)
104
+ reports = function(**all_k_args)
96
105
  except BaseException: # pylint: disable=broad-exception-caught
97
106
  # log that we hit an error on this job and re-raise
98
107
  log(decorate=False)
@@ -111,6 +120,7 @@ def job_execute_inner(
111
120
  def job_execute(
112
121
  job_config: JobConfig,
113
122
  running_jobs: typing.Dict[str, str],
123
+ completed_jobs: typing.Dict[str, str],
114
124
  config_metadata: ConfigMetadata,
115
125
  file_lists: FilePathListLookup,
116
126
  **kwargs: Unpack[HookSpecificKwargs],
@@ -127,5 +137,6 @@ def job_execute(
127
137
  file_lists,
128
138
  **kwargs,
129
139
  )
140
+ completed_jobs[this_id] = running_jobs[this_id]
130
141
  del running_jobs[this_id]
131
142
  return results
@@ -4,14 +4,8 @@ from collections import defaultdict
4
4
  from runem.config_metadata import ConfigMetadata
5
5
  from runem.job import Job
6
6
  from runem.log import log
7
- from runem.types import (
8
- JobConfig,
9
- JobNames,
10
- JobPhases,
11
- JobTags,
12
- PhaseGroupedJobs,
13
- PhaseName,
14
- )
7
+ from runem.types.common import JobNames, JobPhases, JobTags, PhaseName
8
+ from runem.types.runem_config import JobConfig, PhaseGroupedJobs
15
9
  from runem.utils import printable_set
16
10
 
17
11
 
@@ -2,7 +2,7 @@ import shlex
2
2
  import typing
3
3
 
4
4
  from runem.run_command import run_command
5
- from runem.types import JobConfig
5
+ from runem.types.runem_config import JobConfig
6
6
 
7
7
 
8
8
  def validate_simple_command(command_string: str) -> typing.List[str]:
@@ -5,7 +5,8 @@ from runem.job_runner_simple_command import (
5
5
  validate_simple_command,
6
6
  )
7
7
  from runem.job_wrapper_python import get_job_wrapper_py_func
8
- from runem.types import JobFunction, JobWrapper
8
+ from runem.types.runem_config import JobWrapper
9
+ from runem.types.types_jobs import JobFunction
9
10
 
10
11
 
11
12
  def get_job_wrapper(job_wrapper: JobWrapper, cfg_filepath: pathlib.Path) -> JobFunction:
@@ -3,7 +3,9 @@ import sys
3
3
  from importlib.util import module_from_spec
4
4
  from importlib.util import spec_from_file_location as module_spec_from_file_location
5
5
 
6
- from runem.types import FunctionNotFound, JobFunction, JobWrapper
6
+ from runem.types.errors import FunctionNotFound
7
+ from runem.types.runem_config import JobWrapper
8
+ from runem.types.types_jobs import JobFunction
7
9
 
8
10
 
9
11
  def _load_python_function_from_module(
@@ -4,14 +4,13 @@ from collections import defaultdict
4
4
  from datetime import timedelta
5
5
 
6
6
  from runem.log import log
7
- from runem.types import (
7
+ from runem.types.common import OrderedPhases, PhaseName
8
+ from runem.types.types_jobs import (
8
9
  JobReturn,
9
10
  JobRunMetadatasByPhase,
10
11
  JobRunReportByPhase,
11
12
  JobRunTimesByPhase,
12
13
  JobTiming,
13
- OrderedPhases,
14
- PhaseName,
15
14
  ReportUrlInfo,
16
15
  ReportUrls,
17
16
  TimingEntries,
@@ -28,7 +28,7 @@ import typing
28
28
  from collections import defaultdict
29
29
  from datetime import timedelta
30
30
  from itertools import repeat
31
- from multiprocessing.managers import DictProxy, ListProxy, ValueProxy
31
+ from multiprocessing.managers import DictProxy, ValueProxy
32
32
  from timeit import default_timer as timer
33
33
  from types import TracebackType
34
34
 
@@ -41,23 +41,19 @@ from runem.config import load_project_config, load_user_configs
41
41
  from runem.config_metadata import ConfigMetadata
42
42
  from runem.config_parse import load_config_metadata
43
43
  from runem.files import find_files
44
- from runem.job import Job
45
44
  from runem.job_execute import job_execute
46
45
  from runem.job_filter import filter_jobs
47
46
  from runem.log import error, log, warn
48
47
  from runem.report import report_on_run
49
- from runem.types import (
50
- Config,
51
- FilePathListLookup,
52
- HookName,
48
+ from runem.types.common import OrderedPhases, PhaseName
49
+ from runem.types.filters import FilePathListLookup
50
+ from runem.types.hooks import HookName
51
+ from runem.types.runem_config import Config, Jobs, PhaseGroupedJobs
52
+ from runem.types.types_jobs import (
53
53
  JobReturn,
54
54
  JobRunMetadata,
55
55
  JobRunMetadatasByPhase,
56
- Jobs,
57
56
  JobTiming,
58
- OrderedPhases,
59
- PhaseGroupedJobs,
60
- PhaseName,
61
57
  )
62
58
  from runem.utils import printable_set
63
59
 
@@ -123,7 +119,7 @@ class DummySpinner(ConsoleRenderable): # pragma: no cover
123
119
  def _update_progress(
124
120
  label: str,
125
121
  running_jobs: typing.Dict[str, str],
126
- seen_jobs: typing.List[str],
122
+ completed_jobs: typing.Dict[str, str],
127
123
  all_jobs: Jobs,
128
124
  is_running: ValueProxy[bool],
129
125
  num_workers: int,
@@ -134,7 +130,6 @@ def _update_progress(
134
130
  Args:
135
131
  label (str): The identifier.
136
132
  running_jobs (Dict[str, str]): The currently running jobs.
137
- seen_jobs (List[str]): Jobs that the function has previously tracked.
138
133
  all_jobs (Jobs): All jobs, encompassing both completed and running jobs.
139
134
  is_running (ValueProxy[bool]): Flag indicating if jobs are still running.
140
135
  num_workers (int): Indicates the number of workers performing the jobs.
@@ -146,47 +141,25 @@ def _update_progress(
146
141
  else:
147
142
  spinner = DummySpinner()
148
143
 
149
- with rich_console.status(spinner):
150
-
151
- # The set of all job labels, and the set of completed jobs
152
- all_job_names: typing.Set[str] = {Job.get_job_name(job) for job in all_jobs}
153
- completed_jobs: typing.Set[str] = set()
154
-
155
- # This dataset is used to track changes between iterations
156
- last_running_jobs_set: typing.Set[str] = set()
144
+ last_running_jobs_set: typing.Set[str] = set()
157
145
 
146
+ with rich_console.status(spinner):
158
147
  while is_running.value:
159
148
  running_jobs_set: typing.Set[str] = set(running_jobs.values())
160
- seen_jobs = list(running_jobs_set.union(seen_jobs)) # Update the seen jobs
161
-
162
- # Jobs that have disappeared since last check
163
- disappeared_jobs: typing.Set[str] = last_running_jobs_set - running_jobs_set
164
-
165
- # Jobs that have not yet completed
166
- remaining_jobs: typing.Set[str] = all_job_names - completed_jobs
167
149
 
168
- # Check if we're closing to completion
169
- workers_retiring: bool = len(remaining_jobs) <= num_workers
170
-
171
- if workers_retiring:
172
- # Handle edge case: a task may have disappeared whilst process was sleeping
173
- all_completed_jobs: typing.Set[str] = all_job_names - remaining_jobs
174
- disappeared_jobs.update(all_completed_jobs - running_jobs_set)
175
-
176
- completed_jobs.update(disappeared_jobs)
177
-
178
- # Prepare progress report
150
+ # Progress report
179
151
  progress: str = f"{len(completed_jobs)}/{len(all_jobs)}"
180
- running_jobs_list = printable_set(running_jobs_set)
152
+ running_jobs_list = printable_set(
153
+ running_jobs_set
154
+ ) # Reflect current running jobs accurately
155
+ report: str = f"{label}: {progress}({num_workers}): {running_jobs_list}"
181
156
  if show_spinner:
182
- spinner.text = (
183
- f"{label}: {progress}({num_workers}): {running_jobs_list}"
184
- )
185
-
186
- # Update the tracked dataset for the next iteration
187
- last_running_jobs_set = running_jobs_set
157
+ spinner.text = report
158
+ else:
159
+ if last_running_jobs_set != running_jobs_set:
160
+ rich_console.log(report)
188
161
 
189
- # Sleep to decrease frequency of updates and reduce CPU usage
162
+ # Sleep for reduced CPU usage
190
163
  time.sleep(0.1)
191
164
 
192
165
 
@@ -225,8 +198,8 @@ def _process_jobs(
225
198
  subprocess_error: typing.Optional[BaseException] = None
226
199
 
227
200
  with multiprocessing.Manager() as manager:
228
- seen_jobs: ListProxy[str] = manager.list()
229
201
  running_jobs: DictProxy[typing.Any, typing.Any] = manager.dict()
202
+ completed_jobs: DictProxy[typing.Any, typing.Any] = manager.dict()
230
203
  is_running: ValueProxy[bool] = manager.Value("b", True)
231
204
 
232
205
  terminal_writer_process = multiprocessing.Process(
@@ -234,7 +207,7 @@ def _process_jobs(
234
207
  args=(
235
208
  phase,
236
209
  running_jobs,
237
- seen_jobs,
210
+ completed_jobs,
238
211
  jobs,
239
212
  is_running,
240
213
  num_concurrent_procs,
@@ -251,6 +224,7 @@ def _process_jobs(
251
224
  zip(
252
225
  jobs,
253
226
  repeat(running_jobs),
227
+ repeat(completed_jobs),
254
228
  repeat(config_metadata),
255
229
  repeat(file_lists),
256
230
  ),
@@ -0,0 +1,12 @@
1
+ from runem.types.common import FilePathList, JobName
2
+ from runem.types.options import Options
3
+ from runem.types.types_jobs import HookKwargs, JobKwargs, JobReturnData
4
+
5
+ __all__ = [
6
+ "FilePathList",
7
+ "HookKwargs",
8
+ "JobName",
9
+ "JobReturnData",
10
+ "Options",
11
+ "JobKwargs",
12
+ ]
@@ -0,0 +1,12 @@
1
+ import typing
2
+
3
+ # meta-data types
4
+ JobName = str
5
+ JobTag = str
6
+ JobNames = typing.Set[JobName]
7
+ JobPhases = typing.Set[str]
8
+ JobTags = typing.Set[JobTag]
9
+ PhaseName = str
10
+ OrderedPhases = typing.Tuple[PhaseName, ...]
11
+ FilePathSerialise = str
12
+ FilePathList = typing.List[FilePathSerialise]
@@ -0,0 +1,4 @@
1
+ class FunctionNotFound(ValueError):
2
+ """Thrown when the test-function cannot be found."""
3
+
4
+ pass
@@ -0,0 +1,12 @@
1
+ import typing
2
+
3
+ from runem.types.common import FilePathList, JobTag
4
+
5
+
6
+ class TagFileFilter(typing.TypedDict):
7
+ tag: JobTag
8
+ regex: str
9
+
10
+
11
+ TagFileFilters = typing.Dict[JobTag, TagFileFilter]
12
+ FilePathListLookup = typing.DefaultDict[JobTag, FilePathList]
@@ -0,0 +1,15 @@
1
+ import enum
2
+
3
+
4
+ class HookName(enum.Enum):
5
+ """List supported hooks.
6
+
7
+ TODO:
8
+ - before all tasks are run, after config is read
9
+ - BEFORE_ALL = "before-all"
10
+ - after all tasks are done, before reporting
11
+ - AFTER_ALL = "after-all"
12
+ """
13
+
14
+ # at exit
15
+ ON_EXIT = "on-exit"
@@ -0,0 +1,7 @@
1
+ from runem.informative_dict import InformativeDict, ReadOnlyInformativeDict
2
+
3
+ OptionName = str
4
+ OptionValue = bool
5
+ OptionsWritable = InformativeDict[OptionName, OptionValue]
6
+ OptionsReadOnly = ReadOnlyInformativeDict[OptionName, OptionValue]
7
+ Options = OptionsReadOnly