From acc2a8dd686946afa8d4e8e89b37eab2e441e8b4 Mon Sep 17 00:00:00 2001 From: Zhe Li Date: Wed, 19 Aug 2026 22:43:20 +0000 Subject: [PATCH 1/3] feat(localnet): add ls alias for list --- docs/changes-from-proposal.md | 3 ++- internal/cli/localnet/list.go | 1 + internal/cli/localnet/list_test.go | 13 +++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 internal/cli/localnet/list_test.go diff --git a/docs/changes-from-proposal.md b/docs/changes-from-proposal.md index 60ee5975..b89a699b 100644 --- a/docs/changes-from-proposal.md +++ b/docs/changes-from-proposal.md @@ -91,10 +91,11 @@ The following aliases are not in the proposal but are shipped: | `localnet resume` | `unpause` | Matches `docker compose unpause` terminology | | `localnet observability` | `obs` | Shorter for interactive use | | `localnet container list` | `ls`, `ps` | Matches Docker CLI conventions | +| `localnet list` | `ls` | Short form for listing registered instances | | `localnet token party ls` | `list` | Consistency within party subcommand | | `localnet token party rm` | `remove` | Consistency within party subcommand | -`localnet list` has **no** `ls` alias despite the pattern above — adding it would shadow `localnet logs` with a common prefix, increasing ambiguity in tab-completion. +`localnet list` also accepts `ls` as a short form for listing registered instances. **Behaviour change (removed aliases):** earlier builds shipped `start` as an alias for `up` and `stop` as an alias for `down`. These aliases have been **removed** — `start` and `stop` are now standalone commands with distinct behaviour (see [`localnet stop` / `start`](#localnet-stop--start-new)). `localnet stop` no longer removes containers (use `down` for that), and `localnet start` no longer unconditionally recreates the stack (though it converges to a running instance, falling back to `up` when containers are gone). diff --git a/internal/cli/localnet/list.go b/internal/cli/localnet/list.go index 450fa1b9..43353703 100644 --- a/internal/cli/localnet/list.go +++ b/internal/cli/localnet/list.go @@ -11,6 +11,7 @@ func buildList() *cobra.Command { opts := &localnet.ListOptions{Format: "text"} cmd := &cobra.Command{ Use: "list", + Aliases: []string{"ls"}, Short: "List every Canton LocalNet instance known to this DevKit", Args: cobra.NoArgs, SilenceUsage: true, diff --git a/internal/cli/localnet/list_test.go b/internal/cli/localnet/list_test.go new file mode 100644 index 00000000..e46724b3 --- /dev/null +++ b/internal/cli/localnet/list_test.go @@ -0,0 +1,13 @@ +package localnet + +import "testing" + +func TestListHasLsAlias(t *testing.T) { + cmd := buildList() + for _, alias := range cmd.Aliases { + if alias == "ls" { + return + } + } + t.Fatal("list command must have the `ls` alias") +} From f153580bbf756e71765aae64542365bd21af5e49 Mon Sep 17 00:00:00 2001 From: Zhe Li Date: Thu, 20 Aug 2026 06:54:34 +0000 Subject: [PATCH 2/3] test(cli): cover localnet list alias dispatch --- internal/cli/cli_test.go | 24 ++++++++++++++++++++++++ internal/cli/localnet/list_test.go | 13 ------------- 2 files changed, 24 insertions(+), 13 deletions(-) delete mode 100644 internal/cli/localnet/list_test.go diff --git a/internal/cli/cli_test.go b/internal/cli/cli_test.go index f141bbb3..34ef0b5e 100644 --- a/internal/cli/cli_test.go +++ b/internal/cli/cli_test.go @@ -2,8 +2,11 @@ package cli import ( "bytes" + "encoding/json" "strings" "testing" + + "github.com/bitdynamics-ab/canton-devkit/internal/api/types" ) func TestRunShowsRootHelpWithoutArgs(t *testing.T) { @@ -93,6 +96,27 @@ func TestRunLocalnetRemove_RequiresTarget(t *testing.T) { } } +func TestRunLocalnetListAlias(t *testing.T) { + t.Setenv("CANTON_DEVKIT_REGISTRY", t.TempDir()) + + var out, errb bytes.Buffer + code := New(&out, &errb, "test", "").Run([]string{"localnet", "ls", "--format=json"}) + if code != 0 { + t.Fatalf("localnet ls returned %d; stderr=%q", code, errb.String()) + } + + var got types.ListResponse + if err := json.Unmarshal(out.Bytes(), &got); err != nil { + t.Fatalf("localnet ls output is not list JSON: %v\noutput=%q", err, out.String()) + } + if got.SchemaVersion != types.SchemaVersion { + t.Errorf("schema version = %d, want %d", got.SchemaVersion, types.SchemaVersion) + } + if len(got.Instances) != 0 { + t.Errorf("instances = %+v, want empty registry", got.Instances) + } +} + // TestRunIsArgvOnly documents the DPM-component invocation contract: // when the binary is launched via a DPM manifest with exec-args: // ["localnet"], DPM prepends "localnet" and appends user-supplied args. diff --git a/internal/cli/localnet/list_test.go b/internal/cli/localnet/list_test.go deleted file mode 100644 index e46724b3..00000000 --- a/internal/cli/localnet/list_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package localnet - -import "testing" - -func TestListHasLsAlias(t *testing.T) { - cmd := buildList() - for _, alias := range cmd.Aliases { - if alias == "ls" { - return - } - } - t.Fatal("list command must have the `ls` alias") -} From 17c1ddd1e44b562a3e790900affa277268bdb9f8 Mon Sep 17 00:00:00 2001 From: Zhe Li Date: Thu, 20 Aug 2026 09:12:49 +0200 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: Zhe Li --- docs/changes-from-proposal.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/changes-from-proposal.md b/docs/changes-from-proposal.md index b89a699b..7341e7c2 100644 --- a/docs/changes-from-proposal.md +++ b/docs/changes-from-proposal.md @@ -95,7 +95,6 @@ The following aliases are not in the proposal but are shipped: | `localnet token party ls` | `list` | Consistency within party subcommand | | `localnet token party rm` | `remove` | Consistency within party subcommand | -`localnet list` also accepts `ls` as a short form for listing registered instances. **Behaviour change (removed aliases):** earlier builds shipped `start` as an alias for `up` and `stop` as an alias for `down`. These aliases have been **removed** — `start` and `stop` are now standalone commands with distinct behaviour (see [`localnet stop` / `start`](#localnet-stop--start-new)). `localnet stop` no longer removes containers (use `down` for that), and `localnet start` no longer unconditionally recreates the stack (though it converges to a running instance, falling back to `up` when containers are gone).