vortex-cli 6.0.0__tar.gz → 6.1.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.
- {vortex_cli-6.0.0/vortex_cli.egg-info → vortex_cli-6.1.0}/PKG-INFO +76 -13
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/README.md +75 -12
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/pyproject.toml +1 -1
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/cli.py +22 -6
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/clean.py +14 -13
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/clone.py +73 -49
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/compile.py +7 -2
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/config.py +1 -2
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/copy.py +29 -4
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/db.py +99 -11
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/delete.py +24 -10
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/export.py +16 -4
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/new.py +51 -17
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/pull.py +1 -1
- vortex_cli-6.1.0/vortex/commands/schema.py +669 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/watch.py +44 -7
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/gateway.py +64 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/main.py +35 -1
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/templates/agent/skills/vortex-workflow/SKILL.md +15 -11
- vortex_cli-6.1.0/vortex/webdesign.py +653 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0/vortex_cli.egg-info}/PKG-INFO +76 -13
- vortex_cli-6.0.0/vortex/commands/schema.py +0 -400
- vortex_cli-6.0.0/vortex/webdesign.py +0 -120
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/LICENSE +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/setup.cfg +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/__init__.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/__main__.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/colour.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/__init__.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/agenda.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/agent.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/code.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/docs.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/execute.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/find.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/grep.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/import_.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/libs.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/list.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/log.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/push.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/render.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/status.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/undo.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/commands/use.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/constants.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/docs/Blackbook v2.md +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/docs/Blackbook.pdf +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/docs/index.html +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/docs/marked.min.js +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/lib/puakma-6.0.40.jar +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/libs.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/logging.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/models.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/soap.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/spinner.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/templates/agent/AGENTS.md +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/templates/agent/skills/puakma-database/SKILL.md +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/templates/agent/skills/puakma-design-elements/SKILL.md +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/templates/agent/skills/puakma-overview/SKILL.md +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/templates/agent/vortex.code-snippets +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/util.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex/workspace.py +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex_cli.egg-info/SOURCES.txt +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex_cli.egg-info/dependency_links.txt +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex_cli.egg-info/entry_points.txt +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex_cli.egg-info/requires.txt +0 -0
- {vortex_cli-6.0.0 → vortex_cli-6.1.0}/vortex_cli.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vortex_cli
|
|
3
|
-
Version: 6.
|
|
3
|
+
Version: 6.1.0
|
|
4
4
|
Summary: Vortex CLI
|
|
5
5
|
Author-email: Jordan Amos <jordan.amos@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -150,15 +150,15 @@ For a full list of commands see `--help`.
|
|
|
150
150
|
- `code`: Open the workspace in Visual Studio Code (`-s <server>` opens that server's own workspace with exactly its jars on the Java classpath).
|
|
151
151
|
- `use`: Set the default server so you don't need to pass `--server` on every command. e.g. `vortex use production`
|
|
152
152
|
- `list` (or `ls`): List Puakma Applications on the server or cloned locally. (`ls` is an alias for `vortex list --local`)
|
|
153
|
-
- `clone`: Clone Puakma Applications and their design objects into the workspace. Apps can be referenced by ID (`vortex clone 13`), by TemplateName (`vortex clone bettrackr_app`), or by group/name (`vortex clone bettrackr/app`). A bare application group clones
|
|
153
|
+
- `clone`: Clone Puakma Applications and their design objects into the workspace. Apps can be referenced by ID (`vortex clone 13`), by TemplateName (`vortex clone bettrackr_app`), or by group/name (`vortex clone bettrackr/app`). A bare application group clones every active, non-inherited application in it (`vortex clone BetTrackr`; add `--all`/`-a` for the disabled and inherited ones too) - all optionally server-qualified (`dev:13`, `dev:bettrackr/app`, `dev:BetTrackr`). `--reclone` re-clones what is already cloned: every server's clones, or one server's with `--server`. See [Cloning a whole group](#cloning-a-whole-group).
|
|
154
154
|
- `watch`: Watch the workspace for changes to Design Objects and automatically upload them to the server each app was cloned from. Watches all servers at once unless `--server` is given.
|
|
155
155
|
- `clean`: Delete the locally cloned Puakma Application directories in the workspace.
|
|
156
156
|
Takes optional `APP_ID`s to clean just those clones (all of the server's, if none are
|
|
157
|
-
given).
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
server
|
|
161
|
-
|
|
157
|
+
given). Deletes immediately and needs no network - there is no undo. With `--check`
|
|
158
|
+
it first asks the server for its design element hashes and refuses to delete a clone
|
|
159
|
+
holding local changes the server doesn't have, naming each file; that needs a
|
|
160
|
+
reachable `backend=gateway` server, and a clone it can't verify is refused rather
|
|
161
|
+
than silently deleted.
|
|
162
162
|
- `config`: View and manage configuration. `--check-gateway` reports the agent gateway negotiation and which gateway roles your identity holds.
|
|
163
163
|
- `log`: View the server log.
|
|
164
164
|
- `status`: Show the server status - via the agent gateway when available, otherwise the raw console `status` output.
|
|
@@ -188,11 +188,16 @@ For a full list of commands see `--help`.
|
|
|
188
188
|
vortex clone 13 # by ID
|
|
189
189
|
vortex clone bettrackr_app # by TemplateName
|
|
190
190
|
vortex clone bettrackr/app # by group/name
|
|
191
|
-
vortex clone BetTrackr # every application in the BetTrackr group
|
|
191
|
+
vortex clone BetTrackr # every active application in the BetTrackr group
|
|
192
|
+
vortex clone -a BetTrackr # ... including its disabled and inherited ones
|
|
192
193
|
vortex clone dev:BetTrackr # ... on the 'dev' server
|
|
193
194
|
vortex clone --group BetTrackr # explicitly a group, never a TemplateName
|
|
194
195
|
```
|
|
195
196
|
|
|
197
|
+
A group clone skips disabled and inherited applications (the ones `vortex list`
|
|
198
|
+
hides by default) unless `--all`/`-a` is given. An application you name outright -
|
|
199
|
+
by ID, TemplateName or `group/name` - is always cloned, whatever its state.
|
|
200
|
+
|
|
196
201
|
Groups are matched the way `vortex list --group` matches them - a
|
|
197
202
|
case-insensitive substring - except that an exact (case-insensitive) group name
|
|
198
203
|
always wins, so cloning `BetTrackr` never drags in `BetTrackrLegacy`. If a
|
|
@@ -202,8 +207,8 @@ than cloning the lot.
|
|
|
202
207
|
A bare word is looked up as **both** a TemplateName and a group. In the rare
|
|
203
208
|
case that it is genuinely both, vortex refuses to guess: use `--group NAME` for
|
|
204
209
|
the group, or the ID / `group/name` for the single application. Every flag
|
|
205
|
-
(`--reclone`, `--get-resources`, `--open-urls`, `--timeout`, `--server`)
|
|
206
|
-
to group clones as it does to single apps.
|
|
210
|
+
(`--reclone`, `--all`, `--get-resources`, `--open-urls`, `--timeout`, `--server`)
|
|
211
|
+
applies to group clones as it does to single apps.
|
|
207
212
|
|
|
208
213
|
### Working with Multiple Servers
|
|
209
214
|
|
|
@@ -303,7 +308,10 @@ backend = gateway ; default is 'soap', which never contacts the gatew
|
|
|
303
308
|
|
|
304
309
|
With `backend = gateway`, `watch`/`push` uploads, `delete`, `log`, `status`, `db`, `execute`
|
|
305
310
|
and the journal commands route through it, and `agenda`, `pull`, `render` and `undo` become
|
|
306
|
-
available.
|
|
311
|
+
available. Everything the gateway does not offer goes to the **webdesign vortex API** (the
|
|
312
|
+
JSON action served by `system/webdesign`) - see [SOAP-free on backend = gateway](#soap-free-on-backend--gateway).
|
|
313
|
+
A `backend = gateway` server never talks to SOAPDesigner at all. Check what you are talking
|
|
314
|
+
to and what you may do:
|
|
307
315
|
|
|
308
316
|
```
|
|
309
317
|
vortex config --check-gateway -s dev
|
|
@@ -313,8 +321,9 @@ vortex config --check-gateway -s dev
|
|
|
313
321
|
identity lacks the required role) is reported as an error - vortex never quietly retries the
|
|
314
322
|
same operation over SOAP, because that would let anyone with SOAP access bypass every role,
|
|
315
323
|
journal and guardrail above. Likewise `backend = soap` never contacts the gateway. The one
|
|
316
|
-
deliberate exception is the gateway application's *own* deployments, which
|
|
317
|
-
|
|
324
|
+
deliberate exception is the gateway application's *own* deployments, which never go through
|
|
325
|
+
the gateway (webdesign on `backend = gateway`, SOAP on `backend = soap`) so that a broken
|
|
326
|
+
gateway deploy never needs the gateway to fix itself.
|
|
318
327
|
|
|
319
328
|
The gateway application is **not bundled with this CLI** - deploy it to a server with
|
|
320
329
|
`vortex export` / `vortex import`, then run its `Setup` scheduled action. It ships its own
|
|
@@ -326,6 +335,55 @@ the running server documents its own endpoints, roles and setup steps.
|
|
|
326
335
|
> grant itself any role. Keep webdesign access for operators; agent identities should not have
|
|
327
336
|
> it.
|
|
328
337
|
|
|
338
|
+
### SOAP-free on `backend = gateway`
|
|
339
|
+
|
|
340
|
+
SOAPDesigner is legacy. On a `backend = gateway` server the commands the gateway does not
|
|
341
|
+
cover use the JSON API of `system/webdesign`'s `vortex` action instead - with the same
|
|
342
|
+
credentials, and the webdesign app's own ACL. SOAP is used only when a server is explicitly
|
|
343
|
+
`backend = soap`. The data dictionary (`schema`, `db --list/--schema`) is the exception that
|
|
344
|
+
proves the rule: the gateway's `dictionary` endpoint runs that same webdesign `vortex` action
|
|
345
|
+
server-side behind `GatewayDBRead`/`GatewayDBWrite`, so an agent identity with no webdesign
|
|
346
|
+
access gets a clean role answer rather than a login page, and a change to `vortex.java`
|
|
347
|
+
needs no change to the gateway.
|
|
348
|
+
|
|
349
|
+
| Command | `backend = gateway` | `backend = soap` |
|
|
350
|
+
|---|---|---|
|
|
351
|
+
| `push`, `watch` (modify), `compile --upload` | gateway `upload` (journalled); the gateway app itself: webdesign `PUT design` | SOAP `uploadDesign` |
|
|
352
|
+
| `watch` (create / delete) | webdesign `POST` / `DELETE design` | SOAP |
|
|
353
|
+
| `delete` | gateway `delete` (journalled); the gateway app itself: webdesign | SOAP |
|
|
354
|
+
| `copy`, `new object` | webdesign `POST`/`PUT design`, `PUT design/params` | SOAP |
|
|
355
|
+
| `new app` | webdesign `POST vortex` | SOAP `saveApplication` |
|
|
356
|
+
| `new keyword` | gateway `keyword` (upsert) | SOAP `saveKeyword` |
|
|
357
|
+
| `schema`, `db --list`, `db --schema` | gateway `dictionary` (webdesign's `database`/`table`/`column` routes run server-side; `GatewayDBRead`/`GatewayDBWrite`) | SOAP SQL + `savePuakma*` |
|
|
358
|
+
| `export` | webdesign `ExportPMX` action | SOAP `downloadPmx` |
|
|
359
|
+
| `import` | **still SOAP** - webdesign has no import route yet | SOAP `uploadPmx` |
|
|
360
|
+
| `db --sql`, `list`, `log`, `execute`, `status`, `clone`, `pull` | gateway | SOAP |
|
|
361
|
+
|
|
362
|
+
Where the webdesign API behaves differently from SOAP, the CLI compensates so the commands
|
|
363
|
+
behave as they did. The differences that remain visible:
|
|
364
|
+
|
|
365
|
+
- **Design element writes are whole-row.** The CLI reads the row back first and re-sends what
|
|
366
|
+
it does not model (the other blob, `Options`), so a `DATA`-only upload never wipes source.
|
|
367
|
+
One consequence: every write is one extra `GET`.
|
|
368
|
+
- **Renaming with `new object --update --name` does not rewrite references.** SOAP's
|
|
369
|
+
`updateDesignObject` also updated design params in the app that referred to the old name;
|
|
370
|
+
the webdesign route does not. Fix `OpenAction`/`ParentPage`-style params by hand after a rename.
|
|
371
|
+
- **`schema` cannot record `--default`, `--position` or the column half of `--ref`.** The
|
|
372
|
+
webdesign column write has no `DefaultValue`/`Position`/`RefColumn` fields (SOAP's
|
|
373
|
+
`savePuakmaAttribute2` had them). `--default`/`--position` are refused with a message;
|
|
374
|
+
`--ref TABLE.COLUMN` records the table and warns. Updates leave existing values untouched.
|
|
375
|
+
Extend `POST`/`PUT .../column` in webdesign's `vortex.java` to lift this.
|
|
376
|
+
- **Every write flushes the application's design cache**, where SOAP flushed one element.
|
|
377
|
+
- **No per-application `Developer` role check** - the webdesign app's ACL is the boundary. An
|
|
378
|
+
identity that can reach `system/webdesign` can edit every application through it.
|
|
379
|
+
- **`db --list` orders by table name** (SOAP's `SELECT DISTINCT` had no order); `--schema`
|
|
380
|
+
output is identical.
|
|
381
|
+
- **Database-name resolution is app-scoped.** `schema`/`db --list` find the connection whose
|
|
382
|
+
dictionary holds the tables (as SOAP did by `pmatable` count), asking locally cloned
|
|
383
|
+
applications first and scanning the server inventory only if none of them has it.
|
|
384
|
+
- **`import` remains SOAP** on every backend until webdesign gains a PMX import route
|
|
385
|
+
(`SaveImportPMX` is a multipart UI form, not an API).
|
|
386
|
+
|
|
329
387
|
### Interactive Wizards
|
|
330
388
|
|
|
331
389
|
Run `vortex new object` or `vortex new app` without any flags to launch a step-by-step wizard:
|
|
@@ -421,6 +479,11 @@ vortex schema mydb --add-column invoice customer_id --type BIGINT --ref customer
|
|
|
421
479
|
vortex schema mydb --ddl invoice # print CREATE TABLE from the dictionary
|
|
422
480
|
```
|
|
423
481
|
|
|
482
|
+
On a `backend = gateway` server the dictionary is reached through webdesign's vortex API via
|
|
483
|
+
the gateway's `dictionary` endpoint (`GatewayDBRead` to read, `GatewayDBWrite` to change).
|
|
484
|
+
That API cannot record `--default` or `--position` (refused) nor the column half of `--ref`
|
|
485
|
+
(warned) - see [SOAP-free on backend = gateway](#soap-free-on-backend--gateway).
|
|
486
|
+
|
|
424
487
|
### Agent Support Files
|
|
425
488
|
|
|
426
489
|
`vortex agent` copies bundled support files into the workspace `.vscode` directory so they are
|
|
@@ -106,15 +106,15 @@ For a full list of commands see `--help`.
|
|
|
106
106
|
- `code`: Open the workspace in Visual Studio Code (`-s <server>` opens that server's own workspace with exactly its jars on the Java classpath).
|
|
107
107
|
- `use`: Set the default server so you don't need to pass `--server` on every command. e.g. `vortex use production`
|
|
108
108
|
- `list` (or `ls`): List Puakma Applications on the server or cloned locally. (`ls` is an alias for `vortex list --local`)
|
|
109
|
-
- `clone`: Clone Puakma Applications and their design objects into the workspace. Apps can be referenced by ID (`vortex clone 13`), by TemplateName (`vortex clone bettrackr_app`), or by group/name (`vortex clone bettrackr/app`). A bare application group clones
|
|
109
|
+
- `clone`: Clone Puakma Applications and their design objects into the workspace. Apps can be referenced by ID (`vortex clone 13`), by TemplateName (`vortex clone bettrackr_app`), or by group/name (`vortex clone bettrackr/app`). A bare application group clones every active, non-inherited application in it (`vortex clone BetTrackr`; add `--all`/`-a` for the disabled and inherited ones too) - all optionally server-qualified (`dev:13`, `dev:bettrackr/app`, `dev:BetTrackr`). `--reclone` re-clones what is already cloned: every server's clones, or one server's with `--server`. See [Cloning a whole group](#cloning-a-whole-group).
|
|
110
110
|
- `watch`: Watch the workspace for changes to Design Objects and automatically upload them to the server each app was cloned from. Watches all servers at once unless `--server` is given.
|
|
111
111
|
- `clean`: Delete the locally cloned Puakma Application directories in the workspace.
|
|
112
112
|
Takes optional `APP_ID`s to clean just those clones (all of the server's, if none are
|
|
113
|
-
given).
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
server
|
|
117
|
-
|
|
113
|
+
given). Deletes immediately and needs no network - there is no undo. With `--check`
|
|
114
|
+
it first asks the server for its design element hashes and refuses to delete a clone
|
|
115
|
+
holding local changes the server doesn't have, naming each file; that needs a
|
|
116
|
+
reachable `backend=gateway` server, and a clone it can't verify is refused rather
|
|
117
|
+
than silently deleted.
|
|
118
118
|
- `config`: View and manage configuration. `--check-gateway` reports the agent gateway negotiation and which gateway roles your identity holds.
|
|
119
119
|
- `log`: View the server log.
|
|
120
120
|
- `status`: Show the server status - via the agent gateway when available, otherwise the raw console `status` output.
|
|
@@ -144,11 +144,16 @@ For a full list of commands see `--help`.
|
|
|
144
144
|
vortex clone 13 # by ID
|
|
145
145
|
vortex clone bettrackr_app # by TemplateName
|
|
146
146
|
vortex clone bettrackr/app # by group/name
|
|
147
|
-
vortex clone BetTrackr # every application in the BetTrackr group
|
|
147
|
+
vortex clone BetTrackr # every active application in the BetTrackr group
|
|
148
|
+
vortex clone -a BetTrackr # ... including its disabled and inherited ones
|
|
148
149
|
vortex clone dev:BetTrackr # ... on the 'dev' server
|
|
149
150
|
vortex clone --group BetTrackr # explicitly a group, never a TemplateName
|
|
150
151
|
```
|
|
151
152
|
|
|
153
|
+
A group clone skips disabled and inherited applications (the ones `vortex list`
|
|
154
|
+
hides by default) unless `--all`/`-a` is given. An application you name outright -
|
|
155
|
+
by ID, TemplateName or `group/name` - is always cloned, whatever its state.
|
|
156
|
+
|
|
152
157
|
Groups are matched the way `vortex list --group` matches them - a
|
|
153
158
|
case-insensitive substring - except that an exact (case-insensitive) group name
|
|
154
159
|
always wins, so cloning `BetTrackr` never drags in `BetTrackrLegacy`. If a
|
|
@@ -158,8 +163,8 @@ than cloning the lot.
|
|
|
158
163
|
A bare word is looked up as **both** a TemplateName and a group. In the rare
|
|
159
164
|
case that it is genuinely both, vortex refuses to guess: use `--group NAME` for
|
|
160
165
|
the group, or the ID / `group/name` for the single application. Every flag
|
|
161
|
-
(`--reclone`, `--get-resources`, `--open-urls`, `--timeout`, `--server`)
|
|
162
|
-
to group clones as it does to single apps.
|
|
166
|
+
(`--reclone`, `--all`, `--get-resources`, `--open-urls`, `--timeout`, `--server`)
|
|
167
|
+
applies to group clones as it does to single apps.
|
|
163
168
|
|
|
164
169
|
### Working with Multiple Servers
|
|
165
170
|
|
|
@@ -259,7 +264,10 @@ backend = gateway ; default is 'soap', which never contacts the gatew
|
|
|
259
264
|
|
|
260
265
|
With `backend = gateway`, `watch`/`push` uploads, `delete`, `log`, `status`, `db`, `execute`
|
|
261
266
|
and the journal commands route through it, and `agenda`, `pull`, `render` and `undo` become
|
|
262
|
-
available.
|
|
267
|
+
available. Everything the gateway does not offer goes to the **webdesign vortex API** (the
|
|
268
|
+
JSON action served by `system/webdesign`) - see [SOAP-free on backend = gateway](#soap-free-on-backend--gateway).
|
|
269
|
+
A `backend = gateway` server never talks to SOAPDesigner at all. Check what you are talking
|
|
270
|
+
to and what you may do:
|
|
263
271
|
|
|
264
272
|
```
|
|
265
273
|
vortex config --check-gateway -s dev
|
|
@@ -269,8 +277,9 @@ vortex config --check-gateway -s dev
|
|
|
269
277
|
identity lacks the required role) is reported as an error - vortex never quietly retries the
|
|
270
278
|
same operation over SOAP, because that would let anyone with SOAP access bypass every role,
|
|
271
279
|
journal and guardrail above. Likewise `backend = soap` never contacts the gateway. The one
|
|
272
|
-
deliberate exception is the gateway application's *own* deployments, which
|
|
273
|
-
|
|
280
|
+
deliberate exception is the gateway application's *own* deployments, which never go through
|
|
281
|
+
the gateway (webdesign on `backend = gateway`, SOAP on `backend = soap`) so that a broken
|
|
282
|
+
gateway deploy never needs the gateway to fix itself.
|
|
274
283
|
|
|
275
284
|
The gateway application is **not bundled with this CLI** - deploy it to a server with
|
|
276
285
|
`vortex export` / `vortex import`, then run its `Setup` scheduled action. It ships its own
|
|
@@ -282,6 +291,55 @@ the running server documents its own endpoints, roles and setup steps.
|
|
|
282
291
|
> grant itself any role. Keep webdesign access for operators; agent identities should not have
|
|
283
292
|
> it.
|
|
284
293
|
|
|
294
|
+
### SOAP-free on `backend = gateway`
|
|
295
|
+
|
|
296
|
+
SOAPDesigner is legacy. On a `backend = gateway` server the commands the gateway does not
|
|
297
|
+
cover use the JSON API of `system/webdesign`'s `vortex` action instead - with the same
|
|
298
|
+
credentials, and the webdesign app's own ACL. SOAP is used only when a server is explicitly
|
|
299
|
+
`backend = soap`. The data dictionary (`schema`, `db --list/--schema`) is the exception that
|
|
300
|
+
proves the rule: the gateway's `dictionary` endpoint runs that same webdesign `vortex` action
|
|
301
|
+
server-side behind `GatewayDBRead`/`GatewayDBWrite`, so an agent identity with no webdesign
|
|
302
|
+
access gets a clean role answer rather than a login page, and a change to `vortex.java`
|
|
303
|
+
needs no change to the gateway.
|
|
304
|
+
|
|
305
|
+
| Command | `backend = gateway` | `backend = soap` |
|
|
306
|
+
|---|---|---|
|
|
307
|
+
| `push`, `watch` (modify), `compile --upload` | gateway `upload` (journalled); the gateway app itself: webdesign `PUT design` | SOAP `uploadDesign` |
|
|
308
|
+
| `watch` (create / delete) | webdesign `POST` / `DELETE design` | SOAP |
|
|
309
|
+
| `delete` | gateway `delete` (journalled); the gateway app itself: webdesign | SOAP |
|
|
310
|
+
| `copy`, `new object` | webdesign `POST`/`PUT design`, `PUT design/params` | SOAP |
|
|
311
|
+
| `new app` | webdesign `POST vortex` | SOAP `saveApplication` |
|
|
312
|
+
| `new keyword` | gateway `keyword` (upsert) | SOAP `saveKeyword` |
|
|
313
|
+
| `schema`, `db --list`, `db --schema` | gateway `dictionary` (webdesign's `database`/`table`/`column` routes run server-side; `GatewayDBRead`/`GatewayDBWrite`) | SOAP SQL + `savePuakma*` |
|
|
314
|
+
| `export` | webdesign `ExportPMX` action | SOAP `downloadPmx` |
|
|
315
|
+
| `import` | **still SOAP** - webdesign has no import route yet | SOAP `uploadPmx` |
|
|
316
|
+
| `db --sql`, `list`, `log`, `execute`, `status`, `clone`, `pull` | gateway | SOAP |
|
|
317
|
+
|
|
318
|
+
Where the webdesign API behaves differently from SOAP, the CLI compensates so the commands
|
|
319
|
+
behave as they did. The differences that remain visible:
|
|
320
|
+
|
|
321
|
+
- **Design element writes are whole-row.** The CLI reads the row back first and re-sends what
|
|
322
|
+
it does not model (the other blob, `Options`), so a `DATA`-only upload never wipes source.
|
|
323
|
+
One consequence: every write is one extra `GET`.
|
|
324
|
+
- **Renaming with `new object --update --name` does not rewrite references.** SOAP's
|
|
325
|
+
`updateDesignObject` also updated design params in the app that referred to the old name;
|
|
326
|
+
the webdesign route does not. Fix `OpenAction`/`ParentPage`-style params by hand after a rename.
|
|
327
|
+
- **`schema` cannot record `--default`, `--position` or the column half of `--ref`.** The
|
|
328
|
+
webdesign column write has no `DefaultValue`/`Position`/`RefColumn` fields (SOAP's
|
|
329
|
+
`savePuakmaAttribute2` had them). `--default`/`--position` are refused with a message;
|
|
330
|
+
`--ref TABLE.COLUMN` records the table and warns. Updates leave existing values untouched.
|
|
331
|
+
Extend `POST`/`PUT .../column` in webdesign's `vortex.java` to lift this.
|
|
332
|
+
- **Every write flushes the application's design cache**, where SOAP flushed one element.
|
|
333
|
+
- **No per-application `Developer` role check** - the webdesign app's ACL is the boundary. An
|
|
334
|
+
identity that can reach `system/webdesign` can edit every application through it.
|
|
335
|
+
- **`db --list` orders by table name** (SOAP's `SELECT DISTINCT` had no order); `--schema`
|
|
336
|
+
output is identical.
|
|
337
|
+
- **Database-name resolution is app-scoped.** `schema`/`db --list` find the connection whose
|
|
338
|
+
dictionary holds the tables (as SOAP did by `pmatable` count), asking locally cloned
|
|
339
|
+
applications first and scanning the server inventory only if none of them has it.
|
|
340
|
+
- **`import` remains SOAP** on every backend until webdesign gains a PMX import route
|
|
341
|
+
(`SaveImportPMX` is a multipart UI form, not an API).
|
|
342
|
+
|
|
285
343
|
### Interactive Wizards
|
|
286
344
|
|
|
287
345
|
Run `vortex new object` or `vortex new app` without any flags to launch a step-by-step wizard:
|
|
@@ -377,6 +435,11 @@ vortex schema mydb --add-column invoice customer_id --type BIGINT --ref customer
|
|
|
377
435
|
vortex schema mydb --ddl invoice # print CREATE TABLE from the dictionary
|
|
378
436
|
```
|
|
379
437
|
|
|
438
|
+
On a `backend = gateway` server the dictionary is reached through webdesign's vortex API via
|
|
439
|
+
the gateway's `dictionary` endpoint (`GatewayDBRead` to read, `GatewayDBWrite` to change).
|
|
440
|
+
That API cannot record `--default` or `--position` (refused) nor the column half of `--ref`
|
|
441
|
+
(warned) - see [SOAP-free on backend = gateway](#soap-free-on-backend--gateway).
|
|
442
|
+
|
|
380
443
|
### Agent Support Files
|
|
381
444
|
|
|
382
445
|
`vortex agent` copies bundled support files into the workspace `.vscode` directory so they are
|
|
@@ -410,8 +410,22 @@ def add_clone_parser(
|
|
|
410
410
|
)
|
|
411
411
|
clone_parser.add_argument(
|
|
412
412
|
"--reclone",
|
|
413
|
-
help=
|
|
413
|
+
help=(
|
|
414
|
+
"Reclone the locally cloned applications: every server's "
|
|
415
|
+
"clones, or only those of the given --server"
|
|
416
|
+
),
|
|
417
|
+
action="store_true",
|
|
418
|
+
)
|
|
419
|
+
clone_parser.add_argument(
|
|
420
|
+
"--all",
|
|
421
|
+
"-a",
|
|
422
|
+
dest="include_all",
|
|
414
423
|
action="store_true",
|
|
424
|
+
help=(
|
|
425
|
+
"When cloning a group, also clone its disabled and inherited "
|
|
426
|
+
"applications (skipped by default). An application named "
|
|
427
|
+
"outright is always cloned"
|
|
428
|
+
),
|
|
415
429
|
)
|
|
416
430
|
clone_parser.add_argument(
|
|
417
431
|
"--get-resources",
|
|
@@ -504,8 +518,8 @@ def add_clean_parser(command_parser: _SubParsersAction[ArgumentParser]) -> None:
|
|
|
504
518
|
"clean",
|
|
505
519
|
help=(
|
|
506
520
|
"Delete the cloned Puakma Application directories in the "
|
|
507
|
-
"workspace.
|
|
508
|
-
"
|
|
521
|
+
"workspace. There is no undo; --check first asks the server "
|
|
522
|
+
"whether a clone holds local changes it doesn't have"
|
|
509
523
|
),
|
|
510
524
|
)
|
|
511
525
|
clean_parser.add_argument(
|
|
@@ -525,11 +539,13 @@ def add_clean_parser(command_parser: _SubParsersAction[ArgumentParser]) -> None:
|
|
|
525
539
|
action="store_true",
|
|
526
540
|
)
|
|
527
541
|
clean_parser.add_argument(
|
|
528
|
-
"--
|
|
542
|
+
"--check",
|
|
529
543
|
action="store_true",
|
|
530
544
|
help=(
|
|
531
|
-
"
|
|
532
|
-
"
|
|
545
|
+
"Before deleting, verify each clone against the server's design "
|
|
546
|
+
"element hashes and refuse any holding local changes the server "
|
|
547
|
+
"doesn't have (or that can't be verified). Needs a reachable "
|
|
548
|
+
"backend=gateway server"
|
|
533
549
|
),
|
|
534
550
|
)
|
|
535
551
|
clean_parser.add_argument(
|
|
@@ -9,20 +9,21 @@ the same 'app_ids: list[int] | None' convention 'vortex pull' and
|
|
|
9
9
|
'vortex push' use, APPLICATION ids, not the design-element ids
|
|
10
10
|
'vortex delete' takes - narrows it to those clones.
|
|
11
11
|
|
|
12
|
-
THE SAFETY GATE. There is no undo and no git inside an app
|
|
13
|
-
clean refuses to delete a clone holding local
|
|
14
|
-
have, naming each file
|
|
12
|
+
THE OPT-IN SAFETY GATE. There is no undo and no git inside an app
|
|
13
|
+
folder. With --check, clean refuses to delete a clone holding local
|
|
14
|
+
work the server does not have, naming each file. Deciding that is the
|
|
15
15
|
same three-way comparison pull makes (see pull.local_modifications)
|
|
16
16
|
and it CANNOT be done offline: 'vortex push' does not move the
|
|
17
17
|
manifest baseline, so after a push the local file differs from the
|
|
18
18
|
baseline while matching the server. Telling 'already pushed, safe'
|
|
19
|
-
from 'unsaved work' needs the server's hashes, which makes a
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
from 'unsaved work' needs the server's hashes, which makes --check a
|
|
20
|
+
network operation - one round trip per clone, and slow on a workspace
|
|
21
|
+
with many. That is why it is opt-in: a plain 'vortex clean' deletes
|
|
22
|
+
without asking the server anything (and so works offline). When
|
|
23
|
+
--check is given and the server can't answer - unreachable, refusing,
|
|
24
|
+
or backend=soap, which has no hash endpoint at all - the clone is
|
|
25
|
+
UNVERIFIABLE and clean refuses it rather than silently skipping the
|
|
26
|
+
gate exactly when it was asked for.
|
|
26
27
|
"""
|
|
27
28
|
|
|
28
29
|
from __future__ import annotations
|
|
@@ -100,7 +101,7 @@ def _apply_gate(
|
|
|
100
101
|
logger.error(
|
|
101
102
|
f"{len(blocked)} application(s) hold unsaved local work (or could "
|
|
102
103
|
"not be verified against the server) - push or pull them, or "
|
|
103
|
-
"re-run
|
|
104
|
+
"re-run without --check to discard them. There is no undo"
|
|
104
105
|
)
|
|
105
106
|
return blocked
|
|
106
107
|
|
|
@@ -112,7 +113,7 @@ def clean(
|
|
|
112
113
|
include_libs: bool = False,
|
|
113
114
|
app_ids: list[int] | None = None,
|
|
114
115
|
*,
|
|
115
|
-
|
|
116
|
+
check: bool = False,
|
|
116
117
|
) -> int:
|
|
117
118
|
cloned_apps = workspace.listapps(None if include_all else server)
|
|
118
119
|
|
|
@@ -124,7 +125,7 @@ def clean(
|
|
|
124
125
|
return 1
|
|
125
126
|
cloned_apps = [app for app in cloned_apps if app.id in wanted]
|
|
126
127
|
|
|
127
|
-
if
|
|
128
|
+
if check and cloned_apps:
|
|
128
129
|
if _apply_gate(workspace, cloned_apps):
|
|
129
130
|
return 1
|
|
130
131
|
|
|
@@ -421,40 +421,28 @@ def _fetch_apps(
|
|
|
421
421
|
group_filter: list[str],
|
|
422
422
|
template_filter: list[str],
|
|
423
423
|
strict_search: bool,
|
|
424
|
+
include_all: bool = True,
|
|
424
425
|
) -> list[PuakmaApplication]:
|
|
425
426
|
"""
|
|
426
|
-
Applications matching the filters
|
|
427
|
-
|
|
428
|
-
the list command
|
|
429
|
-
|
|
427
|
+
Applications matching the filters - via the gateway when negotiated
|
|
428
|
+
(client-side filtering), otherwise the SOAP query - with exactly the
|
|
429
|
+
matching semantics of the list command on either backend. Inherited
|
|
430
|
+
and disabled applications are included only with include_all: an
|
|
431
|
+
explicitly named application is always looked up in full (the user
|
|
432
|
+
named it), a group expansion skips them unless 'clone --all'.
|
|
430
433
|
"""
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
"this identity needs GatewayDesignRead (or Admin)"
|
|
444
|
-
) from e
|
|
445
|
-
apps = [
|
|
446
|
-
PuakmaApplication(
|
|
447
|
-
gw_app.id,
|
|
448
|
-
gw_app.name,
|
|
449
|
-
gw_app.group,
|
|
450
|
-
gw_app.inherit_from or "",
|
|
451
|
-
gw_app.template_name or "",
|
|
452
|
-
server.host,
|
|
453
|
-
server_name=server.name,
|
|
454
|
-
)
|
|
455
|
-
for gw_app in gateway_apps
|
|
456
|
-
]
|
|
457
|
-
return _filter_apps(apps, name_filter, group_filter, template_filter, strict_search)
|
|
434
|
+
from vortex.commands.list import _fetch_apps as _list_fetch_apps
|
|
435
|
+
|
|
436
|
+
apps, _extras = _list_fetch_apps(
|
|
437
|
+
server,
|
|
438
|
+
name_filter,
|
|
439
|
+
group_filter,
|
|
440
|
+
template_filter,
|
|
441
|
+
strict_search,
|
|
442
|
+
include_all,
|
|
443
|
+
include_all,
|
|
444
|
+
)
|
|
445
|
+
return apps
|
|
458
446
|
|
|
459
447
|
|
|
460
448
|
def _resolve_one(
|
|
@@ -476,29 +464,53 @@ def _resolve_one(
|
|
|
476
464
|
return [app.id]
|
|
477
465
|
|
|
478
466
|
|
|
479
|
-
def _fetch_group_apps(
|
|
467
|
+
def _fetch_group_apps(
|
|
468
|
+
server: PuakmaServer, group: str, include_all: bool = False
|
|
469
|
+
) -> list[PuakmaApplication]:
|
|
480
470
|
"""
|
|
481
471
|
Applications whose group matches `group`, matched the way
|
|
482
472
|
'vortex list --group' matches groups - a case-insensitive substring.
|
|
483
473
|
An exact (case-insensitive) group name always wins, so cloning
|
|
484
|
-
'BetTrackr' never drags in 'BetTrackrLegacy'.
|
|
485
|
-
|
|
474
|
+
'BetTrackr' never drags in 'BetTrackrLegacy'. Inherited and disabled
|
|
475
|
+
applications are left out unless include_all ('clone --all').
|
|
486
476
|
"""
|
|
487
|
-
apps = _fetch_apps(server, [], [group], [], False)
|
|
477
|
+
apps = _fetch_apps(server, [], [group], [], False, include_all)
|
|
488
478
|
exact = [app for app in apps if (app.group or "").casefold() == group.casefold()]
|
|
489
479
|
return exact or apps
|
|
490
480
|
|
|
491
481
|
|
|
482
|
+
def _group_has_only_hidden_apps(
|
|
483
|
+
server: PuakmaServer, group: str, include_all: bool
|
|
484
|
+
) -> bool:
|
|
485
|
+
"""
|
|
486
|
+
True when a group matched nothing only because every application in
|
|
487
|
+
it is disabled or inherited - the case '--all' exists for. Logs why.
|
|
488
|
+
"""
|
|
489
|
+
if include_all or not _fetch_group_apps(server, group, True):
|
|
490
|
+
return False
|
|
491
|
+
logger.error(
|
|
492
|
+
f"Every application in a group matching '{group}' on '{server.name}' "
|
|
493
|
+
"is disabled or inherited. Use '--all' to clone them too"
|
|
494
|
+
)
|
|
495
|
+
return True
|
|
496
|
+
|
|
497
|
+
|
|
492
498
|
def _resolve_group(
|
|
493
|
-
server: PuakmaServer,
|
|
499
|
+
server: PuakmaServer,
|
|
500
|
+
group: str,
|
|
501
|
+
apps: list[PuakmaApplication] | None = None,
|
|
502
|
+
*,
|
|
503
|
+
include_all: bool = False,
|
|
494
504
|
) -> list[int] | None:
|
|
495
505
|
"""Resolves a group reference to the ids of every application in it"""
|
|
496
506
|
if apps is None:
|
|
497
|
-
apps = _fetch_group_apps(server, group)
|
|
507
|
+
apps = _fetch_group_apps(server, group, include_all)
|
|
498
508
|
if not apps:
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
509
|
+
if not _group_has_only_hidden_apps(server, group, include_all):
|
|
510
|
+
logger.error(
|
|
511
|
+
f"No applications in a group matching '{group}' found on "
|
|
512
|
+
f"'{server.name}'"
|
|
513
|
+
)
|
|
502
514
|
return None
|
|
503
515
|
groups = sorted({app.group or "" for app in apps}, key=str.casefold)
|
|
504
516
|
if len(groups) > 1:
|
|
@@ -513,15 +525,18 @@ def _resolve_group(
|
|
|
513
525
|
return [app.id for app in apps]
|
|
514
526
|
|
|
515
527
|
|
|
516
|
-
def _resolve_bare_word(
|
|
528
|
+
def _resolve_bare_word(
|
|
529
|
+
server: PuakmaServer, word: str, include_all: bool = False
|
|
530
|
+
) -> list[int] | None:
|
|
517
531
|
"""
|
|
518
532
|
A bare word is either a TemplateName or an application group. Both
|
|
519
533
|
are looked up and a word that is somehow both is an error rather
|
|
520
534
|
than a coin toss - the ID or 'group/name' clones the application,
|
|
521
|
-
'--group' clones the group.
|
|
535
|
+
'--group' clones the group. A TemplateName names one application,
|
|
536
|
+
so it is looked up in full; the group expansion honours include_all.
|
|
522
537
|
"""
|
|
523
538
|
templates = _fetch_apps(server, [], [], [word], True)
|
|
524
|
-
group_apps = _fetch_group_apps(server, word)
|
|
539
|
+
group_apps = _fetch_group_apps(server, word, include_all)
|
|
525
540
|
if templates and group_apps:
|
|
526
541
|
logger.error(
|
|
527
542
|
f"'{word}' is both a TemplateName and an application group on "
|
|
@@ -530,15 +545,21 @@ def _resolve_bare_word(server: PuakmaServer, word: str) -> list[int] | None:
|
|
|
530
545
|
)
|
|
531
546
|
return None
|
|
532
547
|
if group_apps:
|
|
533
|
-
return _resolve_group(server, word, group_apps)
|
|
548
|
+
return _resolve_group(server, word, group_apps, include_all=include_all)
|
|
549
|
+
if not templates and _group_has_only_hidden_apps(server, word, include_all):
|
|
550
|
+
return None
|
|
534
551
|
return _resolve_one(server, templates, f"TemplateName '{word}'")
|
|
535
552
|
|
|
536
553
|
|
|
537
|
-
def _resolve_refs_to_ids(
|
|
554
|
+
def _resolve_refs_to_ids(
|
|
555
|
+
server: PuakmaServer, refs: list[AppRef], *, include_all: bool = False
|
|
556
|
+
) -> list[int] | None:
|
|
538
557
|
"""
|
|
539
558
|
Resolves TemplateName, group and group/name references to
|
|
540
559
|
application ids by querying the server. Returns None (having logged
|
|
541
|
-
an error) when a reference can't be resolved unambiguously.
|
|
560
|
+
an error) when a reference can't be resolved unambiguously. Group
|
|
561
|
+
references expand to their active, non-inherited applications
|
|
562
|
+
unless include_all; an application named outright always resolves.
|
|
542
563
|
"""
|
|
543
564
|
ids: list[int] = []
|
|
544
565
|
for ref in refs:
|
|
@@ -546,9 +567,9 @@ def _resolve_refs_to_ids(server: PuakmaServer, refs: list[AppRef]) -> list[int]
|
|
|
546
567
|
ids.append(ref.id)
|
|
547
568
|
continue
|
|
548
569
|
if ref.is_group_only:
|
|
549
|
-
resolved = _resolve_group(server, ref.group or "")
|
|
570
|
+
resolved = _resolve_group(server, ref.group or "", include_all=include_all)
|
|
550
571
|
elif ref.template is not None:
|
|
551
|
-
resolved = _resolve_bare_word(server, ref.template)
|
|
572
|
+
resolved = _resolve_bare_word(server, ref.template, include_all)
|
|
552
573
|
else:
|
|
553
574
|
matches = _fetch_apps(server, [ref.name or ""], [ref.group or ""], [], True)
|
|
554
575
|
resolved = _resolve_one(
|
|
@@ -568,10 +589,13 @@ def clone(
|
|
|
568
589
|
get_resources: bool = False,
|
|
569
590
|
open_urls: bool = False,
|
|
570
591
|
reclone: bool = False,
|
|
592
|
+
include_all: bool = False,
|
|
571
593
|
timeout: int = 300,
|
|
572
594
|
) -> int:
|
|
573
595
|
refs = list(app_refs)
|
|
574
596
|
if reclone:
|
|
597
|
+
# Every application already cloned from THIS server. main()
|
|
598
|
+
# fans a bare '--reclone' out over every server with clones
|
|
575
599
|
refs.extend(AppRef(None, id=app.id) for app in workspace.listapps(server))
|
|
576
600
|
|
|
577
601
|
# Resolve credentials before the spinner starts so any interactive
|
|
@@ -580,7 +604,7 @@ def clone(
|
|
|
580
604
|
# backend=gateway: negotiate now, before any locks - a gateway that
|
|
581
605
|
# doesn't answer is an error here, never a silent SOAP fallback
|
|
582
606
|
server.negotiate_gateway()
|
|
583
|
-
app_ids = _resolve_refs_to_ids(server, refs)
|
|
607
|
+
app_ids = _resolve_refs_to_ids(server, refs, include_all=include_all)
|
|
584
608
|
if app_ids is None:
|
|
585
609
|
return 1
|
|
586
610
|
|
|
@@ -169,11 +169,16 @@ async def _aupload_classes(
|
|
|
169
169
|
server: PuakmaServer,
|
|
170
170
|
to_upload: list[tuple[PuakmaApplication, DesignObject]],
|
|
171
171
|
) -> int:
|
|
172
|
+
# The same routing as push: the gateway when negotiated (journalled,
|
|
173
|
+
# deploy-confirmed), the webdesign API for the gateway app itself,
|
|
174
|
+
# SOAP only on backend=soap - with the handshake lazy
|
|
175
|
+
from vortex.commands.watch import aupload_design_routed
|
|
176
|
+
|
|
172
177
|
ret = 0
|
|
173
178
|
async with server as s:
|
|
174
|
-
await s.
|
|
179
|
+
await asyncio.to_thread(s.negotiate_gateway)
|
|
175
180
|
for _app, obj in to_upload:
|
|
176
|
-
ok = await
|
|
181
|
+
ok = await aupload_design_routed(s, obj, False)
|
|
177
182
|
ret |= 0 if ok else 1
|
|
178
183
|
for app in {app for app, _obj in to_upload}:
|
|
179
184
|
workspace.mkdir(app)
|