Skip to content

Conversation

@symball
Copy link
Contributor

@symball symball commented Jan 4, 2026

Linked with #4852

Description

Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.

Fixes # (issue)

Type of change

Please select the option that is relevant.

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

Tested on a fresh install of Fedora 43 ARM64 within a VM. does not apply to windows or mac

Test Configuration

# Wails
Version         | v2.11.0
Package Manager | dnf    


# System
┌────────────────────────────────────────────────────────────────────┐
| OS           | Fedora Linux                                        |
| Version      | 43                                                  |
| ID           | fedora                                              |
| Branding     |                                                     |
| Go Version   | go1.25.5 X:nodwarf5                                 |
| Platform     | linux                                               |
| Architecture | arm64                                               |
| CPU          |                                                     |
| GPU          | Virtio 1.0 GPU (Red Hat, Inc.) - Driver: virtio-pci |
| Memory       | 8GB                                                 |
└────────────────────────────────────────────────────────────────────┘

# Dependencies
┌───────────────────────────────────────────────────────┐
| Dependency | Package Name       | Status    | Version |
| *docker    | moby-engine        | Installed | 29.1.3  |
| gcc        | gcc-c++            | Installed | 15.2.1  |
| libgtk-3   | gtk3-devel         | Installed | 3.24.51 |
| libwebkit  | Unknown            | Not Found |         |
| npm        | nodejs-npm         | Installed | 10.9.3  |
| pkg-config | pkgconf-pkg-config | Installed | 2.3.0   |
| *upx       | upx                | Installed | 5.0.2   |
|                                                       |
└─────────────── * - Optional Dependency ───────────────┘

Summary by CodeRabbit

  • Bug Fixes
    • Improved library detection: added a fallback search when standard detection fails, helping the system locate installed libraries on more environments and reducing false negatives during setup or runtime.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 4, 2026

📝 Walkthrough

Walkthrough

The changes add a fallback mechanism to library detection in the checkLibrary function: if pkg-config --cflags returns no output, the code executes a shell find across /usr/lib* and /lib* to locate <name>*.so*. A changelog entry documents this fix.

Changes

Cohort / File(s) Summary
Library detection fallback
v2/internal/system/system.go
Added fallback search logic in checkLibrary: when pkg-config --cflags returns no output, runs sh -c "find /usr/lib* /lib* -name '<name>*.so*' -print -quit" and treats any stdout as evidence the library is installed. Added imports: bytes, fmt, log.
Changelog documentation
website/src/pages/changelog.mdx
Added bullet in Unreleased Fixed describing the new fallback behavior in checkLibrary.

Sequence Diagram(s)

sequenceDiagram
  participant App as checkLibrary()
  participant Pkg as pkg-config
  participant Shell as sh (find)
  participant FS as Filesystem

  Note over App,Pkg: Primary attempt
  App->>Pkg: run `pkg-config --cflags <name>`
  alt pkg-config returns flags
    Pkg-->>App: cflags (non-empty)
    Note right of App: Use pkg-config result
  else pkg-config empty
    Pkg-->>App: empty
    Note over App,Shell: Fallback search
    App->>Shell: run `sh -c "find /usr/lib* /lib* -name '<name>*.so*' -print -quit"`
    Shell->>FS: traverse /usr/lib*, /lib*
    FS-->>Shell: paths (if found) or nothing
    Shell-->>App: stdout (paths) or empty
    alt stdout non-empty
      App->>App: mark installed = true
    else stdout empty
      App->>App: mark installed = false
    end
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related issues

  • #4852 — Directly related; implements the same filesystem fallback for checkLibrary when pkg-config fails.

Suggested reviewers

  • leaanthony

Poem

🐰 When pkg-config gives a frown,
I hop through folders up and down.
In /lib and /usr/lib I peep,
Finding shared secrets buried deep.
A little hop, a discovery leap! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding a fallback mechanism to search the file system for libraries when pkg-config fails.
Description check ✅ Passed The description is mostly complete with linked issue, type of change selected, test configuration provided, and changelog updated; however, the 'Fixes #' field is incomplete and some template fields lack detail.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ff6e31d and 9f549bc.

📒 Files selected for processing (2)
  • v2/internal/system/system.go
  • website/src/pages/changelog.mdx
🚧 Files skipped from review as they are similar to previous changes (2)
  • v2/internal/system/system.go
  • website/src/pages/changelog.mdx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run Go Tests (ubuntu-22.04, 1.23)
  • GitHub Check: Run Go Tests (ubuntu-24.04, 1.23)
  • GitHub Check: Run Go Tests (windows-latest, 1.23)
  • GitHub Check: semgrep-cloud-platform/scan

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@symball symball force-pushed the libcheck_fallback branch from bc9e766 to ff6e31d Compare January 4, 2026 07:51
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
v2/internal/system/system.go (1)

130-136: Consider refining the pattern to avoid overly broad matches.

