hop3-cli 0.5.0.dev3__tar.gz → 0.6.1__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.
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/PKG-INFO +13 -14
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/README.md +11 -13
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/pyproject.toml +2 -1
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/commands/__init__.py +2 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/commands/arguments.py +291 -143
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/commands/destructive.py +62 -78
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/commands/flags.py +25 -12
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/commands/help.py +134 -35
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/commands/local/__init__.py +25 -14
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/commands/local/aliases_cmd.py +2 -14
- hop3_cli-0.6.1/src/hop3_cli/commands/local/auth_cmd.py +60 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/commands/local/completion_cmd.py +8 -52
- hop3_cli-0.6.1/src/hop3_cli/commands/local/context_cmd.py +524 -0
- hop3_cli-0.6.1/src/hop3_cli/commands/local/help_text.py +285 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/commands/local/init_cmd.py +18 -35
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/commands/local/login_cmd.py +129 -69
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/commands/local/settings_cmd.py +19 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/commands/local/ssh_ops.py +30 -13
- hop3_cli-0.6.1/src/hop3_cli/commands/local/tunnel_cmd.py +187 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/commands/local/use_cmd.py +21 -28
- hop3_cli-0.6.1/src/hop3_cli/config.py +494 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/core/alias_registry.py +1 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/core/aliases.py +13 -9
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/core/app_scope.py +46 -12
- hop3_cli-0.6.1/src/hop3_cli/core/config_migration.py +395 -0
- hop3_cli-0.6.1/src/hop3_cli/core/config_migration_v2.py +182 -0
- hop3_cli-0.6.1/src/hop3_cli/core/credential_store.py +156 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/core/deploy_preview.py +86 -82
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/core/hop3_toml.py +2 -4
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/core/local_overlay.py +31 -18
- hop3_cli-0.6.1/src/hop3_cli/core/paths.py +35 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/core/project_guard.py +5 -3
- hop3_cli-0.6.1/src/hop3_cli/core/resolution.py +566 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/exit_codes.py +2 -9
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/main.py +241 -85
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/rpc/__init__.py +1 -4
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/rpc/client.py +4 -5
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/rpc/responses.py +65 -87
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/rpc/streaming.py +4 -1
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/ui/__init__.py +1 -2
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/ui/console.py +0 -5
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/ui/messages.py +18 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/ui/rich_printer.py +35 -46
- hop3_cli-0.5.0.dev3/src/hop3_cli/commands/local/auth_cmd.py +0 -52
- hop3_cli-0.5.0.dev3/src/hop3_cli/commands/local/context_cmd.py +0 -563
- hop3_cli-0.5.0.dev3/src/hop3_cli/commands/local/help_text.py +0 -166
- hop3_cli-0.5.0.dev3/src/hop3_cli/commands/local/project_context_cmd.py +0 -776
- hop3_cli-0.5.0.dev3/src/hop3_cli/commands/local/server_cmd.py +0 -599
- hop3_cli-0.5.0.dev3/src/hop3_cli/config.py +0 -563
- hop3_cli-0.5.0.dev3/src/hop3_cli/core/cli_state.py +0 -117
- hop3_cli-0.5.0.dev3/src/hop3_cli/core/context_names.py +0 -72
- hop3_cli-0.5.0.dev3/src/hop3_cli/core/resolution.py +0 -930
- hop3_cli-0.5.0.dev3/src/hop3_cli/core/server_registry.py +0 -309
- hop3_cli-0.5.0.dev3/src/hop3_cli/rpc/tunnel.py +0 -177
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/__init__.py +0 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/commands/local/version_cmd.py +0 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/core/__init__.py +0 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/core/suggest.py +0 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/exceptions.py +0 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/tokens.py +0 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/types.py +0 -0
- {hop3_cli-0.5.0.dev3 → hop3_cli-0.6.1}/src/hop3_cli/ui/prompts.py +0 -0
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hop3-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.1
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Stefane Fermigier
|
|
6
6
|
Author-email: Stefane Fermigier <sf@abilian.com>
|
|
7
7
|
License-Expression: Apache-2.0
|
|
8
8
|
Requires-Dist: toml>=0.10.2,<1.0.0
|
|
9
|
+
Requires-Dist: tomlkit>=0.13.0
|
|
9
10
|
Requires-Dist: jsonrpcclient>=4.0.3,<5.0.0
|
|
10
11
|
Requires-Dist: requests>=2.32.3,<3.0.0
|
|
11
12
|
Requires-Dist: tabulate>=0.9.0,<1.0.0
|
|
@@ -57,29 +58,27 @@ hop3 apps
|
|
|
57
58
|
hop3 use myapp
|
|
58
59
|
|
|
59
60
|
# From here on, app-scoped commands resolve myapp automatically:
|
|
60
|
-
hop3 logs
|
|
61
|
+
hop3 app logs
|
|
61
62
|
hop3 config set KEY=value
|
|
62
|
-
hop3 restart
|
|
63
|
+
hop3 app restart
|
|
63
64
|
```
|
|
64
65
|
|
|
65
66
|
## App Resolution
|
|
66
67
|
|
|
67
|
-
Commands that act on a single app (`logs`, `restart`, `config set`, `run`, …) no longer take the app name as a positional argument. Instead the CLI resolves it from a layered chain, walking sources until one supplies a value (ADR 042 §Resolution
|
|
68
|
+
Commands that act on a single app (`logs`, `restart`, `config set`, `run`, …) no longer take the app name as a positional argument. Instead the CLI resolves it from a layered chain, walking sources until one supplies a value (ADR 042 §Resolution; supersedes ADR 036 §D7):
|
|
68
69
|
|
|
69
70
|
1. `--app <name>` / `-a <name>` — explicit flag, wins over everything.
|
|
70
71
|
2. `$HOP3_APP` — environment variable for the current shell.
|
|
71
72
|
3. `.hop3-app` — one-line file in CWD or any ancestor up to `$HOME`. Drop it in a project repo and `hop3` from inside picks up the right app.
|
|
72
73
|
4. `hop3.toml [cli].app` — same search path as `.hop3-app`, lower priority.
|
|
73
|
-
5. `hop3.toml [contexts.<resolved-context>].app` — when a project context resolves (see below), its `app` field becomes the source. Lets one project map per-environment to different apps.
|
|
74
|
-
6. `hop3.toml [metadata].id` — the project's canonical name. The "I'm physically standing in this project" source
|
|
75
|
-
7. Git remote `hop3-<env>` parsed for an app name — supports `git push hop3-prod main` style deploys.
|
|
76
|
-
8. Active server's `default_app` from `~/.config/hop3-cli/servers.toml` — set via `hop3 server use --default-app <app>`. Lowest-priority fallback for single-app users.
|
|
74
|
+
5. `hop3.toml [contexts.<resolved-context>].app` — when a project context resolves (see below), its `app` field becomes the source. Lets one project map per-environment to different apps. Trusted only when the context was selected CWD-rooted (`--context` or in-tree `.hop3-local.toml`); an ambiently-selected context still resolves but trips the project-mismatch guard.
|
|
75
|
+
6. `hop3.toml [metadata].id` — the project's canonical name. The "I'm physically standing in this project" source, so being inside a project always wins over a sticky binding from elsewhere.
|
|
77
76
|
|
|
78
77
|
Use `hop3 --why <command>` to print the full trace and see which source won. `--why` is diagnostic-only: the command itself is not executed (so `hop3 deploy --why` is safe to run).
|
|
79
78
|
|
|
80
79
|
```bash
|
|
81
80
|
# Explicit (always works):
|
|
82
|
-
hop3 logs --app myapp
|
|
81
|
+
hop3 app logs --app myapp
|
|
83
82
|
hop3 config set --app myapp KEY=value
|
|
84
83
|
|
|
85
84
|
# Per-shell:
|
|
@@ -98,12 +97,12 @@ echo myapp > .hop3-app
|
|
|
98
97
|
hop3 --why logs
|
|
99
98
|
```
|
|
100
99
|
|
|
101
|
-
The ADR 042 model
|
|
100
|
+
The ADR 042 model has a single managed noun — the **context** — and a single selector, `--context <name>`, for every command (app-bound or not).
|
|
102
101
|
|
|
103
|
-
- **
|
|
104
|
-
- **
|
|
102
|
+
- **Contexts** — a named target at two scopes. A **project** context (dev / staging / prod) is declared as a `[contexts.<name>]` block inside the committed `hop3.toml`: a non-secret bundle of server address + app + domains + env. A **global** context is a name bound to a server address in the per-developer `config.toml` (`[contexts.<name>].server`), so project-less commands (`hop3 apps --context prod`) can target a server by name. `--context` resolves project-first, then global; there is no `--server` flag. Managed with `hop3 context` (`add` / `use` / `list` / `show` / `remove` / `rename`) — project scope inside a project tree, global scope outside one (or with `--global`). The per-checkout project selection is recorded in `.hop3-local.toml` (gitignored automatically).
|
|
103
|
+
- **Credentials are invisible plumbing** — there is no "server" noun to manage. `hop3 login` stores a bearer token in the per-server credential store (`~/.config/hop3-cli/credentials.toml`, mode `0600`), keyed by the server's canonical address, and records that server as the default target; `hop3 login --context <name>` also names it as a global context and the default. `config.toml` stays secret-free (local preferences, global contexts, `[cli].default_context`).
|
|
105
104
|
|
|
106
|
-
A `hop3 deploy` from a project tree resolves
|
|
105
|
+
A `hop3 deploy` from a project tree resolves the context (which environment of this project, and therefore which server and app), and shows a preview-and-confirm prompt with the plan before invoking the deploy RPC. `--dry-run` exits after printing the plan; `--force` bypasses the project-mismatch safety guard.
|
|
107
106
|
|
|
108
107
|
See [CLI Reference: App Resolution](../../docs/src/reference/cli.md#app-resolution) and [ADR 042](../../notes/adrs/042-cli-context-model.md) for the full specification.
|
|
109
108
|
|
|
@@ -131,7 +130,7 @@ hop3-cli/
|
|
|
131
130
|
│ ├── rpc/
|
|
132
131
|
│ │ └── client.py # JSON-RPC client with SSH tunnel
|
|
133
132
|
│ ├── commands/
|
|
134
|
-
│ │ ├── local
|
|
133
|
+
│ │ ├── local/ # Local commands (init, login, settings, context)
|
|
135
134
|
│ │ ├── flags.py # CLI flag parsing (--app, --why, --json, -y, …)
|
|
136
135
|
│ │ └── destructive.py # Confirmation prompts
|
|
137
136
|
│ └── ui/
|
|
@@ -37,29 +37,27 @@ hop3 apps
|
|
|
37
37
|
hop3 use myapp
|
|
38
38
|
|
|
39
39
|
# From here on, app-scoped commands resolve myapp automatically:
|
|
40
|
-
hop3 logs
|
|
40
|
+
hop3 app logs
|
|
41
41
|
hop3 config set KEY=value
|
|
42
|
-
hop3 restart
|
|
42
|
+
hop3 app restart
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
## App Resolution
|
|
46
46
|
|
|
47
|
-
Commands that act on a single app (`logs`, `restart`, `config set`, `run`, …) no longer take the app name as a positional argument. Instead the CLI resolves it from a layered chain, walking sources until one supplies a value (ADR 042 §Resolution
|
|
47
|
+
Commands that act on a single app (`logs`, `restart`, `config set`, `run`, …) no longer take the app name as a positional argument. Instead the CLI resolves it from a layered chain, walking sources until one supplies a value (ADR 042 §Resolution; supersedes ADR 036 §D7):
|
|
48
48
|
|
|
49
49
|
1. `--app <name>` / `-a <name>` — explicit flag, wins over everything.
|
|
50
50
|
2. `$HOP3_APP` — environment variable for the current shell.
|
|
51
51
|
3. `.hop3-app` — one-line file in CWD or any ancestor up to `$HOME`. Drop it in a project repo and `hop3` from inside picks up the right app.
|
|
52
52
|
4. `hop3.toml [cli].app` — same search path as `.hop3-app`, lower priority.
|
|
53
|
-
5. `hop3.toml [contexts.<resolved-context>].app` — when a project context resolves (see below), its `app` field becomes the source. Lets one project map per-environment to different apps.
|
|
54
|
-
6. `hop3.toml [metadata].id` — the project's canonical name. The "I'm physically standing in this project" source
|
|
55
|
-
7. Git remote `hop3-<env>` parsed for an app name — supports `git push hop3-prod main` style deploys.
|
|
56
|
-
8. Active server's `default_app` from `~/.config/hop3-cli/servers.toml` — set via `hop3 server use --default-app <app>`. Lowest-priority fallback for single-app users.
|
|
53
|
+
5. `hop3.toml [contexts.<resolved-context>].app` — when a project context resolves (see below), its `app` field becomes the source. Lets one project map per-environment to different apps. Trusted only when the context was selected CWD-rooted (`--context` or in-tree `.hop3-local.toml`); an ambiently-selected context still resolves but trips the project-mismatch guard.
|
|
54
|
+
6. `hop3.toml [metadata].id` — the project's canonical name. The "I'm physically standing in this project" source, so being inside a project always wins over a sticky binding from elsewhere.
|
|
57
55
|
|
|
58
56
|
Use `hop3 --why <command>` to print the full trace and see which source won. `--why` is diagnostic-only: the command itself is not executed (so `hop3 deploy --why` is safe to run).
|
|
59
57
|
|
|
60
58
|
```bash
|
|
61
59
|
# Explicit (always works):
|
|
62
|
-
hop3 logs --app myapp
|
|
60
|
+
hop3 app logs --app myapp
|
|
63
61
|
hop3 config set --app myapp KEY=value
|
|
64
62
|
|
|
65
63
|
# Per-shell:
|
|
@@ -78,12 +76,12 @@ echo myapp > .hop3-app
|
|
|
78
76
|
hop3 --why logs
|
|
79
77
|
```
|
|
80
78
|
|
|
81
|
-
The ADR 042 model
|
|
79
|
+
The ADR 042 model has a single managed noun — the **context** — and a single selector, `--context <name>`, for every command (app-bound or not).
|
|
82
80
|
|
|
83
|
-
- **
|
|
84
|
-
- **
|
|
81
|
+
- **Contexts** — a named target at two scopes. A **project** context (dev / staging / prod) is declared as a `[contexts.<name>]` block inside the committed `hop3.toml`: a non-secret bundle of server address + app + domains + env. A **global** context is a name bound to a server address in the per-developer `config.toml` (`[contexts.<name>].server`), so project-less commands (`hop3 apps --context prod`) can target a server by name. `--context` resolves project-first, then global; there is no `--server` flag. Managed with `hop3 context` (`add` / `use` / `list` / `show` / `remove` / `rename`) — project scope inside a project tree, global scope outside one (or with `--global`). The per-checkout project selection is recorded in `.hop3-local.toml` (gitignored automatically).
|
|
82
|
+
- **Credentials are invisible plumbing** — there is no "server" noun to manage. `hop3 login` stores a bearer token in the per-server credential store (`~/.config/hop3-cli/credentials.toml`, mode `0600`), keyed by the server's canonical address, and records that server as the default target; `hop3 login --context <name>` also names it as a global context and the default. `config.toml` stays secret-free (local preferences, global contexts, `[cli].default_context`).
|
|
85
83
|
|
|
86
|
-
A `hop3 deploy` from a project tree resolves
|
|
84
|
+
A `hop3 deploy` from a project tree resolves the context (which environment of this project, and therefore which server and app), and shows a preview-and-confirm prompt with the plan before invoking the deploy RPC. `--dry-run` exits after printing the plan; `--force` bypasses the project-mismatch safety guard.
|
|
87
85
|
|
|
88
86
|
See [CLI Reference: App Resolution](../../docs/src/reference/cli.md#app-resolution) and [ADR 042](../../notes/adrs/042-cli-context-model.md) for the full specification.
|
|
89
87
|
|
|
@@ -111,7 +109,7 @@ hop3-cli/
|
|
|
111
109
|
│ ├── rpc/
|
|
112
110
|
│ │ └── client.py # JSON-RPC client with SSH tunnel
|
|
113
111
|
│ ├── commands/
|
|
114
|
-
│ │ ├── local
|
|
112
|
+
│ │ ├── local/ # Local commands (init, login, settings, context)
|
|
115
113
|
│ │ ├── flags.py # CLI flag parsing (--app, --why, --json, -y, …)
|
|
116
114
|
│ │ └── destructive.py # Confirmation prompts
|
|
117
115
|
│ └── ui/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "hop3-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.6.1"
|
|
4
4
|
authors = [
|
|
5
5
|
{name = "Stefane Fermigier", email = "sf@abilian.com"},
|
|
6
6
|
]
|
|
@@ -9,6 +9,7 @@ requires-python = "<4.0,>=3.10"
|
|
|
9
9
|
dependencies = [
|
|
10
10
|
# Configuration
|
|
11
11
|
"toml<1.0.0,>=0.10.2",
|
|
12
|
+
"tomlkit>=0.13.0", # comment-preserving TOML round-trip for hop3.toml edits
|
|
12
13
|
# Communication
|
|
13
14
|
"jsonrpcclient<5.0.0,>=4.0.3",
|
|
14
15
|
"requests<3.0.0,>=2.32.3",
|
|
@@ -19,6 +19,7 @@ from .destructive import confirm_destructive_action, is_destructive_command
|
|
|
19
19
|
from .flags import CliFlags, parse_flags
|
|
20
20
|
from .help import (
|
|
21
21
|
append_feedback_footer,
|
|
22
|
+
append_local_commands_full_help,
|
|
22
23
|
emit_status_line,
|
|
23
24
|
handle_help_flags,
|
|
24
25
|
inject_local_commands_into_help,
|
|
@@ -36,6 +37,7 @@ __all__ = [
|
|
|
36
37
|
"LOCAL_COMMANDS_INFO",
|
|
37
38
|
"CliFlags",
|
|
38
39
|
"append_feedback_footer",
|
|
40
|
+
"append_local_commands_full_help",
|
|
39
41
|
"confirm_destructive_action",
|
|
40
42
|
"emit_status_line",
|
|
41
43
|
"generate_archive",
|