dirigent-cli 0.11.0__tar.gz → 0.13.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/PKG-INFO +1 -1
  2. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/pyproject.toml +1 -1
  3. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/pyproject.toml.orig +1 -1
  4. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/commands.py +29 -6
  5. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/project.py +7 -7
  6. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/triggers.py +14 -1
  7. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/LICENSE +0 -0
  8. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/README.md +0 -0
  9. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/__init__.py +0 -0
  10. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/aliases.py +0 -0
  11. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/context.py +0 -0
  12. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/formatters.py +0 -0
  13. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/graph.py +0 -0
  14. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/health.py +0 -0
  15. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/init_form.py +0 -0
  16. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/local.py +0 -0
  17. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/main.py +0 -0
  18. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/output.py +0 -0
  19. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/params.py +0 -0
  20. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/profiles.py +0 -0
  21. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/py.typed +0 -0
  22. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/reaper.py +0 -0
  23. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/scaffold.py +0 -0
  24. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/schemas.py +0 -0
  25. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/sources.py +0 -0
  26. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/stream.py +0 -0
  27. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/summaries.py +0 -0
  28. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/templates/pack/README.md.tmpl +0 -0
  29. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/templates/pack/__init__.py.tmpl +0 -0
  30. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/templates/pack/operator.py.tmpl +0 -0
  31. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/templates/pack/pyproject.toml.tmpl +0 -0
  32. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/templates/pack/test_plugin.py.tmpl +0 -0
  33. {dirigent_cli-0.11.0 → dirigent_cli-0.13.0}/src/dirigent_cli/timing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dirigent-cli
3
- Version: 0.11.0
3
+ Version: 0.13.0
4
4
  Summary: The dirigent command line interface (dirigent / dg).
5
5
  License-Expression: LicenseRef-Proprietary
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "dirigent-cli"
3
- version = "0.11.0"
3
+ version = "0.13.0"
4
4
  description = "The dirigent command line interface (dirigent / dg)."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.13"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "dirigent-cli"
3
- version = "0.11.0"
3
+ version = "0.13.0"
4
4
  description = "The dirigent command line interface (dirigent / dg)."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.13"
@@ -1930,11 +1930,27 @@ def _relay_log(entry: LogEntryOut, state: CliState) -> None:
1930
1930
  def runs_report(
1931
1931
  ctx: typer.Context,
1932
1932
  run_id: Annotated[UUID, typer.Argument(help="The run to summarise.")],
1933
+ markdown: Annotated[
1934
+ bool, typer.Option("--markdown", help="Write the document the run rendered when it settled.")
1935
+ ] = False,
1933
1936
  ) -> None:
1934
- """Summarise a run: what each step amounted to, and how long it took."""
1935
- with client_for(state_of(ctx)) as dg:
1937
+ """Summarise a run: what each step amounted to, and how long it took.
1938
+
1939
+ `--markdown` answers with the run's own report document instead, which a run renders only
1940
+ when its pipeline document declares a `report:` section.
1941
+ """
1942
+ state = state_of(ctx)
1943
+ with client_for(state) as dg:
1944
+ if markdown:
1945
+ document = dg.call(dg.runs.report_document(run_id))
1946
+ if document is None:
1947
+ fail(f"run {run_id} has no report document; declare `report:` in the pipeline document")
1948
+ if state.json_output:
1949
+ return emit_fact("run.report_document", message="rendered", run_id=str(run_id), document=document)
1950
+ console.print(document, end="", highlight=False, markup=False)
1951
+ return
1936
1952
  report = dg.call(dg.runs.report(run_id))
1937
- if state_of(ctx).json_output:
1953
+ if state.json_output:
1938
1954
  return emit_one("run.report", report)
1939
1955
  _print_report(report)
1940
1956
 
