doover-cli 0.4.1__tar.gz → 0.4.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 (88) hide show
  1. {doover_cli-0.4.1 → doover_cli-0.4.2}/PKG-INFO +1 -1
  2. {doover_cli-0.4.1 → doover_cli-0.4.2}/pyproject.toml +1 -1
  3. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/apps/apps.py +25 -1
  4. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/apps.py +14 -10
  5. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_apps.py +8 -9
  6. {doover_cli-0.4.1 → doover_cli-0.4.2}/uv.lock +1 -1
  7. {doover_cli-0.4.1 → doover_cli-0.4.2}/.github/CONTRIBUTING.md +0 -0
  8. {doover_cli-0.4.1 → doover_cli-0.4.2}/.github/ISSUE_TEMPLATE/bug-report.yaml +0 -0
  9. {doover_cli-0.4.1 → doover_cli-0.4.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  10. {doover_cli-0.4.1 → doover_cli-0.4.2}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
  11. {doover_cli-0.4.1 → doover_cli-0.4.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  12. {doover_cli-0.4.1 → doover_cli-0.4.2}/.github/workflows/lint-test.yml +0 -0
  13. {doover_cli-0.4.1 → doover_cli-0.4.2}/.github/workflows/release-brew.yml +0 -0
  14. {doover_cli-0.4.1 → doover_cli-0.4.2}/.github/workflows/release-pypi.yml +0 -0
  15. {doover_cli-0.4.1 → doover_cli-0.4.2}/.github/workflows/release.yml +0 -0
  16. {doover_cli-0.4.1 → doover_cli-0.4.2}/.gitignore +0 -0
  17. {doover_cli-0.4.1 → doover_cli-0.4.2}/.pre-commit-config.yaml +0 -0
  18. {doover_cli-0.4.1 → doover_cli-0.4.2}/AGENT.md +0 -0
  19. {doover_cli-0.4.1 → doover_cli-0.4.2}/LICENSE +0 -0
  20. {doover_cli-0.4.1 → doover_cli-0.4.2}/README.md +0 -0
  21. {doover_cli-0.4.1 → doover_cli-0.4.2}/debian/changelog +0 -0
  22. {doover_cli-0.4.1 → doover_cli-0.4.2}/debian/control +0 -0
  23. {doover_cli-0.4.1 → doover_cli-0.4.2}/debian/rules +0 -0
  24. {doover_cli-0.4.1 → doover_cli-0.4.2}/docs/user_stories.md +0 -0
  25. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/__init__.py +0 -0
  26. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/agent.py +0 -0
  27. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/api/__init__.py +0 -0
  28. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/api/auth.py +0 -0
  29. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/api/errors.py +0 -0
  30. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/api/session.py +0 -0
  31. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/apps/app_install.py +0 -0
  32. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/apps/device.py +0 -0
  33. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/apps/device_type.py +0 -0
  34. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/apps/tunnel.py +0 -0
  35. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/channel.py +0 -0
  36. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/colours.py +0 -0
  37. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/config_schema.py +0 -0
  38. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/dda_logs.py +0 -0
  39. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/doover_config.py +0 -0
  40. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/grpc.py +0 -0
  41. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/login.py +0 -0
  42. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/renderer/__init__.py +0 -0
  43. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/renderer/_base.py +0 -0
  44. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/renderer/_basic.py +0 -0
  45. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/renderer/_default.py +0 -0
  46. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/renderer/_json.py +0 -0
  47. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/report.py +0 -0
  48. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/simulator.py +0 -0
  49. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/ui_schema.py +0 -0
  50. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/user.py +0 -0
  51. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/__init__.py +0 -0
  52. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/api.py +0 -0
  53. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/context.py +0 -0
  54. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/crud/__init__.py +0 -0
  55. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/crud/commands.py +0 -0
  56. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/crud/lookup.py +0 -0
  57. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/crud/prompting.py +0 -0
  58. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/crud/schema.py +0 -0
  59. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/crud/values.py +0 -0
  60. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/errors.py +0 -0
  61. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/formatters.py +0 -0
  62. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/misc.py +0 -0
  63. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/parsers.py +0 -0
  64. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/prompt.py +0 -0
  65. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/sentry.py +0 -0
  66. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/shell_commands.py +0 -0
  67. {doover_cli-0.4.1 → doover_cli-0.4.2}/src/doover_cli/utils/state.py +0 -0
  68. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/__init__.py +0 -0
  69. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/conftest.py +0 -0
  70. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_agent.py +0 -0
  71. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_app_install.py +0 -0
  72. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_auth_integration.py +0 -0
  73. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_auth_unit.py +0 -0
  74. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_basic.py +0 -0
  75. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_crud_commands.py +0 -0
  76. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_crud_lookup.py +0 -0
  77. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_crud_prompting.py +0 -0
  78. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_crud_schema.py +0 -0
  79. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_crud_values.py +0 -0
  80. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_default_renderer.py +0 -0
  81. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_device.py +0 -0
  82. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_device_cli_integration.py +0 -0
  83. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_device_type.py +0 -0
  84. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_device_type_cli_integration.py +0 -0
  85. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_prompt.py +0 -0
  86. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_sentry.py +0 -0
  87. {doover_cli-0.4.1 → doover_cli-0.4.2}/tests/test_user.py +0 -0
  88. {doover_cli-0.4.1 → doover_cli-0.4.2}/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.4.1
3
+ Version: 0.4.2
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.4.1"
3
+ version = "0.4.2"
4
4
  description = "CLI for Doover"
5
5
  requires-python = ">=3.11"
6
6
  dependencies = [
@@ -104,6 +104,21 @@ def _resolve_staging(staging: bool | None) -> bool:
104
104
  return ".staging." in _control_base_url()
105
105
 
106
106
 
107
+ def _detect_git_commit(root_fp: Path) -> str:
108
+ """Best-effort current git commit SHA for the app dir (empty if unavailable)."""
109
+ try:
110
+ result = subprocess.run(
111
+ ["git", "rev-parse", "HEAD"],
112
+ cwd=root_fp,
113
+ capture_output=True,
114
+ text=True,
115
+ check=False,
116
+ )
117
+ except OSError:
118
+ return ""
119
+ return result.stdout.strip() if result.returncode == 0 else ""
120
+
121
+
107
122
  def _build_container(
108
123
  root_fp: Path, *, buildx: bool, build_args: str, image_name: str
109
124
  ) -> None:
@@ -1087,7 +1102,13 @@ def release(
1087
1102
  ] = None,
1088
1103
  tag: Annotated[
1089
1104
  str | None,
1090
- typer.Option(help="Optional version label (e.g. git sha / semver)."),
1105
+ typer.Option(help="Optional version label (e.g. semver / image tag)."),
1106
+ ] = None,
1107
+ commit: Annotated[
1108
+ str | None,
1109
+ typer.Option(
1110
+ help="Source git commit SHA (for browsing the code). Defaults to the repo's HEAD."
1111
+ ),
1091
1112
  ] = None,
1092
1113
  notes: Annotated[str, typer.Option(help="Optional release notes.")] = "",
1093
1114
  staging: Annotated[
@@ -1124,12 +1145,15 @@ def release(
1124
1145
  )
1125
1146
  raise typer.Exit(1)
1126
1147
 
1148
+ resolved_commit = commit if commit is not None else _detect_git_commit(root_fp)
1149
+
1127
1150
  client, renderer = get_state()
1128
1151
  with renderer.loading("Creating application version..."):
1129
1152
  version = client.create_application_version(
1130
1153
  application_id,
1131
1154
  digest=digest,
1132
1155
  tag=tag or "",
1156
+ commit=resolved_commit or "",
1133
1157
  notes=notes or "",
1134
1158
  )
1135
1159
  rich.print("[green]Released a new application version.[/green]")
@@ -306,16 +306,20 @@ def get_app_directory(root: Path | None = None) -> Path:
306
306
 
307
307
 
308
308
  def get_uv_path() -> Path:
309
- brew = Path("/opt/homebrew/bin/uv")
310
- if brew.exists():
311
- return brew
312
-
313
- uv_path = Path.home() / ".local" / "bin" / "uv"
314
- if not uv_path.exists():
315
- raise RuntimeError(
316
- "uv not found in your PATH. Please install it and try again."
317
- )
318
- return uv_path
309
+ # Prefer uv on PATH (covers CI where uv is installed to a tool cache dir),
310
+ # then common fixed locations.
311
+ found = shutil.which("uv")
312
+ if found:
313
+ return Path(found)
314
+
315
+ for candidate in (
316
+ Path("/opt/homebrew/bin/uv"),
317
+ Path.home() / ".local" / "bin" / "uv",
318
+ ):
319
+ if candidate.exists():
320
+ return candidate
321
+
322
+ raise RuntimeError("uv not found in your PATH. Please install it and try again.")
319
323
 
320
324
 
321
325
  def call_with_uv(
@@ -662,7 +662,9 @@ def test_app_publish_processor_type_without_ui_skips_ui_export(monkeypatch, tmp_
662
662
  assert "export_ui_called" not in captured
663
663
  assert captured["build_script"] == ("./build.sh", tmp_path)
664
664
  assert captured["processor_source"] == ("303", {"file": package_fp})
665
- assert renderer.render_calls == [{"id": 303, "versioned": True}]
665
+ # publish uploads the package but no longer cuts a version (that's `release`)
666
+ assert "processor_version" not in captured
667
+ assert renderer.render_calls == [{"id": 303}]
666
668
 
667
669
 
668
670
  def test_app_publish_skips_ui_export_when_config_disables_generation(
@@ -769,9 +771,7 @@ def test_app_publish_honours_explicit_staging(monkeypatch, tmp_path):
769
771
  lambda ctx, app_fp, validate_: None,
770
772
  )
771
773
 
772
- result = runner.invoke(
773
- app, ["app", "publish", str(tmp_path), "--staging"]
774
- )
774
+ result = runner.invoke(app, ["app", "publish", str(tmp_path), "--staging"])
775
775
 
776
776
  assert result.exit_code == 0
777
777
  assert captured["body"]["deployment_data"] == "staging-data"
@@ -872,9 +872,7 @@ def test_app_publish_skips_build_when_requested_by_config(monkeypatch, tmp_path)
872
872
  assert renderer.render_calls == [{"id": 101}]
873
873
 
874
874
 
875
- def test_app_publish_processor_builds_package_and_releases_version(
876
- monkeypatch, tmp_path
877
- ):
875
+ def test_app_publish_processor_builds_package_without_release(monkeypatch, tmp_path):
878
876
  captured = {}
879
877
  renderer = FakeRenderer()
880
878
  app_config = FakeAppConfig(app_id=303)
@@ -938,10 +936,11 @@ def test_app_publish_processor_builds_package_and_releases_version(
938
936
  assert captured["build_script"] == ("./build.sh", tmp_path)
939
937
  assert captured["application_id"] == "303"
940
938
  assert captured["body"] == {"file": package_fp}
941
- assert captured["version"][0] == "303"
939
+ # publish uploads the package; the version is cut by `doover app release`
940
+ assert "version" not in captured
942
941
  assert "build_called" not in captured
943
942
  assert "push_called" not in captured
944
- assert renderer.render_calls == [{"id": 303, "versioned": True}]
943
+ assert renderer.render_calls == [{"id": 303}]
945
944
 
946
945
 
947
946
  def test_publish_processor_package_uses_package_zip(tmp_path):
@@ -544,7 +544,7 @@ wheels = [
544
544
 
545
545
  [[package]]
546
546
  name = "doover-cli"
547
- version = "0.4.0"
547
+ version = "0.4.2"
548
548
  source = { editable = "." }
549
549
  dependencies = [
550
550
  { 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