dv-flow-mgr 0.0.1.13577785562a1__tar.gz → 0.0.1.13657597614a1__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 (103) hide show
  1. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/PKG-INFO +1 -1
  2. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/Steps.md +27 -0
  3. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/pyproject.toml +1 -1
  4. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/__init__.py +1 -0
  5. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/package_def.py +107 -128
  6. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/param_def.py +0 -1
  7. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/param_ref_eval.py +2 -2
  8. dv_flow_mgr-0.0.1.13657597614a1/src/dv_flow/mgr/std/exec.py +19 -0
  9. dv_flow_mgr-0.0.1.13657597614a1/src/dv_flow/mgr/std/fileset.py +75 -0
  10. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/std/flow.dv +11 -5
  11. dv_flow_mgr-0.0.1.13657597614a1/src/dv_flow/mgr/std/message.py +6 -0
  12. dv_flow_mgr-0.0.1.13657597614a1/src/dv_flow/mgr/std/task_null.py +9 -0
  13. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_data.py +1 -0
  14. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_def.py +4 -3
  15. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_graph_builder.py +17 -11
  16. dv_flow_mgr-0.0.1.13657597614a1/src/dv_flow/mgr/task_listener_log.py +15 -0
  17. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_node.py +120 -21
  18. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_runner.py +85 -6
  19. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow_mgr.egg-info/PKG-INFO +1 -1
  20. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow_mgr.egg-info/SOURCES.txt +2 -0
  21. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_pyclass.py +107 -42
  22. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_pytask_smoke.py +34 -38
  23. dv_flow_mgr-0.0.1.13577785562a1/src/dv_flow/mgr/std/fileset.py +0 -78
  24. dv_flow_mgr-0.0.1.13577785562a1/src/dv_flow/mgr/std/message.py +0 -7
  25. dv_flow_mgr-0.0.1.13577785562a1/src/dv_flow/mgr/std/task_null.py +0 -11
  26. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/.github/workflows/ci.yml +0 -0
  27. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/.gitignore +0 -0
  28. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/.vscode/settings.json +0 -0
  29. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/LICENSE +0 -0
  30. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/README.md +0 -0
  31. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/KeyArchitecture.md +0 -0
  32. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/Makefile +0 -0
  33. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/Notes.md +0 -0
  34. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/Roadmap.md +0 -0
  35. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/RundirLayout.md +0 -0
  36. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/Stages.md +0 -0
  37. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/Tasks.md +0 -0
  38. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/TypesAndDefs.md +0 -0
  39. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/Usecases.md +0 -0
  40. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/conf.py +0 -0
  41. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/index.rst +0 -0
  42. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/intro.rst +0 -0
  43. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/quickstart.rst +0 -0
  44. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/reference.rst +0 -0
  45. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/fwperiph_dma.pss +0 -0
  46. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/ivpm.yaml +0 -0
  47. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/setup.cfg +0 -0
  48. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/__main__.py +0 -0
  49. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/cmds/cmd_run.py +0 -0
  50. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/eval_jq.py +0 -0
  51. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/expr_eval.py +0 -0
  52. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/expr_parser.py +0 -0
  53. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/fileset.py +0 -0
  54. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/fragment_def.py +0 -0
  55. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/out +0 -0
  56. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/package.py +0 -0
  57. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/package_import_spec.py +0 -0
  58. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/param.py +0 -0
  59. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/parsetab.py +0 -0
  60. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/pkg_rgy.py +0 -0
  61. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/share/flow.json +0 -0
  62. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task.py +0 -0
  63. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_ctor.py +0 -0
  64. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_exec_data.py +0 -0
  65. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_graph_runner.py +0 -0
  66. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_graph_runner_local.py +0 -0
  67. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_impl_data.py +0 -0
  68. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_memento.py +0 -0
  69. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_output.py +0 -0
  70. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_params_ctor.py +0 -0
  71. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/type.py +0 -0
  72. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/type_def.py +0 -0
  73. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/util.py +0 -0
  74. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow_mgr.egg-info/dependency_links.txt +0 -0
  75. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow_mgr.egg-info/entry_points.txt +0 -0
  76. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow_mgr.egg-info/requires.txt +0 -0
  77. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow_mgr.egg-info/top_level.txt +0 -0
  78. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/examples/example1/example1.flow +0 -0
  79. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/system/test_depends.py +0 -0
  80. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/system/test_pkg_discovery.py +0 -0
  81. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/system/test_stdlib.py +0 -0
  82. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/__init__.py +0 -0
  83. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/fileset/test1/files1/file1_1.sv +0 -0
  84. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/fileset/test1/files1/file1_2.sv +0 -0
  85. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/fileset/test1/files2/file2_1.sv +0 -0
  86. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/fileset/test1/files2/file2_2.sv +0 -0
  87. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/fileset/test1/flow.dv +0 -0
  88. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/fileset/test1 copy/files1/file1_1.sv +0 -0
  89. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/fileset/test1 copy/files1/file1_2.sv +0 -0
  90. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/fileset/test1 copy/files2/file2_1.sv +0 -0
  91. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/fileset/test1 copy/files2/file2_2.sv +0 -0
  92. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/fileset/test1 copy/test1.dfs +0 -0
  93. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/proj1/proj1.dfs +0 -0
  94. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/proj2/proj2.dfs +0 -0
  95. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/proj3/proj3.dfs +0 -0
  96. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_data_merge.py +0 -0
  97. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_expr_eval.py +0 -0
  98. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_expr_parser.py +0 -0
  99. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_fileset.py +0 -0
  100. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_parse.py +0 -0
  101. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_smoke copy.sav +0 -0
  102. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_smoke.py +0 -0
  103. {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_stdlib.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: dv-flow-mgr
3
- Version: 0.0.1.13577785562a1
3
+ Version: 0.0.1.13657597614a1
4
4
  Summary: DV Flow Manager is a build system for silicon design
5
5
  Author-email: Matthew Ballance <matt.ballance@gmail.com>
6
6
  License: Apache License
@@ -115,4 +115,31 @@ with:
115
115
  # List-of
116
116
  - append-list:
117
117
 
118
+ # Why PSS?
119
+ - Key usecases
120
+
121
+ # Open Source and PSS
122
+
123
+ # YAML basics
124
+ - Load packages and create TaskNodeCtor objects from a YAML file
125
+ - Define types in YAML
126
+ - Implement a 'task factory'
127
+ - Support package overrides (config setting?)
128
+ -
129
+
130
+ # TaskNode, TaskNodeCtor
131
+ - TaskNodeCtor exists for each node type
132
+ - Every node declaration in a YAML file
133
+ - Node types accessed via the Python API
134
+ - A new node -- likely with different parameter values -- can be created via the API
135
+ - A node created via the YAML spec has a dedicated node ctor
136
+
137
+ When created via the
138
+
139
+ # Early Differentiators
140
+ - Library of tools with aggressive work avoidance (faster turnaround)
141
+ - Cross-tool support (strategy for category support)
142
+ - Extract and display markers (easier identification of failures)
143
+
144
+
118
145
 
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "dv-flow-mgr"
8
- version = "0.0.1.13577785562a1"
8
+ version = "0.0.1.13657597614a1"
9
9
  dependencies = [
10
10
  'pydantic',
11
11
  'pyyaml',
@@ -7,4 +7,5 @@ from .task_data import *
7
7
  from .task_graph_runner import TaskGraphRunner
8
8
  from .task_graph_runner_local import TaskGraphRunnerLocal
9
9
  from .task_graph_builder import TaskGraphBuilder
10
+ from .task_node import task
10
11
 
@@ -33,10 +33,10 @@ from typing import Any, Dict, List, Callable, Tuple, ClassVar
33
33
  from .fragment_def import FragmentDef
34
34
  from .package import Package
35
35
  from .package_import_spec import PackageImportSpec, PackageSpec
36
- #from .task import TaskCtorCls, TaskCtorParam, TaskCtorParamCls
36
+ from .task_node import TaskNodeCtor, TaskNodeCtorProxy, TaskNodeCtorTask
37
37
  from .task_ctor import TaskCtor
38
38
  from .task_def import TaskDef, TaskSpec
39
- from .std.task_null import TaskNull
39
+ from .std.task_null import TaskNull, TaskNullParams
40
40
  from .type_def import TypeDef
41
41
 
42
42
 
@@ -122,115 +122,27 @@ class PackageDef(BaseModel):
122
122
  ctor_t = tasks_m[task_name][2]
123
123
  return ctor_t
124
124
 
125
- def handleParams(self, task, ctor_t):
126
- self._log.debug("--> handleParams %s params=%s" % (task.name, str(task.params)))
127
-
128
- if task.params is not None and len(task.params) > 0:
129
- decl_params = False
130
-
131
- # First, add in a parameter-setting stage
132
- ctor_t = TaskCtorParam(
133
- name=ctor_t.name,
134
- uses=ctor_t,
135
- srcdir=ctor_t.srcdir)
136
- # ctor_t.params.update(task.params)
137
-
138
- for value in task.params.values():
139
- self._log.debug("value: %s" % str(value))
140
- if type(value) == dict and "type" in value.keys():
141
- decl_params = True
142
- break
143
-
144
- field_m = {}
145
- # First, add parameters from the base class
146
- base_o = ctor_t.mkParams()
147
- for fname,info in base_o.model_fields.items():
148
- self._log.debug("Field: %s (%s)" % (fname, info.default))
149
- field_m[fname] = (info.annotation, info.default)
150
-
151
- if decl_params:
152
- self._log.debug("Type declares new parameters")
153
- # We need to combine base parameters with new parameters
154
- ptype_m = {
155
- "str" : str,
156
- "int" : int,
157
- "float" : float,
158
- "bool" : bool,
159
- "list" : List
160
- }
161
- pdflt_m = {
162
- "str" : "",
163
- "int" : 0,
164
- "float" : 0.0,
165
- "bool" : False,
166
- "list" : []
167
- }
168
- for p in task.params.keys():
169
- param = task.params[p]
170
- self._log.debug("param: %s" % str(param))
171
- if type(param) == dict and "type" in param.keys():
172
- ptype_s = param["type"]
173
- if ptype_s not in ptype_m.keys():
174
- raise Exception("Unknown type %s" % ptype_s)
175
- ptype = ptype_m[ptype_s]
176
-
177
- if p in field_m.keys():
178
- raise Exception("Duplicate field %s" % p)
179
- if "value" in param.keys():
180
- field_m[p] = (ptype, param["value"])
181
- else:
182
- field_m[p] = (ptype, pdflt_m[ptype_s])
183
- else:
184
- if p not in field_m.keys():
185
- raise Exception("Field %s not found" % p)
186
- if type(param) != dict:
187
- value = param
188
- elif "value" in param.keys():
189
- value = param["value"]
190
- else:
191
- raise Exception("No value specified for param %s: %s" % (
192
- p, str(param)))
193
- field_m[p] = (field_m[p][0], value)
194
- self._log.debug("field_m: %s" % str(field_m))
195
- param_t = pydantic.create_model(
196
- "Task%sParams" % task.name, **field_m)
197
- ctor_t = TaskCtorParamCls(
198
- name=ctor_t.name,
199
- uses=ctor_t,
200
- params_ctor=param_t)
201
- else: # no new parameters declared
202
- self._log.debug("Type only overrides existing parameters")
203
- for p in task.params.keys():
204
- param = task.params[p]
205
- if p not in field_m.keys():
206
- raise Exception("Field %s not found" % p)
207
- if type(param) != dict:
208
- value = param
209
- elif "value" in param.keys():
210
- value = param["value"]
211
- else:
212
- raise Exception("No value specified for param %s: %s" % (
213
- p, str(param)))
214
- field_m[p] = (field_m[p][0], value)
215
- self._log.debug("Set param=%s to %s" % (p, str(value)))
216
- ctor_t.params[p] = value
217
-
218
- self._log.debug("<-- handleParams %s" % task.name)
219
-
220
- return ctor_t
221
-
222
125
  def mkTaskCtor(self, session, task, srcdir, tasks_m) -> TaskCtor:
223
126
  self._log.debug("--> %s::mkTaskCtor %s (srcdir: %s)" % (self.name, task.name, srcdir))
127
+ base_ctor_t : TaskCtor = None
224
128
  ctor_t : TaskCtor = None
129
+ base_params : BaseModel = None
130
+ callable = None
131
+ passthrough = False
132
+ needs = [] if task.needs is None else task.needs.copy()
133
+
134
+ if task.uses is not None:
135
+ base_ctor_t = self.getTaskCtor(session, task.uses, tasks_m)
136
+ base_params = base_ctor_t.mkTaskParams()
225
137
 
226
138
  # Determine the implementation constructor first
227
- if task.pyclass is not None:
139
+ if task.pytask is not None:
228
140
  # Built-in impl
229
141
  # Now, lookup the class
230
- self._log.debug("Use PyClass implementation")
231
- last_dot = task.pyclass.rfind('.')
232
- clsname = task.pyclass[last_dot+1:]
233
- modname = task.pyclass[:last_dot]
142
+ self._log.debug("Use PyTask implementation")
143
+ last_dot = task.pytask.rfind('.')
144
+ clsname = task.pytask[last_dot+1:]
145
+ modname = task.pytask[:last_dot]
234
146
 
235
147
  try:
236
148
  if modname not in sys.modules:
@@ -244,39 +156,106 @@ class PackageDef(BaseModel):
244
156
  modname, self.basedir, str(e)))
