Skip to content
Draft
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
18 changes: 11 additions & 7 deletions v2/internal/system/packagemanager/dnf.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (y *Dnf) PackageInstalled(pkg *Package) (bool, error) {
if pkg.SystemPackage == false {
return false, nil
}
stdout, _, err := shell.RunCommand(".", "dnf", "info", "installed", pkg.Name)
stdout, _, err := shell.RunCommand(".", "dnf", "-q", "list", "--installed", pkg.Name)
if err != nil {
_, ok := err.(*exec.ExitError)
if ok {
Expand All @@ -82,15 +82,19 @@ func (y *Dnf) PackageInstalled(pkg *Package) (bool, error) {
return false, err
}

splitoutput := strings.Split(stdout, "\n")
for _, line := range splitoutput {
if strings.HasPrefix(line, "Version") {
splitline := strings.Split(line, ":")
pkg.Version = strings.TrimSpace(splitline[1])
lines := strings.Split(stdout, "\n")
for _, line := range lines {
fields := strings.Fields(line)
if len(fields) >= 2 && strings.HasPrefix(fields[0], pkg.Name) {
versionArch := fields[1]
parts := strings.SplitN(versionArch, "-", 2)
if len(parts) > 0 {
pkg.Version = parts[0]
}
}
}

return true, err
return true, nil
}

// PackageAvailable tests if the given package is available for installation
Expand Down
109 changes: 109 additions & 0 deletions v2/test/4457/dnf_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package test4457

import (
"os"
"path/filepath"
"testing"

"github.com/wailsapp/wails/v2/internal/system/packagemanager"
)

func TestDnfPackageInstalledNotInstalled(t *testing.T) {
tmpDir := t.TempDir()
mockDnf := filepath.Join(tmpDir, "dnf")
script := `#!/bin/sh
# Mock dnf that simulates "package not installed" exit code
# dnf -q list --installed returns exit code 1 when package is not installed
exit 1
`
err := os.WriteFile(mockDnf, []byte(script), 0755)
if err != nil {
t.Fatal(err)
}

origPath := os.Getenv("PATH")
os.Setenv("PATH", tmpDir+":"+origPath)
defer os.Setenv("PATH", origPath)

dnf := packagemanager.NewDnf("fedora")
pkg := &packagemanager.Package{Name: "webkit2gtk4.0-devel", SystemPackage: true}

installed, err := dnf.PackageInstalled(pkg)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if installed {
t.Error("expected package to NOT be installed, but got installed=true")
}
}

func TestDnfPackageInstalledIsInstalled(t *testing.T) {
tmpDir := t.TempDir()
mockDnf := filepath.Join(tmpDir, "dnf")
script := `#!/bin/sh
# Mock dnf that simulates installed package output
echo "Installed packages"
echo "webkit2gtk4.0-devel.x86_64 2.46.5-1.fc41 updates"
exit 0
`
err := os.WriteFile(mockDnf, []byte(script), 0755)
if err != nil {
t.Fatal(err)
}

origPath := os.Getenv("PATH")
os.Setenv("PATH", tmpDir+":"+origPath)
defer os.Setenv("PATH", origPath)

dnf := packagemanager.NewDnf("fedora")
pkg := &packagemanager.Package{Name: "webkit2gtk4.0-devel", SystemPackage: true}

installed, err := dnf.PackageInstalled(pkg)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !installed {
t.Error("expected package to be installed, but got installed=false")
}
}

func TestDnfPackageInstalledOldDnfInfoFallbackFails(t *testing.T) {
tmpDir := t.TempDir()
mockDnf := filepath.Join(tmpDir, "dnf")
script := `#!/bin/sh
# This simulates the OLD behavior: "dnf info installed" returns available
# packages with exit code 0 even when not installed.
# With the fix using "dnf -q list --installed", exit code 1 means not installed.
# We verify the mock is called with the correct arguments.
for arg in "$@"; do
echo "ARG: $arg"
done
# If called with "info installed" (old behavior), exit 0 with version info (bug)
# If called with "-q list --installed" (new behavior), exit 1 (not installed)
if [ "$1" = "-q" ] && [ "$2" = "list" ] && [ "$3" = "--installed" ]; then
exit 1
fi
# Old path would reach here and incorrectly report installed
echo "Version : 2.46.5"
exit 0
`
err := os.WriteFile(mockDnf, []byte(script), 0755)
if err != nil {
t.Fatal(err)
}

origPath := os.Getenv("PATH")
os.Setenv("PATH", tmpDir+":"+origPath)
defer os.Setenv("PATH", origPath)

dnf := packagemanager.NewDnf("fedora")
pkg := &packagemanager.Package{Name: "webkit2gtk4.0-devel", SystemPackage: true}

installed, err := dnf.PackageInstalled(pkg)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if installed {
t.Error("expected package to NOT be installed with new dnf -q list --installed approach")
}
}
Loading