dirigent-cli 0.9.0__tar.gz → 0.9.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 (32) hide show
  1. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/PKG-INFO +1 -1
  2. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/pyproject.toml +1 -1
  3. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/pyproject.toml.orig +1 -1
  4. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/commands.py +23 -8
  5. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/LICENSE +0 -0
  6. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/README.md +0 -0
  7. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/__init__.py +0 -0
  8. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/aliases.py +0 -0
  9. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/context.py +0 -0
  10. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/formatters.py +0 -0
  11. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/graph.py +0 -0
  12. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/health.py +0 -0
  13. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/local.py +0 -0
  14. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/main.py +0 -0
  15. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/output.py +0 -0
  16. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/params.py +0 -0
  17. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/profiles.py +0 -0
  18. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/project.py +0 -0
  19. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/py.typed +0 -0
  20. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/reaper.py +0 -0
  21. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/scaffold.py +0 -0
  22. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/schemas.py +0 -0
  23. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/sources.py +0 -0
  24. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/stream.py +0 -0
  25. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/summaries.py +0 -0
  26. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/templates/pack/README.md.tmpl +0 -0
  27. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/templates/pack/__init__.py.tmpl +0 -0
  28. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/templates/pack/operator.py.tmpl +0 -0
  29. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/templates/pack/pyproject.toml.tmpl +0 -0
  30. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/templates/pack/test_plugin.py.tmpl +0 -0
  31. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/timing.py +0 -0
  32. {dirigent_cli-0.9.0 → dirigent_cli-0.9.2}/src/dirigent_cli/triggers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dirigent-cli
3
- Version: 0.9.0
3
+ Version: 0.9.2
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.9.0"
3
+ version = "0.9.2"
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.9.0"
3
+ version = "0.9.2"
4
4
  description = "The dirigent command line interface (dirigent / dg)."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.13"
@@ -41,6 +41,7 @@ from dirigent_cli.output import (
41
41
  emit_problem,
42
42
  emit_record,
43
43
  emit_records,
44
+ error_console,
44
45
  fields,
45
46
  flagged,
46
47
  json_mode,
@@ -490,6 +491,8 @@ def init_command(
490
491
  """
491
492
  import asyncio
492
493
 
494
+ from dirigent_core.auth import MIN_PASSWORD_LENGTH, WeakPassword
495
+
493
496
  state = state_of(ctx)
494
497
  # Run once by a person at a terminal, so it renders unless records were asked for.
495
498
  if not state.chosen:
@@ -501,12 +504,12 @@ def init_command(
501
504
  try:
502
505
  check_template(template)
503
506
  except ProjectError as error:
504
- fail(str(error))
507
+ _init_fail(str(error))
505
508
  stack = template == COMPOSE_TEMPLATE_NAME
506
509
  if stack and documents_only:
507
- fail("--documents-only does not apply to the compose template, which writes no instance to skip")
510
+ _init_fail("--documents-only does not apply to the compose template, which writes no instance to skip")
508
511
  if stack and admin != "admin":
509
- fail("--admin does not apply to the compose template; the stack's first admin is named admin")
512
+ _init_fail("--admin does not apply to the compose template; the stack's first admin is named admin")
510
513
  if not documents_only and not stack:
511
514
  _refuse_an_existing_instance(root)
512
515
  secret = (
@@ -514,11 +517,13 @@ def init_command(
514
517
  if documents_only
515
518
  else (password or os.environ.get(BOOTSTRAP_PASSWORD_ENV) or _prompt_for_a_password(stack=stack))
516
519
  )
520
+ if not documents_only and len(secret) < MIN_PASSWORD_LENGTH:
521
+ _init_fail(str(WeakPassword()))
517
522
  version = cli_version()
518
523
  try:
519
524
  made = scaffold(directory, template=template, version=version, password=secret)
520
525
  except ProjectError as error:
521
- fail(str(error))
526
+ _init_fail(str(error))
522
527
  left = [_within(path, directory) for path in made.skipped]
523
528
  if documents_only or stack:
524
529
  starting = [
@@ -573,6 +578,17 @@ def instance_settings(root: Path) -> Settings:
573
578
  )
574
579
 
575
580
 
581
+ def _init_fail(message: str, *, problems: Sequence[str] = ()) -> NoReturn:
582
+ """Refuse an init: a record where records were asked for, plain sentences otherwise."""
583
+ if json_mode():
584
+ refuse(message, problems=problems)
585
+ else:
586
+ error_console.print(message, highlight=False, markup=False)
587
+ for problem in problems:
588
+ error_console.print(f" {problem}", highlight=False, markup=False)
589
+ raise typer.Exit(code=1)
590
+
591
+
576
592
  def _refuse_an_existing_instance(root: Path) -> None:
577
593
  """Refuse to initialise over an instance that is already there.
578
594
 
@@ -581,7 +597,7 @@ def _refuse_an_existing_instance(root: Path) -> None:
581
597
  """
582
598
  existing = instance_settings(root).sqlite_path
583
599
  if existing is not None and existing.exists():
584
- refuse(
600
+ _init_fail(
585
601
  f"{existing} already exists, so this directory holds an instance already",
586
602
  problems=[
587
603
  "dg dev --keep-state starts it",
@@ -589,13 +605,12 @@ def _refuse_an_existing_instance(root: Path) -> None:
589
605
  "dg init --documents-only scaffolds documents beside it",
590
606
  ],
591
607
  )
592
- raise typer.Exit(code=1)
593
608
 
594
609
 
595
610
  def _prompt_for_a_password(*, stack: bool = False) -> str:
596
611
  """Ask for the first admin's password, or say how to give it without a prompt."""
597
612
  if not sys.stdin.isatty():
598
- fail(f"no password for the first admin: pass --password, or set {BOOTSTRAP_PASSWORD_ENV}")
613
+ _init_fail(f"no password for the first admin: pass --password, or set {BOOTSTRAP_PASSWORD_ENV}")
599
614
  asked = "password for the stack's first admin" if stack else "password for the first admin"
600
615
  return str(typer.prompt(asked, hide_input=True, confirmation_prompt=True))
601
616
 
@@ -623,7 +638,7 @@ async def first_admin(settings: Settings, username: str, password: str) -> str:
623
638
  issued = await issue_token(session, user, name="init")
624
639
  return issued.secret.get_secret_value()
625
640
  except AuthError as error:
626
- fail(str(error))
641
+ _init_fail(str(error))
627
642
  finally:
628
643
  await engine.dispose()
629
644
 
File without changes
File without changes