245
157
 
246
158
  if not hasattr(mod, clsname):
247
- raise Exception("Class %s not found in module %s" % (clsname, modname))
248
- task_ctor = getattr(mod, clsname)
249
-
250
- # Determine if we need to use a new
251
-
252
- if task.uses is not None:
253
- uses = self.getTaskCtor(session, task.uses, tasks_m)
254
- else:
255
- uses = None
256
-
257
- ctor_t = TaskCtorCls(
159
+ raise Exception("Method %s not found in module %s" % (clsname, modname))
160
+ callable = getattr(mod, clsname)
161
+
162
+ # Determine if we need to use a new
163
+ paramT = self._getParamT(task, base_params)
164
+
165
+ if callable is not None:
166
+ ctor_t = TaskNodeCtorTask(
258
167
  name=task.name,
259
- uses=uses,
260
- task_ctor=task_ctor,
261
- srcdir=srcdir)
262
- elif task.uses is not None:
168
+ srcdir=srcdir,
169
+ paramT=paramT, # TODO: need to determine the parameter type
170
+ passthrough=passthrough,
171
+ needs=needs, # TODO: need to determine the needs
172
+ task=callable)
173
+ elif base_ctor_t is not None:
263
174
  # Use the existing (base) to create the implementation
264
- ctor_t = TaskCtor(
175
+ ctor_t = TaskNodeCtorProxy(
265
176
  name=task.name,
266
- uses=self.getTaskCtor(session, task.uses, tasks_m),
267
- srcdir=srcdir)
177
+ srcdir=srcdir,
178
+ paramT=paramT, # TODO: need to determine the parameter type
179
+ passthrough=passthrough,
180
+ needs=needs,
181
+ uses=base_ctor_t)
268
182
  else:
