terp-cli 0.5.2__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.
- terp_cli-0.5.4/PKG-INFO +16 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/pyproject.toml +8 -8
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/__init__.py +73 -16
- terp_cli-0.5.2/PKG-INFO +0 -16
- {terp_cli-0.5.2 → terp_cli-0.5.4}/.gitignore +0 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/_appref.py +0 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/access.py +0 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/apidocs.py +0 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/capabilities.py +0 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/dev.py +0 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/docker.py +0 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/grants.py +0 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/jobs.py +0 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/openapi.py +0 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/profiles.py +0 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/py.typed +0 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/scaffold.py +0 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/schema.py +0 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/seed.py +0 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/service_accounts.py +0 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/users.py +0 -0
- {terp_cli-0.5.2 → terp_cli-0.5.4}/src/terp/cli/verify.py +0 -0
terp_cli-0.5.4/PKG-INFO
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: terp-cli
|
|
3
|
+
Version: 0.5.4
|
|
4
|
+
Summary: Terp command-line tool — inspect, scaffolding, migrations, checks, api-docs.
|
|
5
|
+
License-Expression: Apache-2.0
|
|
6
|
+
Requires-Python: >=3.13
|
|
7
|
+
Requires-Dist: terp-arch==0.5.4
|
|
8
|
+
Requires-Dist: terp-core==0.5.4
|
|
9
|
+
Requires-Dist: terp-migrations==0.5.4
|
|
10
|
+
Provides-Extra: jobs
|
|
11
|
+
Requires-Dist: terp-cap-outbox==0.5.4; extra == 'jobs'
|
|
12
|
+
Requires-Dist: terp-cap-scheduler-apscheduler==0.5.4; extra == 'jobs'
|
|
13
|
+
Provides-Extra: scheduler
|
|
14
|
+
Requires-Dist: terp-cap-scheduler-apscheduler==0.5.4; extra == 'scheduler'
|
|
15
|
+
Provides-Extra: worker
|
|
16
|
+
Requires-Dist: terp-cap-outbox==0.5.4; extra == 'worker'
|
|
@@ -4,29 +4,29 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "terp-cli"
|
|
7
|
-
version = "0.5.
|
|
7
|
+
version = "0.5.4"
|
|
8
8
|
description = "Terp command-line tool — inspect, scaffolding, migrations, checks, api-docs."
|
|
9
9
|
requires-python = ">=3.13"
|
|
10
10
|
license = "Apache-2.0"
|
|
11
11
|
dependencies = [
|
|
12
|
-
"terp-core==0.5.
|
|
12
|
+
"terp-core==0.5.4",
|
|
13
13
|
# `terp migrate` delegates to terp-migrations (lazily imported), keeping Alembic
|
|
14
14
|
# off the path for `terp inspect` / `terp guide` while making migrations work.
|
|
15
|
-
"terp-migrations==0.5.
|
|
15
|
+
"terp-migrations==0.5.4",
|
|
16
16
|
# `terp guide rules` projects the live rule registry; terp-arch is imported lazily
|
|
17
17
|
# (only when that topic is rendered), so it stays off the common `terp guide` path.
|
|
18
|
-
"terp-arch==0.5.
|
|
18
|
+
"terp-arch==0.5.4",
|
|
19
19
|
]
|
|
20
20
|
|
|
21
21
|
# Job-process adapters stay optional: the base CLI must not install the table-owning outbox
|
|
22
22
|
# or a scheduler engine into apps that only use inspect/check/migrate. Deployments can select
|
|
23
23
|
# one process role, while `jobs` is the convenient complete jobs-process bundle.
|
|
24
24
|
[project.optional-dependencies]
|
|
25
|
-
worker = ["terp-cap-outbox==0.5.
|
|
26
|
-
scheduler = ["terp-cap-scheduler-apscheduler==0.5.
|
|
25
|
+
worker = ["terp-cap-outbox==0.5.4"]
|
|
26
|
+
scheduler = ["terp-cap-scheduler-apscheduler==0.5.4"]
|
|
27
27
|
jobs = [
|
|
28
|
-
"terp-cap-outbox==0.5.
|
|
29
|
-
"terp-cap-scheduler-apscheduler==0.5.
|
|
28
|
+
"terp-cap-outbox==0.5.4",
|
|
29
|
+
"terp-cap-scheduler-apscheduler==0.5.4",
|
|
30
30
|
]
|
|
31
31
|
|
|
32
32
|
[project.scripts]
|
|
@@ -372,25 +372,70 @@ Domain events (eventbus capability)
|
|
|
372
372
|
"testing": """\
|
|
373
373
|
Testing a Terp app (process-global runtime isolation)
|
|
374
374
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
and the decrypt call site. In a test process they outlive the app that installed them.
|
|
378
|
-
- You get isolation for free. terp-core ships a pytest plugin (terp.core.testing,
|
|
379
|
-
registered under pytest11) whose autouse fixture SNAPSHOTS every runtime before a
|
|
380
|
-
test and RESTORES it after. No conftest.py line, no opt-in. Without it a suite goes
|
|
381
|
-
order-dependent: green together, red alone - the sharpest failure mode there is,
|
|
382
|
-
because the green is the wrong answer.
|
|
383
|
-
- Isolation does not INSTALL a runtime your test needs - that is your decision:
|
|
375
|
+
WHAT YOU MUST STILL DO YOURSELF. The platform UNDOES a runtime; it never INSTALLS the
|
|
376
|
+
one your test needs. That distinction is the whole of testing on Terp:
|
|
384
377
|
* whole runtime -> compose the app in a fixture (see apps/example/tests/conftest.py,
|
|
385
378
|
where db_engine + app_db are function-scoped and build() runs per test)
|
|
386
379
|
* only the event bus -> the `terp_events` fixture, which installs a catalog
|
|
387
380
|
(and dispatcher) for the duration of one test:
|
|
388
381
|
terp_events(event_catalog, dispatcher=dispatch_in_process)
|
|
382
|
+
Annotate it `InstallEvents` (exported from terp.core.testing) - it carries
|
|
383
|
+
configure_events' real signature, so a wrong catalog is a type error.
|
|
389
384
|
* asserting on what was written to a FAKE/bare session -> `terp_default_runtime`,
|
|
390
385
|
which states the baseline instead of assuming it. Without it a composed app's
|
|
391
386
|
durable audit sink quietly adds audit rows to the session under assertion.
|
|
392
|
-
|
|
393
|
-
|
|
387
|
+
Deleting a conftest that INSTALLS something is not part of adopting the plugin.
|
|
388
|
+
|
|
389
|
+
WHAT YOU GET FOR FREE. terp-core ships a pytest plugin (terp.core.testing, registered
|
|
390
|
+
under pytest11) whose autouse fixture SNAPSHOTS every runtime before a test and
|
|
391
|
+
RESTORES it after. No conftest.py line, no opt-in. Without it a suite goes
|
|
392
|
+
order-dependent: green together, red alone - the sharpest failure mode there is,
|
|
393
|
+
because the green is the wrong answer.
|
|
394
|
+
|
|
395
|
+
THE SIX SEAMS. create_app installs six process globals per app; in a test process they
|
|
396
|
+
outlive the app that installed them. Restored automatically -- but installed by you:
|
|
397
|
+
|
|
398
|
+
seam what create_app installs who installs it in a test
|
|
399
|
+
audit audit policy + durable sink compose the app, else the log-only
|
|
400
|
+
default (terp_default_runtime)
|
|
401
|
+
events event catalog + dispatcher compose the app, or `terp_events`
|
|
402
|
+
jobs job catalog + queue compose the app
|
|
403
|
+
scheduling schedule catalog compose the app
|
|
404
|
+
passwords password policy compose the app, else the default
|
|
405
|
+
secrets the decrypt call site compose the app (a secrets capability)
|
|
406
|
+
|
|
407
|
+
STRICT MODE. Restoring is faithful, which is also its blind spot: a runtime installed
|
|
408
|
+
BEFORE the first test (a stray `import app.main` at collection time, a module-scope
|
|
409
|
+
create_app()) is part of the snapshot, so it is restored before every test and covers
|
|
410
|
+
every test equally - green together, red alone, with nothing having leaked. Strict mode
|
|
411
|
+
follows the snapshot with a RESET, so every test starts from the platform baseline and
|
|
412
|
+
a test that only ever passed on ambient state fails where it stands:
|
|
413
|
+
[tool.pytest.ini_options]
|
|
414
|
+
terp_strict_isolation = true # or: pytest --terp-strict-isolation
|
|
415
|
+
New projects start with it on, and the framework runs its own suites that way. Switching
|
|
416
|
+
it on in an existing suite can turn a green red - that red is the finding, not the
|
|
417
|
+
regression: the test was reading a runtime it never installed. Install it explicitly;
|
|
418
|
+
never re-order the suite.
|
|
419
|
+
|
|
420
|
+
AND READ THE GREEN HONESTLY. Strict mode resets BEFORE fixtures run, so it can only see
|
|
421
|
+
installs that happen before the suite. An autouse fixture that installs a runtime for a
|
|
422
|
+
whole package is invisible to it - every test gets a bus it never asked for, and strict
|
|
423
|
+
mode agrees with you every time. So: a green strict run does NOT mean your installs are
|
|
424
|
+
precise, only that none of them happen before the suite. Ask the other half instead:
|
|
425
|
+
uv run pytest --terp-report-runtime-installs
|
|
426
|
+
which reports, per seam, the tests that installed it. Read the SHAPE of the answer: one or
|
|
427
|
+
two ids under a seam is a test installing what it needs; every id in a package under one
|
|
428
|
+
seam is a fixture installing it for them. Then make that installer NAMED and non-autouse,
|
|
429
|
+
and let the tests that emit request it. The ones that then fail were the ones being carried.
|
|
430
|
+
|
|
431
|
+
TWO FIXTURES, ONE SEAM. A seam holds one runtime, so the last install wins - and pytest
|
|
432
|
+
decides "last" from the FIXTURE GRAPH, not from the order of your test's parameters. A tap
|
|
433
|
+
that installs a recording dispatcher after the catalog fixture must DEPEND on it:
|
|
434
|
+
@pytest.fixture
|
|
435
|
+
def emitted(events_runtime: None, terp_events: InstallEvents) -> list[object]:
|
|
436
|
+
...
|
|
437
|
+
Getting it the wrong way round is silent: the tap installs first, the catalog fixture
|
|
438
|
+
overwrites it, and the recorder simply records nothing.
|
|
394
439
|
""",
|
|
395
440
|
"jobs": """\
|
|
396
441
|
Background jobs (terp.core.enqueue + JobCatalog)
|
|
@@ -729,14 +774,26 @@ Data collections (DataView)
|
|
|
729
774
|
refused by the boundary lint. It gives search, sorting, pagination, column management,
|
|
730
775
|
selection + batch actions, row actions, expandable rows, and persisted view
|
|
731
776
|
preferences, driven by a repository port.
|
|
732
|
-
- Client-side (small collections — rows already in memory)
|
|
733
|
-
|
|
734
|
-
|
|
777
|
+
- Client-side (small collections — rows already in memory). The repository owns row
|
|
778
|
+
identity and value access; the component never reads a field itself:
|
|
779
|
+
const repo = useMemo(
|
|
780
|
+
() =>
|
|
781
|
+
new InMemoryDataViewRepository(rows, {
|
|
782
|
+
getRowId: (r) => r.id,
|
|
783
|
+
getValue: (r, col) => r[col as keyof Row],
|
|
784
|
+
searchFields: ["title", "status"],
|
|
785
|
+
}),
|
|
786
|
+
[rows],
|
|
787
|
+
);
|
|
788
|
+
<DataView repository={repo} columns={columns} viewId="notes.list" />
|
|
735
789
|
- Server-side (large collections — let the backend paginate/sort/filter):
|
|
736
790
|
const repo = useMemo(() => new HttpDataViewRepository({...}), [client]);
|
|
737
791
|
and keep query state in the URL with useServerDataView.
|
|
738
|
-
- Columns declare {
|
|
739
|
-
|
|
792
|
+
- Columns declare {id, header, accessor?, cell?, enableSorting?, meta?} — `id` is the
|
|
793
|
+
column key the repository's getValue receives, `accessor` reads the value and `cell`
|
|
794
|
+
renders it; header text is UiText. There is no `keyField` prop: row identity is
|
|
795
|
+
`getRowId` on the repository. Row actions and batch actions are declared as data
|
|
796
|
+
(the component renders the token-styled controls).
|
|
740
797
|
- Persist per-user view preferences via the ViewStateRepository seam
|
|
741
798
|
(LocalStorageViewStateRepository for the browser; InMemoryViewStateRepository in tests).
|
|
742
799
|
- For a simple titled CRUD list (no tables), ResourceList over useResource is the
|
terp_cli-0.5.2/PKG-INFO
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: terp-cli
|
|
3
|
-
Version: 0.5.2
|
|
4
|
-
Summary: Terp command-line tool — inspect, scaffolding, migrations, checks, api-docs.
|
|
5
|
-
License-Expression: Apache-2.0
|
|
6
|
-
Requires-Python: >=3.13
|
|
7
|
-
Requires-Dist: terp-arch==0.5.2
|
|
8
|
-
Requires-Dist: terp-core==0.5.2
|
|
9
|
-
Requires-Dist: terp-migrations==0.5.2
|
|
10
|
-
Provides-Extra: jobs
|
|
11
|
-
Requires-Dist: terp-cap-outbox==0.5.2; extra == 'jobs'
|
|
12
|
-
Requires-Dist: terp-cap-scheduler-apscheduler==0.5.2; extra == 'jobs'
|
|
13
|
-
Provides-Extra: scheduler
|
|
14
|
-
Requires-Dist: terp-cap-scheduler-apscheduler==0.5.2; extra == 'scheduler'
|
|
15
|
-
Provides-Extra: worker
|
|
16
|
-
Requires-Dist: terp-cap-outbox==0.5.2; extra == 'worker'
|
|
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
|