doover-cli 0.5.3__tar.gz → 0.5.4__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 (88) hide show
  1. {doover_cli-0.5.3 → doover_cli-0.5.4}/PKG-INFO +1 -1
  2. {doover_cli-0.5.3 → doover_cli-0.5.4}/pyproject.toml +4 -1
  3. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/__init__.py +2 -0
  4. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/apps/apps.py +10 -0
  5. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_apps.py +45 -0
  6. {doover_cli-0.5.3 → doover_cli-0.5.4}/uv.lock +0 -1
  7. {doover_cli-0.5.3 → doover_cli-0.5.4}/.github/CONTRIBUTING.md +0 -0
  8. {doover_cli-0.5.3 → doover_cli-0.5.4}/.github/ISSUE_TEMPLATE/bug-report.yaml +0 -0
  9. {doover_cli-0.5.3 → doover_cli-0.5.4}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  10. {doover_cli-0.5.3 → doover_cli-0.5.4}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
  11. {doover_cli-0.5.3 → doover_cli-0.5.4}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  12. {doover_cli-0.5.3 → doover_cli-0.5.4}/.github/workflows/lint-test.yml +0 -0
  13. {doover_cli-0.5.3 → doover_cli-0.5.4}/.github/workflows/release-brew.yml +0 -0
  14. {doover_cli-0.5.3 → doover_cli-0.5.4}/.github/workflows/release-pypi.yml +0 -0
  15. {doover_cli-0.5.3 → doover_cli-0.5.4}/.github/workflows/release.yml +0 -0
  16. {doover_cli-0.5.3 → doover_cli-0.5.4}/.gitignore +0 -0
  17. {doover_cli-0.5.3 → doover_cli-0.5.4}/.pre-commit-config.yaml +0 -0
  18. {doover_cli-0.5.3 → doover_cli-0.5.4}/AGENT.md +0 -0
  19. {doover_cli-0.5.3 → doover_cli-0.5.4}/LICENSE +0 -0
  20. {doover_cli-0.5.3 → doover_cli-0.5.4}/README.md +0 -0
  21. {doover_cli-0.5.3 → doover_cli-0.5.4}/debian/changelog +0 -0
  22. {doover_cli-0.5.3 → doover_cli-0.5.4}/debian/control +0 -0
  23. {doover_cli-0.5.3 → doover_cli-0.5.4}/debian/rules +0 -0
  24. {doover_cli-0.5.3 → doover_cli-0.5.4}/docs/user_stories.md +0 -0
  25. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/agent.py +0 -0
  26. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/api/__init__.py +0 -0
  27. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/api/auth.py +0 -0
  28. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/api/errors.py +0 -0
  29. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/api/session.py +0 -0
  30. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/apps/app_install.py +0 -0
  31. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/apps/device.py +0 -0
  32. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/apps/device_type.py +0 -0
  33. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/apps/tunnel.py +0 -0
  34. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/channel.py +0 -0
  35. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/colours.py +0 -0
  36. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/config_schema.py +0 -0
  37. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/dda_logs.py +0 -0
  38. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/doover_config.py +0 -0
  39. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/grpc.py +0 -0
  40. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/login.py +0 -0
  41. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/renderer/__init__.py +0 -0
  42. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/renderer/_base.py +0 -0
  43. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/renderer/_basic.py +0 -0
  44. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/renderer/_default.py +0 -0
  45. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/renderer/_json.py +0 -0
  46. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/report.py +0 -0
  47. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/simulator.py +0 -0
  48. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/ui_schema.py +0 -0
  49. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/user.py +0 -0
  50. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/__init__.py +0 -0
  51. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/api.py +0 -0
  52. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/apps.py +0 -0
  53. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/context.py +0 -0
  54. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/crud/__init__.py +0 -0
  55. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/crud/commands.py +0 -0
  56. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/crud/lookup.py +0 -0
  57. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/crud/prompting.py +0 -0
  58. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/crud/schema.py +0 -0
  59. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/crud/values.py +0 -0
  60. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/errors.py +0 -0
  61. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/formatters.py +0 -0
  62. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/misc.py +0 -0
  63. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/parsers.py +0 -0
  64. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/prompt.py +0 -0
  65. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/sentry.py +0 -0
  66. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/shell_commands.py +0 -0
  67. {doover_cli-0.5.3 → doover_cli-0.5.4}/src/doover_cli/utils/state.py +0 -0
  68. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/__init__.py +0 -0
  69. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/conftest.py +0 -0
  70. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_agent.py +0 -0
  71. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_app_install.py +0 -0
  72. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_auth_integration.py +0 -0
  73. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_auth_unit.py +0 -0
  74. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_basic.py +0 -0
  75. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_crud_commands.py +0 -0
  76. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_crud_lookup.py +0 -0
  77. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_crud_prompting.py +0 -0
  78. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_crud_schema.py +0 -0
  79. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_crud_values.py +0 -0
  80. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_default_renderer.py +0 -0
  81. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_device.py +0 -0
  82. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_device_cli_integration.py +0 -0
  83. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_device_type.py +0 -0
  84. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_device_type_cli_integration.py +0 -0
  85. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_prompt.py +0 -0
  86. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_sentry.py +0 -0
  87. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_user.py +0 -0
  88. {doover_cli-0.5.3 → doover_cli-0.5.4}/tests/test_utils_apps.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: doover-cli