@@ -2360,7 +2376,7 @@ def workers_command(
2360
2376
  def system_info(
2361
2377
  ctx: typer.Context,
2362
2378
  ) -> None:
2363
- """Describe the instance, and check every connection it holds."""
2379
+ """Describe the instance, and repeat what each connection said when it was last checked."""
2364
2380
  with client_for(state_of(ctx)) as dg:
2365
2381
  info = dg.call(dg.system.info())
2366
2382
  if state_of(ctx).json_output:
@@ -2383,9 +2399,16 @@ def system_info(
2383
2399
  console.print()
2384
2400
  table(
2385
2401
  "connections",
2386
- ["code", "name", "kind", "connected", "detail"],
2402
+ ["code", "name", "kind", "last check", "healthy", "detail"],
2387
2403
  [
2388
- [row.code, row.name or "-", row.kind, render_bool(row.connected), row.detail or "-"]
2404
+ [
2405
+ row.code,
2406
+ row.name or "-",
2407
+ row.kind,
2408
+ moment(row.last_check_at),
2409
+ render_bool(row.last_check_healthy),
2410
+ row.last_check_detail or "-",
2411
+ ]
2389
2412
  for row in info.connections
2390
2413
  ],
2391
2414
  )
@@ -209,9 +209,9 @@ SERVICE_EXAMPLES: Final = {
209
209
  """\
210
210
  # A greeting written to the stack's own bucket and read back, through the s3:// scheme.
211
211
  #
212
- # There is no S3 block: storage.copy moves bytes between schemes, and the stack's `migrate`
213
- # service bootstraps the `artifacts` connection that serves s3://. The bucket comes from the
214
- # URI, so this one is the stack's:
212
+ # There is no S3 block: storage.write puts text in an object, storage.copy moves bytes between
213
+ # schemes, and the stack's `migrate` service bootstraps the `artifacts` connection that serves
214
+ # s3://. The bucket comes from the URI, so this one is the stack's:
215
215
  #
216
216
  # dg run s3-hello --watch
217
217
 
@@ -223,7 +223,7 @@ description: Write a greeting to the bucket and copy it back, through s3://.
223
223
 
224
224
  requires:
225
225
  blocks:
226
- - value.const
226
+ - storage.write
227
227
  - storage.copy
228
228
  connections:
229
229
  - artifacts
@@ -232,10 +232,10 @@ requires:
232
232
 
233
233
  steps:
234
234
  greet:
235
- block: value.const
235
+ block: storage.write
236
236
  config:
237
- value: "hello from object storage"
238
- save_to: "${run.scratch}/hello.txt"
237
+ target: "${run.scratch}/hello.txt"
238
+ text: "hello from object storage"
239
239
 
240
240
  upload:
241
241
  block: storage.copy
@@ -441,12 +441,22 @@ def alerts_rules_create(
441
441
  description: Annotated[str | None, typer.Option("--description", help="What this rule is for.")] = None,
442
442
  pipeline: Annotated[str | None, typer.Option("--pipeline", help="Watch one pipeline instead of all.")] = None,
443
443
  connection: Annotated[str | None, typer.Option("--connection", help="The credential the channel uses.")] = None,
444
- template: Annotated[str | None, typer.Option("--template", help="Subject template, reading ${run.*}.")] = None,
444
+ template: Annotated[
445
+ str | None, typer.Option("--template", help="Subject, a Jinja template over the run's facts.")
446
+ ] = None,
447
+ body: Annotated[str | None, typer.Option("--body", help="Body, a Jinja template over the run's facts.")] = None,
448
+ body_file: Annotated[
449
+ Path | None, typer.Option("--body-file", help="Read the body template from a file instead.")
450
+ ] = None,
445
451
  throttle: Annotated[str, typer.Option("--throttle", help="At most one message per window, e.g. 15m.")] = "0s",
446
452
  ) -> None:
447
453
  """Declare an alert rule binding an event at a scope to a channel."""
448
454
  if event not in set(AlertEvent):
449
455
  _fail(f"{event!r} is not an alert event ({', '.join(sorted(AlertEvent))})")
456
+ if body is not None and body_file is not None:
457
+ _fail("a rule takes one body: --body or --body-file, not both")
458
+ if body_file is not None:
459
+ body = body_file.read_text()
450
460
  with client_for(state_of(ctx)) as dg:
451
461
  created = dg.call(
452
462
  dg.alerts.create_rule(
@@ -459,6 +469,7 @@ def alerts_rules_create(
459
469
  pipeline=pipeline,
460
470
  connection=connection,
461
471
  template=template,
472
+ body=body,
462
473
  throttle=throttle,
463
474
  )
464
475
  )
@@ -471,6 +482,8 @@ def alerts_rules_create(
471
482
  scope=created.pipeline or created.scope.value,
472
483
  notifier=created.notifier,
473
484
  connection=created.connection,
485
+ template=created.template is not None,
486
+ body=created.body is not None,
474
487
  throttle=created.throttle,
475
488
  )
476
489
 
File without changes
File without changes