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.
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/PKG-INFO +1 -1
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/Steps.md +27 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/pyproject.toml +1 -1
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/__init__.py +1 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/package_def.py +107 -128
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/param_def.py +0 -1
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/param_ref_eval.py +2 -2
- dv_flow_mgr-0.0.1.13657597614a1/src/dv_flow/mgr/std/exec.py +19 -0
- dv_flow_mgr-0.0.1.13657597614a1/src/dv_flow/mgr/std/fileset.py +75 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/std/flow.dv +11 -5
- dv_flow_mgr-0.0.1.13657597614a1/src/dv_flow/mgr/std/message.py +6 -0
- dv_flow_mgr-0.0.1.13657597614a1/src/dv_flow/mgr/std/task_null.py +9 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_data.py +1 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_def.py +4 -3
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_graph_builder.py +17 -11
- dv_flow_mgr-0.0.1.13657597614a1/src/dv_flow/mgr/task_listener_log.py +15 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_node.py +120 -21
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_runner.py +85 -6
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow_mgr.egg-info/PKG-INFO +1 -1
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow_mgr.egg-info/SOURCES.txt +2 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_pyclass.py +107 -42
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_pytask_smoke.py +34 -38
- dv_flow_mgr-0.0.1.13577785562a1/src/dv_flow/mgr/std/fileset.py +0 -78
- dv_flow_mgr-0.0.1.13577785562a1/src/dv_flow/mgr/std/message.py +0 -7
- dv_flow_mgr-0.0.1.13577785562a1/src/dv_flow/mgr/std/task_null.py +0 -11
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/.github/workflows/ci.yml +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/.gitignore +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/.vscode/settings.json +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/LICENSE +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/README.md +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/KeyArchitecture.md +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/Makefile +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/Notes.md +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/Roadmap.md +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/RundirLayout.md +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/Stages.md +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/Tasks.md +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/TypesAndDefs.md +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/Usecases.md +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/conf.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/index.rst +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/intro.rst +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/quickstart.rst +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/docs/reference.rst +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/fwperiph_dma.pss +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/ivpm.yaml +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/setup.cfg +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/__main__.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/cmds/cmd_run.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/eval_jq.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/expr_eval.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/expr_parser.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/fileset.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/fragment_def.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/out +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/package.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/package_import_spec.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/param.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/parsetab.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/pkg_rgy.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/share/flow.json +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_ctor.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_exec_data.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_graph_runner.py +0 -0
- {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
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_impl_data.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_memento.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_output.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_params_ctor.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/type.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/type_def.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/util.py +0 -0
- {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
- {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
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow_mgr.egg-info/requires.txt +0 -0
- {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
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/examples/example1/example1.flow +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/system/test_depends.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/system/test_pkg_discovery.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/system/test_stdlib.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/__init__.py +0 -0
- {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
- {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
- {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
- {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
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/fileset/test1/flow.dv +0 -0
- {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
- {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
- {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
- {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
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/fileset/test1 copy/test1.dfs +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/proj1/proj1.dfs +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/proj2/proj2.dfs +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/data/proj3/proj3.dfs +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_data_merge.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_expr_eval.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_expr_parser.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_fileset.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_parse.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_smoke copy.sav +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_smoke.py +0 -0
- {dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/tests/unit/test_stdlib.py +0 -0
@@ -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
|
|
{dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/package_def.py
RENAMED
@@ -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
|
-
|
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.
|
139
|
+
if task.pytask is not None:
|
228
140
|
# Built-in impl
|
229
141
|
# Now, lookup the class
|
230
|
-
self._log.debug("Use
|
231
|
-
last_dot = task.
|
232
|
-
clsname = task.
|
233
|
-
modname = task.
|
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("
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
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
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
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 =
|
175
|
+
ctor_t = TaskNodeCtorProxy(
|
265
176
|
name=task.name,
|
266
|
-
|
267
|
-
|
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 =
|
184
|
+
ctor_t = TaskNodeCtorTask(
|
271
185
|
name=task.name,
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
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):
|
@@ -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
|
+
)
|
{dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/std/flow.dv
RENAMED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
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: |
|
{dv_flow_mgr-0.0.1.13577785562a1 → dv_flow_mgr-0.0.1.13657597614a1}/src/dv_flow/mgr/task_def.py
RENAMED
@@ -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
|
-
|
38
|
+
pytask : str = dc.Field(default=None)
|
39
39
|
desc : str = dc.Field(default="")
|
40
40
|
doc : str = dc.Field(default="")
|
41
|
-
|
42
|
-
params:
|
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 :
|
96
|
+
ctor_t : TaskNodeCtor = pkg.getTaskCtor(task_name)
|
96
97
|
|
97
98
|
self._logger.debug("ctor_t: %s" % ctor_t.name)
|
98
99
|
|
99
|
-
|
100
|
+
needs = []
|
100
101
|
|
101
|
-
for
|
102
|
-
if not
|
103
|
-
task = self._mkTaskGraph(
|
104
|
-
self._task_m[
|
105
|
-
|
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
|
-
|
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
|
-
|
112
|
-
|
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
|
+
|