269
183
  self._log.debug("Use 'Null' as the class implementation")
270
- ctor_t = TaskCtorCls(
184
+ ctor_t = TaskNodeCtorTask(
271
185
  name=task.name,
272
- task_ctor=TaskNull,
273
- srcdir=srcdir)
274
-
275
- ctor_t = self.handleParams(task, ctor_t)
276
- ctor_t.depends.extend(task.depends)
186
+ srcdir=srcdir,
187
+ paramT=TaskNullParams,
188
+ passthrough=passthrough,
189
+ needs=needs,
190
+ task=TaskNull)
277
191
 
278
192
  self._log.debug("<-- %s::mkTaskCtor %s" % (self.name, task.name))
279
193
  return ctor_t
194
+
195
+ def _getParamT(self, task, base_t : BaseModel):
196
+ # Get the base parameter type (if available)
197
+ # We will build a new type with updated fields
198
+
199
+ ptype_m = {
200
+ "str" : str,
201
+ "int" : int,
202
+ "float" : float,
203
+ "bool" : bool,
204
+ "list" : List
205
+ }
206
+ pdflt_m = {
207
+ "str" : "",
208
+ "int" : 0,
209
+ "float" : 0.0,
210
+ "bool" : False,
211
+ "list" : []
212
+ }
213
+
214
+ fields = []
215
+ field_m : Dict[str,int] = {}
216
+
217
+ # First, pull out existing fields (if there's a base type)
218
+ if base_t is not None:
219
+ self._log.debug("Base type: %s" % str(base_t))
220
+ for name,f in base_t.model_fields.items():
221
+ ff : dc.Field = f
222
+ fields.append(f)
223
+ field_m[name] = (f.annotation, getattr(base_t, name))
224
+ else:
225
+ self._log.debug("No base type")
226
+
227
+ for p in task.params.keys():
228
+ param = task.params[p]
229
+ self._log.debug("param: %s %s (%s)" % (p, str(param), str(type(param))))
230
+ if hasattr(param, "type") and param.type is not None:
231
+ ptype_s = param.type
232
+ if ptype_s not in ptype_m.keys():
233
+ raise Exception("Unknown type %s" % ptype_s)
234
+ ptype = ptype_m[ptype_s]
235
+
236
+ if p in field_m.keys():
237
+ raise Exception("Duplicate field %s" % p)
238
+ if param.value is not None:
239
+ field_m[p] = (ptype, param.value)
240
+ else:
241
+ field_m[p] = (ptype, pdflt_m[ptype_s])
242
+ self._log.debug("Set param=%s to %s" % (p, str(field_m[p][1])))
243
+ else:
244
+ if p not in field_m.keys():
245
+ raise Exception("Field %s not found" % p)
246
+ if type(param) != dict:
247
+ value = param
248
+ elif "value" in param.keys():
249
+ value = param["value"]
250
+ else:
251
+ raise Exception("No value specified for param %s: %s" % (
252
+ p, str(param)))
253
+ field_m[p] = (field_m[p][0], value)
254
+ self._log.debug("Set param=%s to %s" % (p, str(field_m[p][1])))
255
+
256
+ params_t = pydantic.create_model("Task%sParams" % task.name, **field_m)
257
+
258
+ return params_t
280
259
 
