From 0f6e1c3a747432187eb40ec381403a4bd5fe3077 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 18 May 2026 08:54:46 -0400 Subject: [PATCH] fix(cli): show sync wait dependencies (#25089) (#25359) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cherry-pick of https://github.com/coder/coder/pull/25089 Original PR: #25089 — fix(cli): show sync wait dependencies Merge commit: f3e90b334d1f391b801c4c2761b5853bed26cbe1 Requested by: @matifali Co-authored-by: Max Schwenk --- cli/sync_start.go | 25 ++++++++++++++++--- cli/sync_test.go | 25 +++++++++++++++---- cli/sync_want.go | 5 +++- .../start_with_dependencies.golden | 4 +-- .../want_success.golden | 2 +- 5 files changed, 48 insertions(+), 13 deletions(-) diff --git a/cli/sync_start.go b/cli/sync_start.go index ee6b2a394d..a95935d8ef 100644 --- a/cli/sync_start.go +++ b/cli/sync_start.go @@ -2,6 +2,9 @@ package cli import ( "context" + "fmt" + "slices" + "strings" "time" "golang.org/x/xerrors" @@ -48,13 +51,23 @@ func (*RootCmd) syncStart(socketPath *string) *serpent.Command { } defer client.Close() - ready, err := client.SyncReady(ctx, unitName) + statusResp, err := client.SyncStatus(ctx, unitName) if err != nil { - return xerrors.Errorf("error checking dependencies: %w", err) + return xerrors.Errorf("get status failed: %w", err) } + ready := statusResp.IsReady + var waitedFor []string if !ready { - cliui.Infof(i.Stdout, "Waiting for dependencies of unit '%s' to be satisfied...", unitName) + for _, dep := range statusResp.Dependencies { + if !dep.IsSatisfied { + waitedFor = append(waitedFor, string(dep.DependsOn)) + } + } + slices.Sort(waitedFor) + waitedForList := strings.Join(waitedFor, ", ") + + cliui.Infof(i.Stdout, "Unit %q is waiting for dependencies to be satisfied: [%s]", unitName, waitedForList) ticker := time.NewTicker(syncPollInterval) defer ticker.Stop() @@ -83,7 +96,11 @@ func (*RootCmd) syncStart(socketPath *string) *serpent.Command { return xerrors.Errorf("start unit failed: %w", err) } - cliui.Info(i.Stdout, "Success") + if len(waitedFor) == 0 { + cliui.Info(i.Stdout, "Success") + } else { + cliui.Info(i.Stdout, fmt.Sprintf("Unit %q finished waiting for dependencies: [%s]", unitName, strings.Join(waitedFor, ", "))) + } return nil }, diff --git a/cli/sync_test.go b/cli/sync_test.go index 7635bab574..68864c2630 100644 --- a/cli/sync_test.go +++ b/cli/sync_test.go @@ -93,19 +93,20 @@ func TestSyncCommands_Golden(t *testing.T) { ctx := testutil.Context(t, testutil.WaitShort) - // Set up dependency: test-unit depends on dep-unit + // Set up dependencies: test-unit depends on dep-unit and dep-unit-2. client, err := agentsocket.NewClient(ctx, agentsocket.WithPath(path)) require.NoError(t, err) - // Declare dependency err = client.SyncWant(ctx, "test-unit", "dep-unit") require.NoError(t, err) + err = client.SyncWant(ctx, "test-unit", "dep-unit-2") + require.NoError(t, err) client.Close() outBuf := testutil.NewWaitBuffer() done := make(chan error, 1) go func() { - if err := outBuf.WaitFor(ctx, "Waiting"); err != nil { + if err := outBuf.WaitFor(ctx, "is waiting for dependencies"); err != nil { done <- err return } @@ -118,13 +119,23 @@ func TestSyncCommands_Golden(t *testing.T) { } defer compClient.Close() - // Start and complete the dependency unit. + // Start and complete both dependency units. err = compClient.SyncStart(compCtx, "dep-unit") if err != nil { done <- err return } err = compClient.SyncComplete(compCtx, "dep-unit") + if err != nil { + done <- err + return + } + err = compClient.SyncStart(compCtx, "dep-unit-2") + if err != nil { + done <- err + return + } + err = compClient.SyncComplete(compCtx, "dep-unit-2") done <- err }() @@ -132,7 +143,7 @@ func TestSyncCommands_Golden(t *testing.T) { inv.Stdout = outBuf inv.Stderr = outBuf - // Run the start command - it should wait for the dependency. + // Run the start command. It should wait for the dependencies. err = inv.WithContext(ctx).Run() require.NoError(t, err) @@ -179,6 +190,10 @@ func TestSyncCommands_Golden(t *testing.T) { err := inv.WithContext(ctx).Run() require.NoError(t, err) + require.Contains(t, outBuf.String(), "Unit \"test-unit\" declared dependencies: [dep-1, dep-2, dep-3]") + require.Contains(t, outBuf.String(), "dep-1") + require.Contains(t, outBuf.String(), "dep-2") + require.Contains(t, outBuf.String(), "dep-3") // Verify all dependencies were registered by checking status. outBuf.Reset() diff --git a/cli/sync_want.go b/cli/sync_want.go index d6dde13d69..5905e73771 100644 --- a/cli/sync_want.go +++ b/cli/sync_want.go @@ -1,6 +1,9 @@ package cli import ( + "fmt" + "strings" + "golang.org/x/xerrors" "github.com/coder/coder/v2/agent/agentsocket" @@ -39,7 +42,7 @@ func (*RootCmd) syncWant(socketPath *string) *serpent.Command { } } - cliui.Info(i.Stdout, "Success") + cliui.Info(i.Stdout, fmt.Sprintf("Unit %q declared dependencies: [%s]", dependentUnit, strings.Join(i.Args[1:], ", "))) return nil }, diff --git a/cli/testdata/TestSyncCommands_Golden/start_with_dependencies.golden b/cli/testdata/TestSyncCommands_Golden/start_with_dependencies.golden index 23256e9ad1..19f00d76f4 100644 --- a/cli/testdata/TestSyncCommands_Golden/start_with_dependencies.golden +++ b/cli/testdata/TestSyncCommands_Golden/start_with_dependencies.golden @@ -1,2 +1,2 @@ -Waiting for dependencies of unit 'test-unit' to be satisfied... -Success +Unit "test-unit" is waiting for dependencies to be satisfied: [dep-unit, dep-unit-2] +Unit "test-unit" finished waiting for dependencies: [dep-unit, dep-unit-2] diff --git a/cli/testdata/TestSyncCommands_Golden/want_success.golden b/cli/testdata/TestSyncCommands_Golden/want_success.golden index 35821117c8..a8ebf104ac 100644 --- a/cli/testdata/TestSyncCommands_Golden/want_success.golden +++ b/cli/testdata/TestSyncCommands_Golden/want_success.golden @@ -1 +1 @@ -Success +Unit "test-unit" declared dependencies: [dep-unit]