devnomads-cli 0.3.0__tar.gz → 0.4.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 (20) hide show
  1. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/PKG-INFO +4 -7
  2. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/README.md +2 -3
  3. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/devnomads_cli.egg-info/PKG-INFO +4 -7
  4. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/devnomads_cli.egg-info/requires.txt +1 -4
  5. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/dncli.py +12 -10
  6. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/pyproject.toml +2 -5
  7. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/tests/test_cert.py +2 -2
  8. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/tests/test_config.py +2 -2
  9. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/LICENSE +0 -0
  10. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/devnomads_cli.egg-info/SOURCES.txt +0 -0
  11. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/devnomads_cli.egg-info/dependency_links.txt +0 -0
  12. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/devnomads_cli.egg-info/entry_points.txt +0 -0
  13. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/devnomads_cli.egg-info/top_level.txt +0 -0
  14. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/setup.cfg +0 -0
  15. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/tests/test_cli.py +0 -0
  16. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/tests/test_generate.py +0 -0
  17. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/tests/test_generated_cli.py +0 -0
  18. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/tests/test_helpers.py +0 -0
  19. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/tests/test_hook.py +0 -0
  20. {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/tests/test_transfer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devnomads-cli
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Manage your DevNomads services from the command line
5
5
  Author-email: DevNomads <support@devnomads.nl>
6
6
  License: MIT
@@ -11,9 +11,7 @@ Requires-Dist: typer>=0.12
11
11
  Requires-Dist: httpx>=0.27
12
12
  Requires-Dist: rich>=13
13
13
  Requires-Dist: cryptography>=42
14
- Requires-Dist: devnomads>=0.1
15
- Provides-Extra: cert
16
- Requires-Dist: devnomads[acme]>=0.1; extra == "cert"
14
+ Requires-Dist: devnomads[acme]>=0.2.1
17
15
  Dynamic: license-file
18
16
 
19
17
  # dncli
@@ -56,7 +54,7 @@ Sleutels**, then store it:
56
54
  dncli configure
57
55
  ```
58
56
 
59
- The key is written to `~/.config/dnctl/credentials`, readable only
57
+ The key is written to `~/.config/dncli/credentials`, readable only
60
58
  by you. From here every command works:
61
59
 
62
60
  ```sh
@@ -128,10 +126,9 @@ dncli services list | jq -r '.[].entity'
128
126
 
129
127
  ## Certificates
130
128
 
131
- The `cert` extra adds Let's Encrypt issuance over DNS-01 and HTTP-01:
129
+ `dncli` issues Let's Encrypt certificates over DNS-01 and HTTP-01:
132
130
 
133
131
  ```sh
134
- uv tool install "devnomads-cli[cert]"
135
132
  dncli cert issue example.com -d "*.example.com"
136
133
  ```
137
134
 
@@ -38,7 +38,7 @@ Sleutels**, then store it:
38
38
  dncli configure
39
39
  ```
40
40
 
41
- The key is written to `~/.config/dnctl/credentials`, readable only
41
+ The key is written to `~/.config/dncli/credentials`, readable only
42
42
  by you. From here every command works:
43
43
 
44
44
  ```sh
@@ -110,10 +110,9 @@ dncli services list | jq -r '.[].entity'
110
110
 
111
111
  ## Certificates
112
112
 
113
- The `cert` extra adds Let's Encrypt issuance over DNS-01 and HTTP-01:
113
+ `dncli` issues Let's Encrypt certificates over DNS-01 and HTTP-01:
114
114
 
115
115
  ```sh
116
- uv tool install "devnomads-cli[cert]"
117
116
  dncli cert issue example.com -d "*.example.com"
118
117
  ```
119
118
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devnomads-cli
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Manage your DevNomads services from the command line
5
5
  Author-email: DevNomads <support@devnomads.nl>
6
6
  License: MIT
@@ -11,9 +11,7 @@ Requires-Dist: typer>=0.12
11
11
  Requires-Dist: httpx>=0.27
12
12
  Requires-Dist: rich>=13
13
13
  Requires-Dist: cryptography>=42
14
- Requires-Dist: devnomads>=0.1
15
- Provides-Extra: cert
16
- Requires-Dist: devnomads[acme]>=0.1; extra == "cert"
14
+ Requires-Dist: devnomads[acme]>=0.2.1
17
15
  Dynamic: license-file
18
16
 
19
17
  # dncli
@@ -56,7 +54,7 @@ Sleutels**, then store it:
56
54
  dncli configure
57
55
  ```
58
56
 
59
- The key is written to `~/.config/dnctl/credentials`, readable only
57
+ The key is written to `~/.config/dncli/credentials`, readable only
60
58
  by you. From here every command works:
61
59
 
62
60
  ```sh
@@ -128,10 +126,9 @@ dncli services list | jq -r '.[].entity'
128
126
 
129
127
  ## Certificates
130
128
 
131
- The `cert` extra adds Let's Encrypt issuance over DNS-01 and HTTP-01:
129
+ `dncli` issues Let's Encrypt certificates over DNS-01 and HTTP-01:
132
130
 
133
131
  ```sh
134
- uv tool install "devnomads-cli[cert]"
135
132
  dncli cert issue example.com -d "*.example.com"
136
133
  ```
137
134
 
@@ -2,7 +2,4 @@ typer>=0.12
2
2
  httpx>=0.27
3
3
  rich>=13
4
4
  cryptography>=42
5
- devnomads>=0.1
6
-
7
- [cert]
8
- devnomads[acme]>=0.1
5
+ devnomads[acme]>=0.2.1
@@ -44,6 +44,7 @@ from devnomads.api import DevNomadsError
44
44
  from devnomads.api.client import _unwrap as _lib_unwrap
45
45
  from devnomads.dns import Dns, challenge_name
46
46
  from rich.console import Console
47
+ from rich.markup import escape
47
48
  from rich.table import Table
48
49
  from typer.core import TyperGroup
49
50
 
@@ -71,7 +72,7 @@ class CliError(typer.Exit):
71
72
 
72
73
  def __init__(self, message: str) -> None:
73
74
  # soft_wrap keeps the error a single grep-able line
74
- err_console.print(f"[red]error:[/] {message}", soft_wrap=True)
75
+ err_console.print(f"[red]error:[/] {escape(message)}", soft_wrap=True)
75
76
  self.message = message
76
77
  super().__init__(code=1)
77
78
 
@@ -85,7 +86,7 @@ def config_dir() -> Path:
85
86
  return Path(env_dir)
86
87
  xdg = os.environ.get("XDG_CONFIG_HOME")
87
88
  base = Path(xdg) if xdg else Path.home() / ".config"
88
- return base / "dnctl"
89
+ return base / "dncli"
89
90
 
90
91
 
91
92
  def credentials_path() -> Path:
@@ -1275,10 +1276,12 @@ def _hook_dispatch(dns: Dns, operation: str, args: list[str]) -> int:
1275
1276
  else:
1276
1277
  dns.unset_txt(record, token_value)
1277
1278
  except (AuthError, ApiError) as exc:
1278
- err_console.print(f"[red]error:[/] {_error_message(exc.status, exc.detail)}")
1279
+ err_console.print(
1280
+ f"[red]error:[/] {escape(_error_message(exc.status, exc.detail))}"
1281
+ )
1279
1282
  return 1
1280
1283
  except DevNomadsError as exc:
1281
- err_console.print(f"[red]error:[/] {exc}")
1284
+ err_console.print(f"[red]error:[/] {escape(str(exc))}")
1282
1285
  return 1
1283
1286
  return 0
1284
1287
 
@@ -1306,7 +1309,7 @@ def hook_main(argv: list[str] | None = None) -> int:
1306
1309
  try:
1307
1310
  client = ApiClient.from_environment()
1308
1311
  except DevNomadsError as exc:
1309
- err_console.print(f"[red]error:[/] {exc}")
1312
+ err_console.print(f"[red]error:[/] {escape(str(exc))}")
1310
1313
  return 1
1311
1314
  try:
1312
1315
  return _hook_dispatch(Dns(client), operation, argv[2:])
@@ -1360,16 +1363,15 @@ CERT_RENEW_WINDOW_DAYS = 30
1360
1363
 
1361
1364
 
1362
1365
  def _load_acme() -> Any:
1363
- """Import devnomads.acme lazily, with a clean message if the extra is
1364
- missing."""
1366
+ """Import devnomads.acme lazily, so non-cert commands skip the ACME
1367
+ stack at startup."""
1365
1368
 
1366
1369
  try:
1367
1370
  import devnomads.acme as acme
1368
1371
  except ImportError as exc:
1369
1372
  raise CliError(
1370
- "certificate issuance needs the 'cert' extra; install it with: "
1371
- 'pip install "devnomads-cli[cert]" '
1372
- '(or: uv tool install "devnomads-cli[cert]")'
1373
+ "could not import devnomads.acme; the install looks broken - "
1374
+ 'reinstall with: pip install --force-reinstall "devnomads-cli"'
1373
1375
  ) from exc
1374
1376
  return acme
1375
1377
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "devnomads-cli"
3
- version = "0.3.0"
3
+ version = "0.4.0"
4
4
  description = "Manage your DevNomads services from the command line"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -11,12 +11,9 @@ dependencies = [
11
11
  "httpx>=0.27",
12
12
  "rich>=13",
13
13
  "cryptography>=42",
14
- "devnomads>=0.1",
14
+ "devnomads[acme]>=0.2.1",
15
15
  ]
16
16
 
17
- [project.optional-dependencies]
18
- cert = ["devnomads[acme]>=0.1"]
19
-
20
17
  [project.scripts]
21
18
  dncli = "dncli:run"
22
19
  dncli-dns-hook = "dncli:hook_main"
@@ -119,7 +119,7 @@ def test_issue_out_dir_override(configured, captured, isolated_config, tmp_path)
119
119
  assert (out / "fullchain.pem").read_text() == FULLCHAIN
120
120
 
121
121
 
122
- def test_load_acme_missing_extra_message(monkeypatch):
122
+ def test_load_acme_import_error_message(monkeypatch):
123
123
  import builtins
124
124
 
125
125
  real_import = builtins.__import__
@@ -132,7 +132,7 @@ def test_load_acme_missing_extra_message(monkeypatch):
132
132
  monkeypatch.setattr(builtins, "__import__", fake_import)
133
133
  result = runner.invoke(app, ["cert", "issue", "example.com"])
134
134
  assert result.exit_code == 1
135
- assert "cert" in result.output
135
+ assert "devnomads.acme" in result.output
136
136
 
137
137
 
138
138
  def test_renew_skips_valid_cert(configured, captured, isolated_config):
@@ -16,14 +16,14 @@ def test_config_dir_from_env(isolated_config):
16
16
  def test_config_dir_xdg_fallback(monkeypatch, tmp_path):
17
17
  monkeypatch.delenv(dncli.ENV_CONFIG_DIR, raising=False)
18
18
  monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path / "xdg"))
19
- assert dncli.config_dir() == tmp_path / "xdg" / "dnctl"
19
+ assert dncli.config_dir() == tmp_path / "xdg" / "dncli"
20
20
 
21
21
 
22
22
  def test_config_dir_home_fallback(monkeypatch, tmp_path):
23
23
  monkeypatch.delenv(dncli.ENV_CONFIG_DIR, raising=False)
24
24
  monkeypatch.delenv("XDG_CONFIG_HOME", raising=False)
25
25
  monkeypatch.setattr(Path, "home", lambda: tmp_path)
26
- assert dncli.config_dir() == tmp_path / ".config" / "dnctl"
26
+ assert dncli.config_dir() == tmp_path / ".config" / "dncli"
27
27
 
28
28
 
29
29
  def test_save_credentials_sets_strict_permissions(write_profile):
File without changes
File without changes