281
260
  @staticmethod
282
261
  def load(path, exp_pkg_name=None):
@@ -14,7 +14,6 @@ class ComplexType(BaseModel):
14
14
  map : Union[MapType, None] = None
15
15
 
16
16
  class ParamDef(BaseModel):
17
- name : str
18
17
  doc : str = None
19
18
  type : Union[str, 'ComplexType'] = None
20
19
  value : Union[Any, None] = None
@@ -7,8 +7,8 @@ from .eval_jq import eval_jq
7
7
  @dc.dataclass
8
8
  class ParamRefEval(object):
9
9
 
10
- parser : ExprParser = ExprParser()
11
- expr_eval : ExprEval = ExprEval()
10
+ parser : ExprParser = dc.field(default_factory=ExprParser)
11
+ expr_eval : ExprEval = dc.field(default_factory=ExprEval)
12
12
 
13
13
  def __post_init__(self):
14
14
  self.expr_eval.methods["jq"] = eval_jq
@@ -0,0 +1,19 @@
1
+ import asyncio
2
+ import logging
3
+ from dv_flow.mgr import TaskDataResult
4
+
5
+ _log = logging.getLogger("Exec")
6
+
7
+ async def Exec(runner, input) -> TaskDataResult:
8
+ _log.debug("TaskExec run: %s: cmd=%s" % (input.name, input.params.command))
9
+
10
+
11
+ proc = await asyncio.create_subprocess_shell(
12
+ input.params.command,
13
+ stdout=asyncio.subprocess.PIPE,
14
+ stderr=asyncio.subprocess.PIPE)
15
+
16
+ await proc.wait()
17
+
18
+ return TaskDataResult()
19
+
@@ -0,0 +1,75 @@
1
+
2
+ import os
3
+ import fnmatch
4
+ import glob
5
+ import logging
6
+ import pydantic.dataclasses as dc
7
+ from pydantic import BaseModel
8
+ from typing import ClassVar, List, Tuple
9
+ from dv_flow.mgr import TaskDataResult
10
+ from dv_flow.mgr import FileSet as _FileSet
11
+
12
+ class TaskFileSetMemento(BaseModel):
13
+ files : List[Tuple[str,float]] = dc.Field(default_factory=list)
14
+
15
+ _log = logging.getLogger("FileSet")
16
+
17
+ async def FileSet(runner, input) -> TaskDataResult:
18
+ _log.debug("TaskFileSet run: %s: basedir=%s, base=%s type=%s include=%s" % (
19
+ input.name,
20
+ input.srcdir,
21
+ input.params.base, input.params.type, str(input.params.include)
22
+ ))
23
+
24
+
25
+ changed = False
26
+ ex_memento = input.memento
27
+ memento = TaskFileSetMemento()
28
+
29
+ _log.debug("ex_memento: %s" % str(ex_memento))
30
+ _log.debug("params: %s" % str(input.params))
31
+
32
+ if input.params is not None:
33
+ glob_root = os.path.join(input.srcdir, input.params.base)
34
+ glob_root = glob_root.strip()
35
+
36
+ if glob_root[-1] == '/' or glob_root == '\\':
37
+ glob_root = glob_root[:-1]
38
+
39
+ _log.debug("glob_root: %s" % glob_root)
40
+
41
+ fs = _FileSet(
42
+ src=input.name,
43
+ type=input.params.type,
44
+ basedir=glob_root)
45
+
46
+ if not isinstance(input.params.include, list):
47
+ input.params.include = [input.params.include]
48
+
49
+ included_files = []
50
+ for pattern in input.params.include:
51
+ included_files.extend(glob.glob(os.path.join(glob_root, pattern), recursive=False))
52
+
53
+ _log.debug("included_files: %s" % str(included_files))
54
+
55
+ for file in included_files:
56
+ if not any(glob.fnmatch.fnmatch(file, os.path.join(glob_root, pattern)) for pattern in input.params.exclude):
57
+ memento.files.append((file, os.path.getmtime(os.path.join(glob_root, file))))
58
+ fs.files.append(file[len(glob_root)+1:])
59
+
60
+ # Check to see if the filelist or fileset have changed
61
+ # Only bother doing this if the upstream task data has not changed
62
+ if ex_memento is not None and not input.changed:
63
+ ex_memento.files.sort(key=lambda x: x[0])
64
+ memento.files.sort(key=lambda x: x[0])
65
+ _log.debug("ex_memento.files: %s" % str(ex_memento.files))
66
+ _log.debug("memento.files: %s" % str(memento.files))
67
+ changed = ex_memento != memento
68
+ else:
69
+ changed = True
70
+
71
+ return TaskDataResult(
72
+ memento=memento,
73
+ changed=changed,
74
+ output=[fs]
75
+ )
@@ -1,16 +1,19 @@
1
1
 
