Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
`~/.vscode-server/bin` を開発ユーザーが書ける形に揃えます。

### Fixed
- **`devbase env <TAB>` の候補に `token` と `backend` が出るようにしました(#454)。** bash と zsh の補完の
サブコマンドの一覧に 2 つが無く、名前を手で打たないと使えませんでした。一致テストが `env` のサブコマンドの
全部を bash と zsh の一覧と比べるようになり、`env` のサブコマンドを足したときの取り残しで落ちます。
- **接続先 URL が手元のサーバ(`http://127.0.0.1:8200` など `http` の loopback)のとき、`devbase up` したコンテナの中の
`bao` がサーバへ届くようにしました(#295)。** これまではコンテナへ渡す `BAO_ADDR` がそのまま `127.0.0.1` を指し、
コンテナ自身へつながっていました。Docker が手元の端末のものなら、コンテナの `BAO_ADDR` のホストを
Expand Down
4 changes: 2 additions & 2 deletions docs/specifications/cli-argument-resolution.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ graph TD
| --- | --- |
| `bin/devbase` の `_PROJECT_NAME_SUBCOMMANDS` | `project` の直下で `[name]` を取る parser の名前の集合に等しい |
| `bin/devbase` の `_NAME_RESOLVABLE_SHORTCUTS` | `cli.SHORTCUTS` のキーと `build` の和に等しい。あわせて、トップレベルで `[name]` を取る parser がすべて `cli.SHORTCUTS` にあること |
| `etc/devbase-completion.bash` | 一時ディレクトリの `projects/` を `DEVBASE_ROOT` にして補完を実行し、`[name]` の集合から補完の例外を引いたすべての道の名前の位置でプロジェクト名が候補に出る。`--context` の集合のすべての道(`container` の道は `ct` で始めても)で `devbase <道> -` の候補に `--context` が出る。`[name]` の集合から補完の例外を引いた道では、`devbase <道> web -` の候補にも `--context` が出る。`--context` を取らない末端の道では、`devbase <道> -` の候補に `--context` が出ない。`project` / `container` の直下で `[name]` か `--context` を取るサブコマンド(入れ子は親の `profile` として数える)が、そのグループのサブコマンドの候補に含まれる |
| `etc/_devbase` | zsh を起動せず内容を読む。`case "$words[2]"` から字下げの深さで道の分岐(`up\|down)` のような `\|` 区切りの見出し)を辿り、`[name]` の集合から補完の例外を引いた道の本体に `_devbase_project_names` がある。`--context` の集合のすべての道の本体に、値の補完を持たない `'--context[...]:context:'`(`:context:` の後ろに補完の関数を置かない形)がある。`project_subcommands` / `container_subcommands` の一覧に bash と同じサブコマンドが含まれる |
| `etc/devbase-completion.bash` | 一時ディレクトリの `projects/` を `DEVBASE_ROOT` にして補完を実行し、`[name]` の集合から補完の例外を引いたすべての道の名前の位置でプロジェクト名が候補に出る。`--context` の集合のすべての道(`container` の道は `ct` で始めても)で `devbase <道> -` の候補に `--context` が出る。`[name]` の集合から補完の例外を引いた道では、`devbase <道> web -` の候補にも `--context` が出る。`--context` を取らない末端の道では、`devbase <道> -` の候補に `--context` が出ない。`project` / `container` の直下で `[name]` か `--context` を取るサブコマンド(入れ子は親の `profile` として数える)が、そのグループのサブコマンドの候補に含まれる。`env` の直下のサブコマンドは、`[name]`・`--context` を取るかによらず全部が `env` のサブコマンドの候補に含まれる |
| `etc/_devbase` | zsh を起動せず内容を読む。`case "$words[2]"` から字下げの深さで道の分岐(`up\|down)` のような `\|` 区切りの見出し)を辿り、`[name]` の集合から補完の例外を引いた道の本体に `_devbase_project_names` がある。`--context` の集合のすべての道の本体に、値の補完を持たない `'--context[...]:context:'`(`:context:` の後ろに補完の関数を置かない形)がある。`project_subcommands` / `container_subcommands` / `env_subcommands` の一覧に bash と同じサブコマンドが含まれる |
| この節の 2 つの表 | 見出し `` #### `[name]` を受け付けるサブコマンド `` と `` #### `--context` を受け付けるサブコマンド `` の直後の表を読む。1 列目は `devbase <グループ...> <sub>` の形で、間の語が道の頭になる。2 列目にバッククォートで並べた語を `<sub>` に入れる。表は `[name]` の集合・`--context` の集合にそれぞれ等しい |

補完の例外は `project profile up` / `down` / `list` の 3 つで、理由は「1 つ目の位置引数は、値が 1 個なら
Expand Down
2 changes: 2 additions & 0 deletions etc/_devbase
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,12 @@ _devbase() {
'import:Import .env bundle (age decrypt + merge)'
'keygen:Generate the devbase age key used by the secret store'
'exec:Run a command with the decrypted secrets in its environment'
'token:Refresh the OpenBao token in running dev containers'
'encrypt:Move plaintext settings into the encrypted store'
'decrypt:Move encrypted settings back to plaintext'
'rekey:Change who can decrypt the secrets and re-encrypt them'
'doctor:Check for leftover plaintext secrets and ignore-rule gaps'
'backend:Choose where secrets are stored (age / plaintext / openbao)'
)

plugin_subcommands=(
Expand Down
2 changes: 1 addition & 1 deletion etc/devbase-completion.bash
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ _devbase_completions() {
# project / container は同じサブコマンド群 (container は非推奨だが補完は維持)。
local project_subcommands="up down ps login logs scale build rebuild list profile open post-start"
local container_subcommands="up down ps login logs scale build rebuild profile open"
local env_subcommands="init sync list set get delete edit project export import keygen exec encrypt decrypt rekey doctor"
local env_subcommands="init sync list set get delete edit project export import keygen exec token encrypt decrypt rekey doctor backend"
local plugin_subcommands="list install uninstall update info sync repo"
local repo_subcommands="add remove list refresh"
local snapshot_subcommands="create list restore copy delete rotate"
Expand Down
14 changes: 10 additions & 4 deletions tests/cli/test_name_context_consistency.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,25 +291,31 @@ def test_zsh_completion_offers_context():


# ---------------------------------------------------------------------------
# 補完: project / container のサブコマンドの一覧
# 補完: project / container / env のサブコマンドの一覧
# ---------------------------------------------------------------------------

# サブコマンドの全部を比べるグループ(`[name]`・`--context` を取るかによらない)
_ALL_SUBCOMMAND_GROUPS = ("env",)


def _group_subcommands(group):
if group in _ALL_SUBCOMMAND_GROUPS:
return {p[1] for p, _ in _walk(cli._create_parser()) if len(p) == 2 and _canonical(p)[0] == group}
# 入れ子の `profile` は親の `profile` として数える
return {p[1] for p in NAME_PATHS | CONTEXT_PATHS if len(p) >= 2 and p[0] == group}


@pytest.mark.parametrize("group", ["project", "container"])
@pytest.mark.parametrize("group", ["project", "container", "env"])
def test_bash_completion_lists_subcommands(group, fake_root):
expected = _group_subcommands(group)
assert expected, f"argparse の {group} に `[name]` / `--context` を取るサブコマンドが無い"
assert expected, f"argparse の {group} に比べるサブコマンドが無い"
offered = _bash_complete((group,), fake_root)
missing = expected - offered
assert not missing, (f"etc/devbase-completion.bash の {group} のサブコマンドの一覧に無い: "
f"{sorted(missing)}")


@pytest.mark.parametrize("group", ["project", "container"])
@pytest.mark.parametrize("group", ["project", "container", "env"])
def test_zsh_completion_lists_subcommands(group):
expected = _group_subcommands(group)
m = re.search(rf"^\s*{group}_subcommands=\((.*?)^\s*\)", ZSH_COMPLETION.read_text(), re.MULTILINE | re.DOTALL)
Expand Down
Loading