diff --git a/cmd/labs/project/command_test.go b/cmd/labs/project/command_test.go index aac2e973a07..6dc73855f7e 100644 --- a/cmd/labs/project/command_test.go +++ b/cmd/labs/project/command_test.go @@ -2,15 +2,20 @@ package project_test import ( "context" + "net/http" + "net/http/httptest" + "os" "path/filepath" "testing" "time" + "github.com/databricks/cli/cmd/labs/github" "github.com/databricks/cli/internal/testcli" "github.com/databricks/cli/libs/env" "github.com/databricks/cli/libs/python" "github.com/databricks/databricks-sdk-go" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) type echoOut struct { @@ -67,3 +72,26 @@ func TestRenderingTable(t *testing.T) { Third Fourth `) } + +func TestRunningCommandWhenUpdateCheckFails(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusInternalServerError) + })) + defer server.Close() + + home := copyTestdata(t, "testdata/installed-in-home") + // Drop the cached releases so the update check has to hit the API. + err := os.Remove(filepath.Join(home, ".databricks", "labs", "blueprint", "cache", "databrickslabs-blueprint-releases.json")) + require.NoError(t, err) + + ctx := github.WithApiOverride(t.Context(), server.URL) + ctx = env.WithUserHomeDir(ctx, home) + py, _ := python.DetectExecutable(ctx) + py, _ = filepath.Abs(py) + ctx = env.Set(ctx, "PYTHON_BIN", py) + + r := testcli.NewRunner(t, ctx, "labs", "blueprint", "echo") + var out echoOut + r.RunAndParseJSON(&out) + assert.Equal(t, "echo", out.Command) +} diff --git a/cmd/labs/project/project.go b/cmd/labs/project/project.go index a8228126bdf..42eba593293 100644 --- a/cmd/labs/project/project.go +++ b/cmd/labs/project/project.go @@ -308,6 +308,10 @@ func (p *Project) checkUpdates(cmd *cobra.Command) error { if err != nil { return err } + // Repositories without releases (and the offline fallback) yield no versions; nothing to advise on. + if len(versions) == 0 { + return nil + } installed, err := p.InstalledVersion(ctx) if err != nil { return err diff --git a/cmd/labs/project/project_test.go b/cmd/labs/project/project_test.go index 42f999f4143..62db00b6a53 100644 --- a/cmd/labs/project/project_test.go +++ b/cmd/labs/project/project_test.go @@ -2,10 +2,14 @@ package project import ( "os" + "path/filepath" "strings" "testing" + "github.com/databricks/cli/libs/env" + "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func assertEqualPaths(t *testing.T, expected, actual string) { @@ -19,3 +23,21 @@ func TestLoad(t *testing.T) { assert.NoError(t, err) assertEqualPaths(t, "testdata/installed-in-home/.databricks/labs/blueprint/lib", prj.folder) } + +func TestCheckUpdatesWithEmptyReleaseList(t *testing.T) { + ctx := env.WithUserHomeDir(t.Context(), t.TempDir()) + rootDir, err := PathInLabs(ctx, "blueprint") + require.NoError(t, err) + prj := &Project{Name: "blueprint", rootDir: rootDir} + require.NoError(t, prj.EnsureFoldersExist()) + + // The far-future refreshed_at keeps the cache valid so no network call is made. + cache := []byte(`{"refreshed_at": "2033-01-01T00:00:00Z", "data": []}`) + require.NoError(t, os.WriteFile(filepath.Join(prj.CacheDir(), "databrickslabs-blueprint-releases.json"), cache, ownerRW)) + version := []byte(`{"version": "v0.3.15", "date": "2023-10-24T15:04:05+01:00"}`) + require.NoError(t, os.WriteFile(filepath.Join(prj.StateDir(), "version.json"), version, ownerRW)) + + cmd := &cobra.Command{} + cmd.SetContext(ctx) + assert.NoError(t, prj.checkUpdates(cmd)) +} diff --git a/cmd/labs/project/proxy.go b/cmd/labs/project/proxy.go index 82c7fb90cab..c46ac7aecf2 100644 --- a/cmd/labs/project/proxy.go +++ b/cmd/labs/project/proxy.go @@ -38,9 +38,9 @@ func (cp *proxy) register(parent *cobra.Command) { } func (cp *proxy) runE(cmd *cobra.Command, _ []string) error { - err := cp.checkUpdates(cmd) - if err != nil { - return err + // The update check only prints an upgrade hint, so a failure must not block the command. + if err := cp.checkUpdates(cmd); err != nil { + log.Debugf(cmd.Context(), "Failed to check for newer release of %s: %s", cp.Project.Name, err) } args, err := cp.commandInput(cmd) if err != nil {