2
+ # yaml-language-server: $schema=https://dv-flow.github.io/dv-flow.schema.json
3
+
2
4
  package:
3
5
  name: std
4
6
 
5
7
  tasks:
6
8
  - name: Message
7
- pyclass: dv_flow.mgr.std.message.Message
9
+ pytask: dv_flow.mgr.std.message.Message
8
10
  with:
9
11
  msg:
10
12
  type: str
11
13
  value: ""
12
14
  - name: FileSet
13
- pyclass: dv_flow.mgr.std.fileset.FileSet
15
+ pytask: dv_flow.mgr.std.fileset.FileSet
16
+ passthrough: true
14
17
  with:
15
18
  base:
16
19
  type: str
@@ -24,9 +27,12 @@ package:
24
27
  exclude:
25
28
  type: str
26
29
  value: ""
27
- # - name: Exec
28
- # pyclass: dv_flow.mgr.std.exec.Exec
29
- # with: {}
30
+ - name: Exec
31
+ pytask: dv_flow.mgr.std.exec.Exec
32
+ with:
33
+ command:
34
+ type: str
35
+ value: ""
30
36
  types:
31
37
  # - name: TaskDataItem
32
38
  # doc: |
@@ -0,0 +1,6 @@
1
+
2
+ from dv_flow.mgr import Task, TaskDataResult
3
+
4
+ async def Message(runner, input) -> TaskDataResult:
5
+ print("%s: %s" % (input.name, input.params.msg))
6
+ return TaskDataResult()
@@ -0,0 +1,9 @@
1
+ from pydantic import BaseModel
2
+ from ..task_data import TaskDataResult
3
+
4
+ class TaskNullParams(BaseModel):
5
+ pass
6
+
7
+ async def TaskNull(runner, input) -> TaskDataResult:
8
+ return TaskDataResult()
9
+
@@ -42,6 +42,7 @@ class TaskParameterSet(BaseModel):
42
42
  seq : int = -1 # Order in which the param-set must appear
