From cc11c2d48beaec06f1d5eee1ec3043b727525218 Mon Sep 17 00:00:00 2001 From: Luca Di Maio Date: Sat, 20 Jun 2026 17:20:15 +0200 Subject: [PATCH] fix(generate-entry): refuse a container that does not exist Signed-off-by: Luca Di Maio --- pkg/commands/generate_entry.go | 5 ++++ pkg/commands/generate_entry_test.go | 41 +++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/pkg/commands/generate_entry.go b/pkg/commands/generate_entry.go index eaed7f1f..b0fbed81 100644 --- a/pkg/commands/generate_entry.go +++ b/pkg/commands/generate_entry.go @@ -146,12 +146,17 @@ func (c *GenerateEntryCommand) resolveTargets( // can't be reached — we fall back to the name in Execute. images := map[string]string{} if listResult, err := c.listCommand.Execute(ctx); err == nil { + found := false for _, container := range listResult.Containers { if container.Name == opts.ContainerName { images[opts.ContainerName] = container.Image + found = true break } } + if !found && !opts.Delete { + return nil, nil, "", fmt.Errorf("cannot find container %s, please create it first", opts.ContainerName) + } } return []string{opts.ContainerName}, images, opts.Icon, nil default: diff --git a/pkg/commands/generate_entry_test.go b/pkg/commands/generate_entry_test.go index 69f31414..f8294504 100644 --- a/pkg/commands/generate_entry_test.go +++ b/pkg/commands/generate_entry_test.go @@ -225,3 +225,44 @@ func TestGenerateEntryCommand_SingleModeUsesImageHint(t *testing.T) { assert.Contains(t, string(content), "ubuntu-distrobox.png", "single-mode must key auto-detection off the image (cached icon path), not the box name 'dev'") } + +// generate-entry refuses to write an entry for a container that does not +// exist (matches the shell, distrobox-generate-entry:285-288). +func TestGenerateEntryCommand_RefusesNonExistentContainer(t *testing.T) { + tempDir := t.TempDir() + mock := &testutil.MockContainerManager{ + ListContainersResult: []containermanager.Container{ + {Name: "other", Image: "alpine", Status: "Exited", Labels: map[string]string{"manager": "distrobox"}}, + }, + } + listCmd := commands.NewListCommand(&config.Values{}, mock) + cmd := commands.NewGenerateEntryCommand(&config.Values{}, listCmd) + + err := cmd.Execute(context.Background(), &commands.GenerateEntryOptions{ + ContainerName: "ghost", + DesktopEntryBaseDir: tempDir, + DistroboxPath: "/usr/bin/distrobox", + }) + require.Error(t, err) + assert.Contains(t, err.Error(), "cannot find container ghost") + assert.NoFileExists(t, filepath.Join(tempDir, "applications", "ghost.desktop")) +} + +// --delete must NOT require the container to exist (its box may already +// be gone when rm cleans up the entry). +func TestGenerateEntryCommand_DeleteNonExistentNoError(t *testing.T) { + tempDir := t.TempDir() + mock := &testutil.MockContainerManager{ + ListContainersResult: []containermanager.Container{}, + } + listCmd := commands.NewListCommand(&config.Values{}, mock) + cmd := commands.NewGenerateEntryCommand(&config.Values{}, listCmd) + + err := cmd.Execute(context.Background(), &commands.GenerateEntryOptions{ + ContainerName: "ghost", + Delete: true, + DesktopEntryBaseDir: tempDir, + DistroboxPath: "/usr/bin/distrobox", + }) + require.NoError(t, err) +}