3
- Version: 0.5.3
3
+ Version: 0.5.4
4
4
  Summary: CLI for Doover
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.11
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "doover-cli"
3
- version = "0.5.3"
3
+ dynamic = ["version"]
4
4
  description = "CLI for Doover"
5
5
  requires-python = ">=3.11"
6
6
  dependencies = [
@@ -26,6 +26,9 @@ dependencies = [
26
26
  requires = ["hatchling"]
27
27
  build-backend = "hatchling.build"
28
28
 
29
+ [tool.hatch.version]
30
+ path = "src/doover_cli/__init__.py"
31
+
29
32
  [project.scripts]
30
33
  doover = "doover_cli:main"
31
34
 
@@ -1,6 +1,8 @@
1
1
  from doover_cli.renderer import Renderer
2
2
  from typing import Annotated, Optional
3
3
 
4
+ __version__ = "0.5.4"
5
+
4
6
  import click
5
7
  import typer
6
8
 
@@ -1007,6 +1007,16 @@ def publish(
1007
1007
 
1008
1008
  client, renderer = get_state()
1009
1009
 
1010
+ # The publish endpoints are organisation-scoped: without the
1011
+ # X-Doover-Organisation header the control plane rejects the request with
1012
+ # 401 "X-Doover-Organisation header missing" for any non-staff account.
1013
+ # Pin the client to the app's organisation (staging-aware, resolved into the
1014
+ # payload above) so every publish sub-call - create/partial, widget upload,
1015
+ # processor source + version release - carries the header.
1016
+ publish_org_id = payload.get("organisation_id")
1017
+ if publish_org_id is not None:
1018
+ client.organisation_id = int(publish_org_id)
1019
+
1010
1020
  rich.print(
1011
1021
  f"Updating application on doover site ({_control_base_url() or 'unknown base URL'})...\n"
1012
1022
  )
@@ -491,6 +491,51 @@ def test_app_publish_updates_existing_application(monkeypatch, tmp_path):
491
491
  assert renderer.render_calls == [{"id": 101, "published": True}]
492
492
 
493
493
 
494
+ def test_app_publish_pins_client_to_app_organisation(monkeypatch, tmp_path):
495
+ # Regression: publish must set the org context on the client so the
496
+ # X-Doover-Organisation header is sent. Without it the control plane
497
+ # returns 401 "X-Doover-Organisation header missing" for non-staff accounts.
498
+ captured = {}
499
+ renderer = FakeRenderer()
500
+ app_config = FakeAppConfig(app_id=101)
501
+
502
+ class FakeApplicationsClient:
503
+ @staticmethod
504
+ def partial(application_id, body):
505
+ captured["partial"] = (application_id, body)
506
+ return {"id": int(application_id), "published": True}
507
+
508
+ class FakeControlClient:
509
+ organisation_id = None
510
+ applications = FakeApplicationsClient()
511
+
512
+ client = FakeControlClient()
513
+
514
+ monkeypatch.setattr(
515
+ "doover_cli.apps.apps.get_app_directory", lambda root=None: tmp_path
516
+ )
517
+ monkeypatch.setattr(
518
+ "doover_cli.apps.apps.get_app_config", lambda root_fp, app_name=None: app_config
519
+ )
520
+ monkeypatch.setattr(
521
+ "doover_cli.apps.apps.get_state", lambda: (client, renderer)
522
+ )
523
+ monkeypatch.setattr(
524
+ "doover_cli.apps.apps.export_config_command",
525
+ lambda ctx, app_fp, validate_: None,
526
+ )
527
+ monkeypatch.setattr(
528
+ "doover_cli.apps.apps.export_ui_command",
529
+ lambda ctx, app_fp, validate_: None,
530
+ )
531
+
532
+ result = runner.invoke(app, ["app", "publish", str(tmp_path)])
533
+
534
+ assert result.exit_code == 0
535
+ assert client.organisation_id == 17
536
+ assert captured["partial"][0] == "101"
537
+
538
+
494
539
  def test_app_publish_creates_then_updates_when_missing(monkeypatch, tmp_path):
495
540
  captured = {}
496
541
  renderer = FakeRenderer()
@@ -544,7 +544,6 @@ wheels = [
544
544
 
545
545
  [[package]]
546
546
  name = "doover-cli"
547
- version = "0.5.3"
548
547
  source = { editable = "." }
549
548
  dependencies = [
550
549
  { name = "click" },
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