43
43
 
44
44
  class TaskDataInput(BaseModel):
45
+ name : str
45
46
  changed : bool
46
47
  srcdir : str
47
48
  rundir : str
@@ -35,11 +35,12 @@ class TaskDef(BaseModel):
35
35
  name : str
36
36
  # type : Union[str,TaskSpec] = dc.Field(default_factory=list)
37
37
  uses : str = dc.Field(default=None)
38
- pyclass : str = dc.Field(default=None)
38
+ pytask : str = dc.Field(default=None)
39
39
  desc : str = dc.Field(default="")
40
40
  doc : str = dc.Field(default="")
41
- depends : List[Union[str,TaskSpec]] = dc.Field(default_factory=list, alias="needs")
42
- params: List[ParamDef] = dc.Field(default_factory=list, alias="with")
41
+ needs : List[Union[str,TaskSpec]] = dc.Field(default_factory=list, alias="needs")
42
+ params: Dict[str,Union[str,ParamDef]] = dc.Field(default_factory=dict, alias="with")
43
+ passthrough: bool = dc.Field(default=False)
43
44
  # out: List[TaskOutput] = dc.Field(default_factory=list)
44
45
 
45
46
  def copy(self) -> 'TaskDef':
@@ -26,6 +26,7 @@ from .package import Package
26
26
  from .package_def import PackageDef, PackageSpec
