dirigent-cli 0.15.1__tar.gz → 0.15.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.
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/PKG-INFO +1 -1
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/pyproject.toml +1 -1
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/pyproject.toml.orig +1 -1
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/commands.py +38 -5
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/sources.py +27 -1
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/LICENSE +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/README.md +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/__init__.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/aliases.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/context.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/formatters.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/graph.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/health.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/init_form.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/local.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/main.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/output.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/params.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/profiles.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/project.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/py.typed +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/reaper.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/scaffold.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/schemas.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/seeding.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/starters.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/stream.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/summaries.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/templates/pack/README.md.tmpl +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/templates/pack/__init__.py.tmpl +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/templates/pack/operator.py.tmpl +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/templates/pack/pyproject.toml.tmpl +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/templates/pack/test_plugin.py.tmpl +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/timing.py +0 -0
- {dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/triggers.py +0 -0
|
@@ -65,7 +65,14 @@ from dirigent_cli.project import (
|
|
|
65
65
|
write_token_env,
|
|
66
66
|
)
|
|
67
67
|
from dirigent_cli.scaffold import ScaffoldedRecord, ScaffoldError, ScaffoldRecord, scaffold_pack
|
|
68
|
-
from dirigent_cli.sources import
|
|
68
|
+
from dirigent_cli.sources import (
|
|
69
|
+
Document,
|
|
70
|
+
SourceError,
|
|
71
|
+
looks_like_a_document,
|
|
72
|
+
parse_document,
|
|
73
|
+
read_document,
|
|
74
|
+
read_path,
|
|
75
|
+
)
|
|
69
76
|
from dirigent_cli.stream import Sink, track_steps, use_scratch_prefix
|
|
70
77
|
from dirigent_cli.timing import RunProfile, attempt_timing, by_step, profile, step_timing
|
|
71
78
|
from dirigent_client import (
|
|
@@ -184,9 +191,13 @@ def _apply_one(
|
|
|
184
191
|
source: ProvenanceSource | None = None,
|
|
185
192
|
) -> ApplyResult:
|
|
186
193
|
"""Apply one document and return the server's result."""
|
|
194
|
+
try:
|
|
195
|
+
body = parse_document(document)
|
|
196
|
+
except SourceError as error:
|
|
197
|
+
fail(str(error))
|
|
187
198
|
return dg.call(
|
|
188
199
|
dg.pipelines.apply(
|
|
189
|
-
|
|
200
|
+
body,
|
|
190
201
|
code=code,
|
|
191
202
|
source=source if source is not None else document.source,
|
|
192
203
|
source_ref=document.ref,
|
|
@@ -374,12 +385,20 @@ def export_command(
|
|
|
374
385
|
"""Export a pipeline as canonical YAML."""
|
|
375
386
|
with client_for(state_of(ctx)) as dg:
|
|
376
387
|
text = dg.call(dg.pipelines.export(code, version=version))
|
|
388
|
+
if file is not None:
|
|
389
|
+
file.write_text(text)
|
|
377
390
|
if state_of(ctx).json_output:
|
|
378
|
-
return emit_fact(
|
|
391
|
+
return emit_fact(
|
|
392
|
+
"pipeline.exported",
|
|
393
|
+
message="exported",
|
|
394
|
+
code=code,
|
|
395
|
+
version=version,
|
|
396
|
+
document=text,
|
|
397
|
+
path=None if file is None else str(file),
|
|
398
|
+
)
|
|
379
399
|
if file is None:
|
|
380
400
|
console.print(text, end="", highlight=False, markup=False)
|
|
381
401
|
return
|
|
382
|
-
file.write_text(text)
|
|
383
402
|
console.print(f"Wrote [bold]{file}[/].")
|
|
384
403
|
|
|
385
404
|
|
|
@@ -2713,11 +2732,25 @@ def examples_list(
|
|
|
2713
2732
|
def examples_show(
|
|
2714
2733
|
ctx: typer.Context,
|
|
2715
2734
|
code: Annotated[str, typer.Argument(help="The example to read.")],
|
|
2735
|
+
file: Annotated[
|
|
2736
|
+
Path | None, typer.Option("-f", "--file", help="Write the document to a file instead of stdout.")
|
|
2737
|
+
] = None,
|
|
2716
2738
|
local: Annotated[bool, typer.Option("--local", help=LOCAL_CATALOGUE)] = False,
|
|
2717
2739
|
) -> None:
|
|
2718
|
-
"""Print one example's document, verbatim, as the shelf holds it.
|
|
2740
|
+
"""Print one example's document, verbatim, as the shelf holds it, or write it to a file.
|
|
2741
|
+
|
|
2742
|
+
Stdout in a pipe carries records like every command, so a redirect keeps a record and
|
|
2743
|
+
not the document; `-f` writes the document itself.
|
|
2744
|
+
"""
|
|
2719
2745
|
state = state_of(ctx)
|
|
2720
2746
|
entry = _example(state, code, local=local)
|
|
2747
|
+
if file is not None:
|
|
2748
|
+
file.parent.mkdir(parents=True, exist_ok=True)
|
|
2749
|
+
file.write_text(entry.source)
|
|
2750
|
+
if state.json_output:
|
|
2751
|
+
return emit_fact("example.written", message="written", code=entry.code, path=str(file))
|
|
2752
|
+
console.print(f"Wrote [bold]{file}[/].")
|
|
2753
|
+
return
|
|
2721
2754
|
if state.json_output:
|
|
2722
2755
|
return emit_fact("example.source", message="example", **entry.model_dump(mode="json"))
|
|
2723
2756
|
console.print(entry.source, end="", highlight=False, markup=False)
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
import sys
|
|
4
4
|
from pathlib import Path
|
|
5
|
-
from typing import Final
|
|
5
|
+
from typing import Any, Final, cast
|
|
6
6
|
|
|
7
7
|
import httpx2
|
|
8
|
+
import yaml
|
|
8
9
|
from pydantic import BaseModel, ConfigDict
|
|
9
10
|
|
|
10
11
|
from dirigent_client.enums import ProvenanceSource
|
|
@@ -67,6 +68,31 @@ def read_path(path: Path) -> Document:
|
|
|
67
68
|
return Document(text=path.read_text(), source=ProvenanceSource.FILE, ref=str(path))
|
|
68
69
|
|
|
69
70
|
|
|
71
|
+
def parse_document(document: Document) -> dict[str, Any]:
|
|
72
|
+
"""Parse a document's text, refusing what is plainly not a pipeline document, by name.
|
|
73
|
+
|
|
74
|
+
The server checks the same things, but it never saw the file: an error that names the path
|
|
75
|
+
is the one a person can act on when a whole project was applied.
|
|
76
|
+
"""
|
|
77
|
+
try:
|
|
78
|
+
parsed = yaml.safe_load(document.text)
|
|
79
|
+
except yaml.YAMLError as error:
|
|
80
|
+
raise SourceError(f"{document.label} is not readable YAML or JSON: {error}") from error
|
|
81
|
+
if not isinstance(parsed, dict):
|
|
82
|
+
kind = "empty" if parsed is None else type(parsed).__name__
|
|
83
|
+
raise SourceError(f"{document.label} is not a document: a document is a mapping, and this file is {kind}")
|
|
84
|
+
if "format" not in parsed:
|
|
85
|
+
if "kind" in parsed:
|
|
86
|
+
raise SourceError(
|
|
87
|
+
f"{document.label} holds a dg record (kind {parsed['kind']!r}), not a document: a command whose "
|
|
88
|
+
"stdout is a pipe writes records, so a redirect keeps the record and not the rendering. Write "
|
|
89
|
+
"the document with `dg examples show CODE -f FILE` or `dg export CODE -f FILE`, or copy a "
|
|
90
|
+
"starter with `dg pipeline new STARTER`."
|
|
91
|
+
)
|
|
92
|
+
raise SourceError(f"{document.label} declares no format; add `format: dirigent/v1`")
|
|
93
|
+
return cast("dict[str, Any]", parsed)
|
|
94
|
+
|
|
95
|
+
|
|
70
96
|
def looks_like_a_document(reference: str) -> bool:
|
|
71
97
|
"""Report whether an argument names a document rather than a pipeline.
|
|
72
98
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/templates/pack/__init__.py.tmpl
RENAMED
|
File without changes
|
{dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/templates/pack/operator.py.tmpl
RENAMED
|
File without changes
|
{dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/templates/pack/pyproject.toml.tmpl
RENAMED
|
File without changes
|
{dirigent_cli-0.15.1 → dirigent_cli-0.15.2}/src/dirigent_cli/templates/pack/test_plugin.py.tmpl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|