doover-cli 0.6.2__tar.gz → 0.6.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.
- {doover_cli-0.6.2 → doover_cli-0.6.4}/PKG-INFO +1 -1
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/__init__.py +1 -1
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/apps/apps.py +42 -12
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/config_schema.py +6 -3
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/ui_schema.py +6 -3
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/apps.py +23 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_apps.py +2 -2
- {doover_cli-0.6.2 → doover_cli-0.6.4}/.github/CONTRIBUTING.md +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/.github/ISSUE_TEMPLATE/bug-report.yaml +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/.github/workflows/lint-test.yml +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/.github/workflows/release-brew.yml +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/.github/workflows/release-pypi.yml +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/.github/workflows/release.yml +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/.gitignore +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/.pre-commit-config.yaml +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/AGENT.md +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/LICENSE +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/README.md +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/debian/changelog +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/debian/control +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/debian/rules +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/docs/user_stories.md +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/pyproject.toml +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/agent.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/api/__init__.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/api/auth.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/api/errors.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/api/session.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/apps/app_install.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/apps/device.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/apps/device_type.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/apps/tunnel.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/channel.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/colours.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/dda_logs.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/doover_config.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/grpc.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/login.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/registry.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/renderer/__init__.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/renderer/_base.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/renderer/_basic.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/renderer/_default.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/renderer/_json.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/report.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/simulator.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/user.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/__init__.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/api.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/context.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/crud/__init__.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/crud/commands.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/crud/lookup.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/crud/prompting.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/crud/schema.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/crud/values.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/errors.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/formatters.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/misc.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/parsers.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/prompt.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/sentry.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/shell_commands.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/src/doover_cli/utils/state.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/__init__.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/conftest.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_agent.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_app_install.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_auth_integration.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_auth_unit.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_basic.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_crud_commands.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_crud_lookup.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_crud_prompting.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_crud_schema.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_crud_values.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_default_renderer.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_device.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_device_cli_integration.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_device_type.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_device_type_cli_integration.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_discover.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_prompt.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_registry.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_sentry.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_user.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/tests/test_utils_apps.py +0 -0
- {doover_cli-0.6.2 → doover_cli-0.6.4}/uv.lock +0 -0
|
@@ -299,6 +299,21 @@ def _resolve_application_id(client, app_config, *, staging: bool) -> int | None:
|
|
|
299
299
|
return None
|
|
300
300
|
|
|
301
301
|
|
|
302
|
+
def _image_package_uri(app_config) -> str | None:
|
|
303
|
+
"""The ECR image a processor deploys from, or None if it ships a package.zip.
|
|
304
|
+
|
|
305
|
+
A processor whose dependencies cannot fit Lambda's 250MB unzipped zip limit declares
|
|
306
|
+
`PackageType: "Image"` in `lambda_config` and names an image instead. Such an app has
|
|
307
|
+
no source archive at all, so the whole build-and-upload-a-zip path has to be skipped:
|
|
308
|
+
there is no ./build.sh to run, and the control plane rejects a processor_source
|
|
309
|
+
upload for it.
|
|
310
|
+
"""
|
|
311
|
+
lambda_config = getattr(app_config, "lambda_config", None) or {}
|
|
312
|
+
if lambda_config.get("PackageType") != "Image":
|
|
313
|
+
return None
|
|
314
|
+
return (lambda_config.get("Code") or {}).get("ImageUri")
|
|
315
|
+
|
|
316
|
+
|
|
302
317
|
def _publish_processor_package(
|
|
303
318
|
client,
|
|
304
319
|
app_id: int,
|
|
@@ -1172,20 +1187,32 @@ def publish(
|
|
|
1172
1187
|
rich.print("[green]Widget uploaded.[/green]")
|
|
1173
1188
|
|
|
1174
1189
|
if app_config.type in PACKAGE_APP_TYPES:
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1190
|
+
image_uri = _image_package_uri(app_config)
|
|
1191
|
+
if image_uri:
|
|
1192
|
+
# Nothing to build or upload: the deployable is already in ECR, and the
|
|
1193
|
+
# release below is what points the function at it.
|
|
1179
1194
|
print(
|
|
1180
|
-
"\
|
|
1195
|
+
f"\nProcessor deploys from a container image; skipping package.zip.\n"
|
|
1196
|
+
f" image: {image_uri}\n"
|
|
1197
|
+
f"Push the image before releasing, or the release will deploy whatever "
|
|
1198
|
+
f"that tag currently points at."
|
|
1181
1199
|
)
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1200
|
+
processor_response = None
|
|
1201
|
+
else:
|
|
1202
|
+
if build_package:
|
|
1203
|
+
print("\nBuilding package.zip for upload...")
|
|
1204
|
+
shell_run("sh ./build.sh", cwd=root_fp)
|
|
1205
|
+
else:
|
|
1206
|
+
print(
|
|
1207
|
+
"\nSkipping package.zip build (--no-build-package); using existing package.zip."
|
|
1208
|
+
)
|
|
1209
|
+
print("Uploading package.zip to Doover...")
|
|
1210
|
+
processor_response = _publish_processor_package(
|
|
1211
|
+
client,
|
|
1212
|
+
application_id,
|
|
1213
|
+
root_fp,
|
|
1214
|
+
)
|
|
1215
|
+
print("Done!")
|
|
1189
1216
|
renderer.render(processor_response or response)
|
|
1190
1217
|
if release:
|
|
1191
1218
|
ctx.invoke(
|
|
@@ -1303,6 +1330,9 @@ def discover(
|
|
|
1303
1330
|
)
|
|
1304
1331
|
raise typer.Exit(1)
|
|
1305
1332
|
|
|
1333
|
+
for entry in found:
|
|
1334
|
+
entry["dir"] = os.path.normpath(os.path.join(root, entry["dir"]))
|
|
1335
|
+
|
|
1306
1336
|
if as_json:
|
|
1307
1337
|
# Compact and on one line so it can be captured straight into a step output.
|
|
1308
1338
|
print(json.dumps(found, separators=(",", ":")))
|
|
@@ -8,6 +8,7 @@ import typer
|
|
|
8
8
|
import jsf
|
|
9
9
|
|
|
10
10
|
from .utils.apps import (
|
|
11
|
+
app_names_in_config,
|
|
11
12
|
get_app_directory,
|
|
12
13
|
call_with_uv,
|
|
13
14
|
get_app_config,
|
|
@@ -94,10 +95,12 @@ def validate(
|
|
|
94
95
|
config_file = root_fp / "doover_config.json"
|
|
95
96
|
|
|
96
97
|
if export_ is True:
|
|
97
|
-
|
|
98
|
-
# doover_config.json modified (e.g. when run as a pre-commit hook).
|
|
98
|
+
targets = [app_name] if app_name else app_names_in_config(root_fp) or [None]
|
|
99
99
|
with preserve_file(config_file):
|
|
100
|
-
|
|
100
|
+
for target in targets:
|
|
101
|
+
ctx.invoke(
|
|
102
|
+
export, ctx, app_fp=root_fp, validate_=False, app_name=target
|
|
103
|
+
)
|
|
101
104
|
_validate_config_file(config_file)
|
|
102
105
|
else:
|
|
103
106
|
_validate_config_file(config_file)
|
|
@@ -7,6 +7,7 @@ import rich
|
|
|
7
7
|
import typer
|
|
8
8
|
|
|
9
9
|
from .utils.apps import (
|
|
10
|
+
app_names_in_config,
|
|
10
11
|
get_app_directory,
|
|
11
12
|
call_with_uv,
|
|
12
13
|
get_app_config,
|
|
@@ -86,10 +87,12 @@ def validate(
|
|
|
86
87
|
config_file = root_fp / "doover_config.json"
|
|
87
88
|
|
|
88
89
|
if export_ is True:
|
|
89
|
-
|
|
90
|
-
# doover_config.json modified (e.g. when run as a pre-commit hook).
|
|
90
|
+
targets = [app_name] if app_name else app_names_in_config(root_fp) or [None]
|
|
91
91
|
with preserve_file(config_file):
|
|
92
|
-
|
|
92
|
+
for target in targets:
|
|
93
|
+
ctx.invoke(
|
|
94
|
+
export, ctx, app_fp=root_fp, validate_=False, app_name=target
|
|
95
|
+
)
|
|
93
96
|
_validate_ui_file(config_file)
|
|
94
97
|
else:
|
|
95
98
|
_validate_ui_file(config_file)
|
|
@@ -459,6 +459,29 @@ def get_docker_path() -> Path:
|
|
|
459
459
|
_selected_app_name: dict[Path, str] = {}
|
|
460
460
|
|
|
461
461
|
|
|
462
|
+
def app_names_in_config(root_fp: Path) -> list[str]:
|
|
463
|
+
"""Every app name declared in this directory's doover_config.json.
|
|
464
|
+
|
|
465
|
+
Never prompts, unlike `get_app_config`. For commands that act on the whole
|
|
466
|
+
file rather than one app — schema validation checks every app's schema, so
|
|
467
|
+
prompting for one would be asking a question whose answer does not matter, and
|
|
468
|
+
aborts outright when stdin is not a terminal (pre-commit, CI).
|
|
469
|
+
"""
|
|
470
|
+
config_path = root_fp / "doover_config.json"
|
|
471
|
+
if not config_path.exists():
|
|
472
|
+
return []
|
|
473
|
+
|
|
474
|
+
with open(config_path, "r") as file:
|
|
475
|
+
data = json.load(file)
|
|
476
|
+
|
|
477
|
+
# Same rule as get_app_config: `type` marks an app entry.
|
|
478
|
+
return [
|
|
479
|
+
v.get("name") or k
|
|
480
|
+
for k, v in data.items()
|
|
481
|
+
if isinstance(v, dict) and "type" in v
|
|
482
|
+
]
|
|
483
|
+
|
|
484
|
+
|
|
462
485
|
def get_app_config(root_fp: Path, app_name: str | None = None) -> Any:
|
|
463
486
|
config_path = root_fp / "doover_config.json"
|
|
464
487
|
if not config_path.exists():
|
|
@@ -706,7 +706,7 @@ def test_app_publish_processor_type_without_ui_skips_ui_export(monkeypatch, tmp_
|
|
|
706
706
|
|
|
707
707
|
assert result.exit_code == 0
|
|
708
708
|
assert "export_ui_called" not in captured
|
|
709
|
-
assert captured["build_script"] == ("./build.sh", tmp_path)
|
|
709
|
+
assert captured["build_script"] == ("sh ./build.sh", tmp_path)
|
|
710
710
|
assert captured["processor_source"] == ("303", {"file": package_fp})
|
|
711
711
|
# publish uploads the package but no longer cuts a version (that's `release`)
|
|
712
712
|
assert "processor_version" not in captured
|
|
@@ -981,7 +981,7 @@ def test_app_publish_processor_builds_package_without_release(monkeypatch, tmp_p
|
|
|
981
981
|
result = runner.invoke(app, ["app", "publish", str(tmp_path), "--no-release"])
|
|
982
982
|
|
|
983
983
|
assert result.exit_code == 0
|
|
984
|
-
assert captured["build_script"] == ("./build.sh", tmp_path)
|
|
984
|
+
assert captured["build_script"] == ("sh ./build.sh", tmp_path)
|
|
985
985
|
assert captured["application_id"] == "303"
|
|
986
986
|
assert captured["body"] == {"file": package_fp}
|
|
987
987
|
# publish uploads the package; the version is cut by `doover app release`
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|