27
27
  from .pkg_rgy import PkgRgy
28
28
  from .task import Task
29
+ from .task_node import TaskNodeCtor
29
30
  from typing import Dict, List
30
31
 
31
32
  @dc.dataclass
@@ -92,24 +93,29 @@ class TaskGraphBuilder(object):
92
93
 
93
94
  self._pkg_s.append(pkg)
94
95
 
95
- ctor_t : TaskCtor = pkg.getTaskCtor(task_name)
96
+ ctor_t : TaskNodeCtor = pkg.getTaskCtor(task_name)
96
97
 
97
98
  self._logger.debug("ctor_t: %s" % ctor_t.name)
98
99
 
99
- depends = []
100
+ needs = []
100
101
 
101
- for dep in ctor_t.depends:
102
- if not dep in self._task_m.keys():
103
- task = self._mkTaskGraph(dep, rundir)
104
- self._task_m[dep] = task
105
- pass
106
- depends.append(self._task_m[dep])
102
+ for need_def in ctor_t.getNeeds():
103
+ if not need_def in self._task_m.keys():
104
+ task = self._mkTaskGraph(need_def, rundir)
105
+ self._task_m[need_def] = task
106
+ needs.append(self._task_m[need_def])
107
107
 
108
108
  # The returned task should have all param references resolved
109
- task = ctor_t.mkTask(
109
+ params = ctor_t.mkTaskParams()
110
+
111
+ if params is None:
112
+ raise Exception("ctor %s returned None for params" % str(ctor_t))
113
+
114
+ task = ctor_t.mkTaskNode(
115
+ params=params,
110
116
  name=task_name,
111
- depends=depends,
112
- rundir=rundir)
117
+ needs=needs)
118
+ task.rundir = rundir
113
119
 
114
120
  self._task_m[task.name] = task
115
121
 
@@ -0,0 +1,15 @@
1
+ import dataclasses as dc
2
+
3
+ class TaskListenerLog(object):
4
+
5
+ def event(self, task : 'Task', reason : 'Reason'):
6
+ if reason == 'enter':
7
+ print("> Task %s" % task.name, flush=True)
8
+ elif reason == 'leave':
9
+ for m in task.result.markers:
10
+ print(" %s" % m)
11
+ print("< Task %s" % task.name, flush=True)
12
+ else:
13
+ print("- Task %s" % task.name, flush=True)
14
+ pass
15
+