The pattern name*.so* (e.g., gtk-3*.so*) might match unintended libraries. For example, if searching for "gtk-3", it would also match "gtk-30", "gtk-300", etc. While this may be acceptable for the fallback use case, consider whether a more precise pattern like libname*.so* would be more appropriate (since libraries typically have a "lib" prefix).

🔎 Alternative pattern with lib prefix
-		pattern := fmt.Sprintf("%s*.so*", name)
+		pattern := fmt.Sprintf("lib%s*.so*", name)
 
 		// We'll use the shell to keep the globbing (/usr/lib*, /lib*) and pipeline.
 		cmdStr := fmt.Sprintf(

Note: Verify that this aligns with how library names are provided to checkLibrary.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6630fa5 and ff6e31d.

📒 Files selected for processing (2)
  • v2/internal/system/system.go
  • website/src/pages/changelog.mdx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run Go Tests (macos-latest, 1.23)
  • GitHub Check: Run Go Tests (ubuntu-24.04, 1.23)
  • GitHub Check: Run Go Tests (ubuntu-22.04, 1.23)
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (3)
website/src/pages/changelog.mdx (1)

26-26: LGTM! Changelog entry is clear and well-formatted.

The changelog entry accurately describes the new fallback mechanism and follows the established format.

v2/internal/system/system.go (2)

4-6: LGTM! Standard library imports are appropriate.

The new imports (bytes, fmt, log) are all from the standard library and necessary for the fallback implementation.


128-152: Confirmed: library names are always hardcoded and trusted.

The checkLibrary function is called only twice in the codebase (in v2/internal/system/system_linux.go), both with hardcoded library names: "libgtk-3" and "libwebkit". There is no risk of command injection from this usage pattern.

Comment on lines 128 to 152
// As a fallback, attempt to look for presence of the library using find
if !installed {
pattern := fmt.Sprintf("%s*.so*", name)

// We'll use the shell to keep the globbing (/usr/lib*, /lib*) and pipeline.
// stderr is redirected to /dev/null to match the original command.
cmdStr := fmt.Sprintf(
`find /usr/lib* /lib* -type f -name %q`,
pattern,
)

cmd := exec.Command("sh", "-c", cmdStr)

var out bytes.Buffer
cmd.Stdout = &out

if err := cmd.Run(); err != nil {
log.Printf("error running sh -c: %v", err)
}

raw := strings.TrimSpace(out.String())
if raw != "" {
installed = true
}
}
Copy link
Contributor

@coderabbitai coderabbitai bot Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add platform guard for Linux-only fallback.

According to the PR objectives, this fallback is intended for Linux only and does not apply to Windows or macOS. However, the code lacks a platform check and will execute on all operating systems. On Windows and macOS, the paths /usr/lib* and /lib* don't exist in the expected form, causing unnecessary command failures.

🔎 Suggested fix to add platform guard
 	// As a fallback, attempt to look for presence of the library using find
 	if !installed {
+		// Only attempt filesystem fallback on Linux
+		if runtime.GOOS != "linux" {
+			return &packagemanager.Dependency{
+				Name:           "lib" + name + " ",
+				PackageName:    "N/A",
+				Installed:      false,
+				InstallCommand: "Install via your package manager",
+				Version:        "N/A",
+				Optional:       false,
+				External:       false,
+			}
+		}
+
 		pattern := fmt.Sprintf("%s*.so*", name)
 
 		// We'll use the shell to keep the globbing (/usr/lib*, /lib*) and pipeline.

Note: You'll also need to add "runtime" to the imports at the top of the file.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In v2/internal/system/system.go around lines 128 to 152, the fallback that runs
a shell find over /usr/lib* and /lib* must only run on Linux; add a platform
guard using runtime.GOOS (import "runtime") and only execute the shell+find
branch when runtime.GOOS == "linux". Leave the existing logic untouched for
other OSes, and ensure the function returns or skips the fallback early when not
linux so the find command is not invoked on Windows or macOS.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is only called on Linux so your suggestion is irrelevant

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Find where checkLibrary is called in the codebase
echo "=== Finding checkLibrary invocations ==="
rg -n "checkLibrary" --type=go -C5

echo -e "\n=== Checking for OS-specific logic in system package ==="
# Look for runtime.GOOS checks in the system package
rg -n "runtime\.GOOS|build.*linux|build.*darwin|build.*windows" v2/internal/system/ --type=go -C3

echo -e "\n=== Looking for discover method implementation ==="
# Find the discover method that might have OS-specific dependency checking
ast-grep --pattern $'func ($$$) discover() $$$'

Length of output: 9747


🏁 Script executed:

#!/bin/bash

# Also check for any build tags in the system package files
echo "=== Checking for build tags in system package ==="
fd --type f --extension go . v2/internal/system/ --exec head -3 {}

echo -e "\n=== Looking at dependency list population ==="
# Find where Dependencies are populated
rg -n "Dependencies.*=" v2/internal/system/ --type=go -C5

Length of output: 3541


@symball, you're absolutely right, and I apologize for the incorrect suggestion.

I've verified that checkLibrary is only called from system_linux.go (lines 58-59), which has //go:build linux build constraints. This means the function will never execute on Windows or macOS, even though it's defined in the shared system.go file. The Go build system ensures the call sites are only compiled for Linux.

The runtime platform guard would be redundant. Thank you for the clarification!


🧬 Code Graph Analysis Results

[v2/internal/system/packagemanager/packagemanager.go:59-101]
func Dependencies(p PackageManager) (DependencyList, error) {

var dependencies DependencyList

for name, packages := range p.Packages() {
	dependency := &Dependency{Name: name}
	for _, pkg := range packages {
		dependency.Optional = pkg.Optional
		dependency.External = !pkg.SystemPackage
		dependency.InstallCommand = p.InstallCommand(pkg)
		packageavailable, err := p.PackageAvailable(pkg)
		if err != nil {
			return nil, err
		}
		if packageavailable {
			dependency.Version = pkg.Version
			dependency.PackageName = pkg.Name
			installed, err := p.PackageInstalled(pkg)
			if err != nil {
				return nil, err
			}
			if installed {
				dependency.Installed = true
				dependency.Version = pkg.Version
				if !pkg.SystemPackage {
					dependency.Version = AppVersion(name)
				}
			} else {
				dependency.InstallCommand = p.InstallCommand(pkg)
			}
			break
		}
	}
	dependencies = append(dependencies, dependency)
}

// Sort dependencies
sort.Slice(dependencies, func(i, j int) bool {
	return dependencies[i].Name < dependencies[j].Name
})

return dependencies, nil

}

[v2/internal/system/packagemanager/pm.go:16-22]
PackageManager interface {
Name() string
Packages() packagemap
PackageInstalled(pkg *Package) (bool, error)
PackageAvailable(pkg *Package) (bool, error)
InstallCommand(pkg *Package) string
}

[v2/internal/system/operatingsystem/os.go:4-9]
OS struct {
ID string
Name string
Version string
Branding string
}

[v2/internal/shell/shell.go:9-15]
Command struct {
command string
args []string
env []string
dir string
stdo, stde bytes.Buffer
}


[v2/internal/shell/shell.go:63-65]
func RunCommand(directory string, command string, args ...string) (string, string, error) {
return RunCommandWithEnv(nil, directory, command, args...)
}


✏️ Learnings added
Learnt from: symball
Repo: wailsapp/wails PR: 4853
File: v2/internal/system/system.go:128-152
Timestamp: 2026-01-04T08:01:00.038Z
Learning: In the wails repository, v2/internal/system/system.go contains shared functions like checkLibrary that are defined without build tags, but these functions are only invoked from platform-specific files (system_linux.go, system_windows.go, system_darwin.go) that have appropriate build constraints. The build tags on the calling files ensure platform-specific behavior without needing runtime checks.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

pattern := fmt.Sprintf("%s*.so*", name)

// We'll use the shell to keep the globbing (/usr/lib*, /lib*) and pipeline.
// stderr is redirected to /dev/null to match the original command.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix inaccurate comment or implement stderr redirection.

Line 133 states "stderr is redirected to /dev/null to match the original command," but the code doesn't actually redirect stderr. Either update the comment to reflect the actual behavior or implement the stderr redirection.

🔎 Option 1: Update comment to match implementation
-		// We'll use the shell to keep the globbing (/usr/lib*, /lib*) and pipeline.
-		// stderr is redirected to /dev/null to match the original command.
+		// We'll use the shell to keep the globbing (/usr/lib*, /lib*).
 		cmdStr := fmt.Sprintf(
🔎 Option 2: Implement stderr redirection as documented
 		cmd := exec.Command("sh", "-c", cmdStr)
 
 		var out bytes.Buffer
 		cmd.Stdout = &out
+		cmd.Stderr = nil  // Discard stderr
 
 		if err := cmd.Run(); err != nil {

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In v2/internal/system/system.go around line 133 the comment claims "stderr is
redirected to /dev/null" but the code doesn't perform that; either update the
comment to remove the incorrect claim or implement real stderr redirection: set
the command's Stderr to a discard writer (cmd.Stderr = io.Discard) or open
os.DevNull and assign the file (f, _ := os.OpenFile(os.DevNull, os.O_WRONLY, 0);
defer f.Close(); cmd.Stderr = f) and add the necessary import, ensuring the
comment matches the chosen behavior.
@symball symball force-pushed the libcheck_fallback branch from ff6e31d to 9f549bc Compare January 4, 2026 07:58
@sonarqubecloud
Copy link

sonarqubecloud bot commented Jan 4, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
1 Security Hotspot

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant