Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenFileManager for opening with the native file manager and optional file selection support #3937

Merged
merged 1 commit into from
Dec 13, 2024

Conversation

rcalixte
Copy link

@rcalixte rcalixte commented Dec 7, 2024

Closes #3197

cc @Krzysztofz01

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.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration using wails doctor.

  • Windows
  • macOS
  • Linux

If you checked Linux, please specify the distro and version.

Test Configuration

Please paste the output of wails doctor. If you are unable to run this command, please describe your environment in as much detail as possible.

Checklist:

  • I have updated website/src/pages/changelog.mdx with details of this PR
  • My code follows the general coding style of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new method to open the file manager with optional file selection highlighting.
    • Added support for Linux packaging and enhanced macOS builds.
    • New templates for SvelteKit have been introduced.
  • Bug Fixes

    • Resolved issues with callbacks running on the main thread for macOS.
    • Fixed deadlocks, compilation issues, and improved cross-platform compatibility.
  • Documentation

    • Updated changelog to reflect new features, fixes, and changes across versions.
    • Added documentation for events on the mkdocs website.

Copy link
Contributor

coderabbitai bot commented Dec 7, 2024

Walkthrough

The pull request introduces significant updates to the project's changelog and core functionality. A new method, app.OpenFileManager(path string, selectFile bool), is added to facilitate opening the file manager at a specified path with optional file selection. The Open function in the fileexplorer package has been replaced with OpenFileManager, enhancing error handling and modular command construction for different operating systems. Additionally, the OpenDirectory method in the application package has been removed in favor of the new method. Various fixes and improvements are documented in the changelog, reflecting ongoing development.

Changes

File Change Summary
mkdocs-website/docs/en/changelog.md Updated changelog to include new features, fixes, and changes, including the addition of app.OpenFileManager.
v3/internal/fileexplorer/fileexplorer.go Replaced Open with OpenFileManager, added error handling, and refactored command construction for OS compatibility.
v3/pkg/application/application.go Removed OpenDirectory method and added OpenFileManager method to the App struct.
v3/internal/fileexplorer/fileexplorer_test.go Added fileexplorer_test.go with tests for OpenFileManager across different operating systems.

Assessment against linked issues

Objective Addressed Explanation
Open folder and select a specified file (Issue #3197)
Open a specified folder, not a dialog (Issue #3197)
Open a specified file, not a dialog (Issue #3197) Unclear if the implementation fully supports this.

Possibly related PRs

Suggested reviewers

  • leaanthony

Poem

🐇 In the meadow where the changes bloom,
A file manager opens, dispelling the gloom.
With paths to explore and files to select,
Our code hops forward, what a fine project!
Through bugs and fixes, we dance with delight,
A brighter tomorrow, in code we unite! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Experiment)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 3

🧹 Outside diff range and nitpick comments (1)
mkdocs-website/docs/en/changelog.md (1)

23-23: Add Space Between Contributor Mentions for Correct Formatting

In line 23, there is no space between the two contributor mentions, which may affect Markdown rendering and make it harder to read.

Apply this diff to add a space:

23
    - `app.OpenFileManager(path string)` to open file manager to the path `path` with optional highlighting via `selectFile` by [@Krzysztofz01](https://github.com/Krzysztofz01)[@rcalixte](https://github.com/rcalixte)
+   - `app.OpenFileManager(path string)` to open file manager to the path `path` with optional highlighting via `selectFile` by [@Krzysztofz01](https://github.com/Krzysztofz01) [@rcalixte](https://github.com/rcalixte)
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 2e4fce7 and fcf7da2.

📒 Files selected for processing (3)
  • mkdocs-website/docs/en/changelog.md (1 hunks)
  • v3/internal/fileexplorer/fileexplorer.go (1 hunks)
  • v3/pkg/application/application.go (2 hunks)

v3/internal/fileexplorer/fileexplorer.go Outdated Show resolved Hide resolved
v3/internal/fileexplorer/fileexplorer.go Outdated Show resolved Hide resolved
v3/pkg/application/application.go Outdated Show resolved Hide resolved
@rcalixte rcalixte force-pushed the file_manager branch 5 times, most recently from adc6a94 to dc9056c Compare December 7, 2024 23:38
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: 0

🧹 Outside diff range and nitpick comments (3)
v3/internal/fileexplorer/fileexplorer.go (3)

20-21: Improve error message clarity

The error message includes redundant "stat" text which doesn't add value to the error context.

-		return fmt.Errorf("failed to access the specified path stat: %w", err)
+		return fmt.Errorf("failed to access the specified path: %w", err)

50-58: Consider adding context for command execution

The command execution could benefit from context to handle potential hanging processes, especially when dealing with external file managers.

+import "context"
+
 func OpenFileManager(path string, selectFile bool) error {
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+
-	cmd := exec.Command(explorerBin, explorerArgs...)
+	cmd := exec.CommandContext(ctx, explorerBin, explorerArgs...)

120-123: Consider supporting file selection in fallback mode

The fallback implementation currently forces directory opening and ignores the selectFile parameter. Consider implementing file selection support using alternative methods like dbus-send to communicate with file managers that support it.

 var linuxFallbackExplorerBinArgs explorerBinArgs = func(path string, selectFile bool) (string, []string, error) {
-	// NOTE: The linux fallback explorer opening is not supporting file selection
-	path = filepath.Dir(path)
+	if !selectFile {
+		path = filepath.Dir(path)
+	}
+	// Try dbus-send first for file managers that support it
+	if selectFile {
+		if _, err := exec.LookPath("dbus-send"); err == nil {
+			return "dbus-send", []string{
+				"--session",
+				"--dest=org.freedesktop.FileManager1",
+				"--type=method_call",
+				"/org/freedesktop/FileManager1",
+				"org.freedesktop.FileManager1.ShowItems",
+				fmt.Sprintf("array:string:file://%s", path),
+				"string:''",
+			}, nil
+		}
+	}
 	return "xdg-open", []string{path}, nil
 }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between fcf7da2 and dc9056c.

📒 Files selected for processing (3)
  • mkdocs-website/docs/en/changelog.md (1 hunks)
  • v3/internal/fileexplorer/fileexplorer.go (1 hunks)
  • v3/pkg/application/application.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • mkdocs-website/docs/en/changelog.md
  • v3/pkg/application/application.go
🔇 Additional comments (4)
v3/internal/fileexplorer/fileexplorer.go (4)

62-70: LGTM! Windows implementation is correct

The implementation properly handles both directory opening and file selection scenarios using the appropriate explorer.exe flags.


72-80: LGTM! macOS implementation is correct

The implementation correctly uses the open command with the -R flag for file selection.


90-94: Possible Incorrect Path Construction When XDG_DATA_HOME Is Unset

This is a previously identified issue that still needs to be addressed.


106-113: ⚠️ Potential issue

Fix duplicate path argument and improve desktop entry handling

There are two issues in this section:

  1. The path is being appended twice (once through %f/%F replacement and again explicitly)
  2. The desktop entry Exec field handling needs improvement (previously identified)
 		exec := cfg.Section("Desktop Entry").Key("Exec").String()
 		exec = strings.ReplaceAll(exec, "%f", path)
 		exec = strings.ReplaceAll(exec, "%F", path)
 		exec = strings.ReplaceAll(exec, "%u", path)
 		exec = strings.ReplaceAll(exec, "%U", path)
 		args := strings.Fields(exec)
-		args = append(args, path)
 
 		return args[0], args[1:], nil

Likely invalid or redundant comment.

@rcalixte rcalixte force-pushed the file_manager branch 2 times, most recently from 7d2559a to 683d9bf Compare December 7, 2024 23:59
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: 0

🧹 Outside diff range and nitpick comments (4)
v3/internal/fileexplorer/fileexplorer.go (4)

21-21: Consider a longer timeout for slow systems or network paths.

The 5-second timeout might be insufficient when dealing with slow systems, network paths, or when the file manager is slow to start.

-ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)

24-29: Enhance path validation.

The current path validation could be more robust by:

  1. Converting to absolute path
  2. Cleaning the path to remove any . or ..
  3. Checking for symlink resolution
-path = os.ExpandEnv(path)
-if pathInfo, err := os.Stat(path); err != nil {
+path = os.ExpandEnv(path)
+path = filepath.Clean(path)
+absPath, err := filepath.Abs(path)
+if err != nil {
+    return fmt.Errorf("failed to resolve absolute path: %w", err)
+}
+path = absPath
+if pathInfo, err := os.Stat(path); err != nil {

47-47: Improve error message for unsupported platforms.

The error message could be more specific by including the current platform.

-return errors.New("unsupported platform")
+return fmt.Errorf("platform %q is not supported", runtime.GOOS)

127-130: Consider Supporting File Selection in Fallback Mode

The fallback implementation could try alternative file managers that support file selection (e.g., nautilus, dolphin, nemo) before falling back to xdg-open.

var linuxFallbackExplorerBinArgs explorerBinArgs = func(path string, selectFile bool) (string, []string, error) {
-    // NOTE: The linux fallback explorer opening is not supporting file selection
-    path = filepath.Dir(path)
-    return "xdg-open", []string{path}, nil
+    if !selectFile {
+        return "xdg-open", []string{path}, nil
+    }
+    
+    // Try common file managers that support selection
+    fileManagers := []struct {
+        bin  string
+        args []string
+    }{
+        {"nautilus", []string{"--select"}},
+        {"dolphin", []string{"--select"}},
+        {"nemo", []string{"--no-desktop"}},
+    }
+    
+    for _, fm := range fileManagers {
+        if _, err := exec.LookPath(fm.bin); err == nil {
+            args := append(fm.args, path)
+            return fm.bin, args, nil
+        }
+    }
+    
+    // If no file manager supports selection, fall back to opening the directory
+    return "xdg-open", []string{filepath.Dir(path)}, nil
}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between dc9056c and 683d9bf.

📒 Files selected for processing (3)
  • mkdocs-website/docs/en/changelog.md (1 hunks)
  • v3/internal/fileexplorer/fileexplorer.go (1 hunks)
  • v3/pkg/application/application.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • v3/pkg/application/application.go
  • mkdocs-website/docs/en/changelog.md
🔇 Additional comments (5)
v3/internal/fileexplorer/fileexplorer.go (5)

18-18: Well-designed type for platform-specific implementations!

The explorerBinArgs function type provides a clean interface for implementing platform-specific file manager opening logic.


67-75: LGTM! Proper handling of Windows explorer.exe quirks.

The implementation correctly:

  • Handles paths with spaces using quotes
  • Implements file selection using the /select flag
  • Ignores exit codes due to known Windows explorer.exe behavior

77-85: LGTM! Clean macOS implementation.

The implementation correctly uses the open command with the -R flag for file selection, following macOS conventions.


95-99: 🛠️ Refactor suggestion

Incorrect Path Construction When XDG_DATA_HOME Is Unset

The path construction should use filepath.Join for better cross-platform compatibility.

-xdgPath := strings.TrimSpace(os.Getenv("XDG_DATA_HOME"))
-if xdgPath == "" {
-    xdgPath = os.Getenv("HOME") + "/.local/share"
-}
-desktopFile = xdgPath + "/applications/" + strings.TrimSpace((buf.String()))
+xdgPath := strings.TrimSpace(os.Getenv("XDG_DATA_HOME"))
+if xdgPath == "" {
+    xdgPath = filepath.Join(os.Getenv("HOME"), ".local", "share")
+}
+desktopFile = filepath.Join(xdgPath, "applications", strings.TrimSpace(buf.String()))

111-119: 🛠️ Refactor suggestion

Enhance Desktop Entry Field Code Handling

While the code handles basic field codes, it should also:

  1. Handle field codes with URIs (%u, %U) properly by converting paths to URIs
  2. Handle other field codes like %d, %D, %n, %N, %v, %m
  3. Strip out any remaining unhandled field codes
+func pathToURI(path string) string {
+    absPath, err := filepath.Abs(path)
+    if err != nil {
+        return path
+    }
+    return "file://" + absPath
+}
+
 exec := cfg.Section("Desktop Entry").Key("Exec").String()
-exec = strings.ReplaceAll(exec, "%f", path)
-exec = strings.ReplaceAll(exec, "%F", path)
-exec = strings.ReplaceAll(exec, "%u", path)
-exec = strings.ReplaceAll(exec, "%U", path)
+exec = strings.ReplaceAll(exec, "%f", path)
+exec = strings.ReplaceAll(exec, "%F", path)
+exec = strings.ReplaceAll(exec, "%u", pathToURI(path))
+exec = strings.ReplaceAll(exec, "%U", pathToURI(path))
+// Strip other field codes
+exec = strings.NewReplacer(
+    "%d", "",
+    "%D", "",
+    "%n", "",
+    "%N", "",
+    "%v", "",
+    "%m", "",
+).Replace(exec)

Likely invalid or redundant comment.

Copy link
Member

@leaanthony leaanthony left a comment

Choose a reason for hiding this comment

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

Nice one! Do you think we could add some tests to ensure that the string processing does what we think it should?

@rcalixte
Copy link
Author

rcalixte commented Dec 8, 2024

Nice one! Do you think we could add some tests to ensure that the string processing does what we think it should?

I've added some tests but it would help to have paths that are known at the time the tests are running.

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

🧹 Outside diff range and nitpick comments (1)
v3/internal/fileexplorer/fileexplorer_test.go (1)

1-40: Consider adding integration tests.

While unit tests are valuable, the current implementation would benefit from integration tests that verify the actual interaction with the native file manager.

Consider:

  1. Adding integration test markers (e.g., //+build integration)
  2. Implementing platform-specific process verification
  3. Adding user interaction simulation tests
  4. Documenting manual test scenarios

Would you like me to help create a separate integration test file with these improvements?

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 683d9bf and 1b282aa.

📒 Files selected for processing (4)
  • mkdocs-website/docs/en/changelog.md (1 hunks)
  • v3/internal/fileexplorer/fileexplorer.go (1 hunks)
  • v3/internal/fileexplorer/fileexplorer_test.go (1 hunks)
  • v3/pkg/application/application.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • v3/pkg/application/application.go
  • mkdocs-website/docs/en/changelog.md
  • v3/internal/fileexplorer/fileexplorer.go
🔇 Additional comments (1)
v3/internal/fileexplorer/fileexplorer_test.go (1)

1-8: LGTM! Clean package structure and imports.

The test package name and imports are correctly defined.

v3/internal/fileexplorer/fileexplorer_test.go Outdated Show resolved Hide resolved
v3/internal/fileexplorer/fileexplorer_test.go Outdated Show resolved Hide resolved
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

🧹 Outside diff range and nitpick comments (2)
v3/internal/fileexplorer/fileexplorer.go (2)

20-35: Consider increasing the timeout duration for slow systems.

The 10-second timeout might be insufficient for slow systems or network paths. Consider making this configurable or increasing it to handle edge cases.

-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)

31-35: Enhance path validation for edge cases.

While the current path validation is good, consider adding checks for:

  • Path length limits on Windows
  • Special characters that might cause issues with shell execution
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 1b282aa and 17abf0b.

📒 Files selected for processing (4)
  • mkdocs-website/docs/en/changelog.md (1 hunks)
  • v3/internal/fileexplorer/fileexplorer.go (1 hunks)
  • v3/internal/fileexplorer/fileexplorer_test.go (1 hunks)
  • v3/pkg/application/application.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • v3/internal/fileexplorer/fileexplorer_test.go
  • v3/pkg/application/application.go
  • mkdocs-website/docs/en/changelog.md
🔇 Additional comments (2)
v3/internal/fileexplorer/fileexplorer.go (2)

4-15: LGTM! Well-structured imports and type definition.

The new imports and the explorerBinArgs function type are well-organized and appropriate for the functionality. The type definition provides a clean interface for platform-specific implementations.

Also applies to: 18-19


20-71: Verify input validation for security concerns.

The code executes commands based on user input, which could potentially be exploited.

✅ Verification successful

Let me analyze the code and search results to verify the security concerns.

The code in fileexplorer.go shows proper input validation and path sanitization:

  1. Uses os.ExpandEnv() to safely expand environment variables
  2. Uses filepath.Clean() to normalize the path and remove any . or .. components
  3. Uses filepath.Abs() to resolve to absolute path
  4. Validates path existence with os.Stat() before proceeding
  5. The command execution uses platform-specific predefined binaries and arguments (via explorerBinArgs)
  6. Command execution is constrained with a timeout context

Let's verify the platform-specific command execution:


Let's check the platform-specific implementations to ensure they handle the command arguments securely:


Let's try a different search pattern to find the platform-specific implementations:


Input validation and command execution are properly secured

The code implements multiple layers of security:

  1. Path sanitization:

    • Uses os.ExpandEnv(), filepath.Clean(), and filepath.Abs() to safely handle paths
    • Validates path existence with os.Stat()
  2. Command execution safety:

    • Uses platform-specific predefined binaries (explorer.exe, open, xdg-open)
    • Arguments are properly constructed without shell interpolation
    • Command execution is constrained with a timeout context
    • Windows: Properly quotes paths in arguments
    • Darwin: Uses safe -R flag for selection
    • Linux: Safely handles desktop entries and falls back to xdg-open
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential command injection vulnerabilities

# Test: Search for command execution without proper escaping
rg -A 5 'exec\.Command|os\.StartProcess'

# Test: Check for path traversal protection
rg -A 5 'filepath\.Clean|filepath\.Abs'

Length of output: 66158


Script:

#!/bin/bash
# Check platform-specific command execution implementations
rg -A 10 'type explorerBinArgs'

Length of output: 894


Script:

#!/bin/bash
# Check platform-specific command execution implementations
rg -A 15 'func \w+ExplorerBinArgs'

Length of output: 36


Script:

#!/bin/bash
# Search for platform-specific explorer implementations
rg -A 15 'var \w+ExplorerBinArgs'

# Also search for any file with 'explorer' in the name to find the implementations
fd explorer

Length of output: 3824

v3/internal/fileexplorer/fileexplorer.go Outdated Show resolved Hide resolved
v3/internal/fileexplorer/fileexplorer.go Outdated Show resolved Hide resolved
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: 3

🧹 Outside diff range and nitpick comments (4)
v3/internal/fileexplorer/fileexplorer.go (3)

21-23: Consider increasing the timeout duration.

The 10-second timeout might be too short for slow systems or network drives. Consider making this configurable or increasing it to 30 seconds.

-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)

62-64: Consider logging command output on error.

While suppressing command output is generally good, it might be helpful to capture and log it when an error occurs to aid in debugging.

-	cmd.Stdout = nil
-	cmd.Stderr = nil
+	var stdout, stderr bytes.Buffer
+	cmd.Stdout = &stdout
+	cmd.Stderr = &stderr

Then in the error handling:

 	if err := cmd.Run(); err != nil {
 		if !ignoreExitCode {
-			return fmt.Errorf("failed to open the file explorer: %w", err)
+			return fmt.Errorf("failed to open the file explorer: %w (stdout: %s, stderr: %s)", 
+				err, stdout.String(), stderr.String())
 		}
 	}

140-144: Consider warning about disabled file selection in fallback mode.

When falling back to xdg-open, if selectFile is true, consider returning a warning in the error message.

-	return "xdg-open", []string{path}, nil
+	if selectFile {
+		return "xdg-open", []string{path}, fmt.Errorf("file selection not supported in fallback mode")
+	}
+	return "xdg-open", []string{path}, nil
v3/internal/fileexplorer/fileexplorer_test.go (1)

20-29: Consider adding more error test cases.

The test cases could be expanded to include:

  • Invalid paths with special characters
  • Network paths
  • Paths with insufficient permissions
 	tests := []struct {
 		name        string
 		path        string
 		selectFile  bool
 		expectedErr error
 	}{
 		{"Open Existing File", tempDir, false, nil},
 		{"Select Existing File", tempDir, true, nil},
 		{"Non-Existent Path", "/path/does/not/exist", false, fmt.Errorf("failed to access the specified path: /path/does/not/exist")},
+		{"Path With Special Chars", filepath.Join(tempDir, "test space.txt"), true, nil},
+		{"No Permission Path", "/root/test.txt", false, fmt.Errorf("failed to access the specified path")},
 	}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 17abf0b and 8484c61.

📒 Files selected for processing (4)
  • mkdocs-website/docs/en/changelog.md (1 hunks)
  • v3/internal/fileexplorer/fileexplorer.go (1 hunks)
  • v3/internal/fileexplorer/fileexplorer_test.go (1 hunks)
  • v3/pkg/application/application.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • v3/pkg/application/application.go
  • mkdocs-website/docs/en/changelog.md
🔇 Additional comments (4)
v3/internal/fileexplorer/fileexplorer.go (4)

25-36: LGTM! Robust path handling implementation.

The path handling is thorough with:

  • Environment variable expansion
  • Path cleaning and normalization
  • Absolute path resolution
  • Existence validation
  • Smart handling of selectFile based on path type

74-82: LGTM! Clean Windows implementation.

The Windows implementation correctly handles:

  • File selection with /select flag
  • Path quoting
  • Command argument construction

84-92: LGTM! Clean macOS implementation.

The macOS implementation correctly uses the 'open' command with proper handling of the -R flag for file selection.


146-168: LGTM! Well-implemented helper functions.

Both pathToURI and findDesktopFile are well-implemented:

  • Proper URL encoding
  • Following XDG specification
  • Good error handling

v3/internal/fileexplorer/fileexplorer.go Show resolved Hide resolved
v3/internal/fileexplorer/fileexplorer_test.go Outdated Show resolved Hide resolved
v3/internal/fileexplorer/fileexplorer_test.go Outdated Show resolved Hide resolved
@rcalixte
Copy link
Author

rcalixte commented Dec 8, 2024

Nice one! Do you think we could add some tests to ensure that the string processing does what we think it should?

I think it's ready for review. Let me know if anything else should be changed.

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: 0

🧹 Outside diff range and nitpick comments (2)
v3/internal/fileexplorer/fileexplorer.go (2)

74-82: Consider enhancing path escaping for Windows.

While the current implementation works, it could be improved to handle special characters in paths more robustly.

-		args = append(args, fmt.Sprintf("/select,\"%s\"", path))
+		args = append(args, fmt.Sprintf("/select,%s", strings.ReplaceAll(path, "\"", "\"\"")))

94-138: Consider adding error logging and improving path handling.

The Linux implementation could benefit from:

  1. Logging errors before falling back
  2. More robust path handling in args
 if err := fileManagerQuery.Run(); err != nil {
+	a.Logger.Debug("Failed to query default file manager", "error", err)
 	return linuxFallbackExplorerBinArgs(path, selectFile)
 }

 desktopFile, err := findDesktopFile(strings.TrimSpace((buf.String())))
 if err != nil {
+	a.Logger.Debug("Failed to find desktop file", "error", err)
 	return linuxFallbackExplorerBinArgs(path, selectFile)
 }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7958150 and 48157e3.

📒 Files selected for processing (4)
  • mkdocs-website/docs/en/changelog.md (1 hunks)
  • v3/internal/fileexplorer/fileexplorer.go (1 hunks)
  • v3/internal/fileexplorer/fileexplorer_test.go (1 hunks)
  • v3/pkg/application/application.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • v3/internal/fileexplorer/fileexplorer_test.go
🔇 Additional comments (6)
v3/internal/fileexplorer/fileexplorer.go (4)

19-72: Well-structured implementation with proper error handling and path validation!

The implementation includes:

  • Appropriate use of context with timeout
  • Thorough path validation and error handling
  • Clear separation of platform-specific logic

84-92: Clean implementation following macOS conventions!

The implementation correctly uses the 'open' command with appropriate flags.


140-144: Appropriate fallback implementation with clear documentation!

The fallback mechanism is well-documented and provides basic functionality when the primary method fails.


146-168: Well-implemented helper functions following standards!

Both helper functions are properly implemented:

  • pathToURI handles path escaping correctly
  • findDesktopFile follows XDG specification for desktop entry locations
mkdocs-website/docs/en/changelog.md (1)

22-22: Well-documented changelog entry!

The changelog properly documents the new feature with clear attribution to contributors.

v3/pkg/application/application.go (1)

1050-1054: Clean implementation with proper synchronization!

The OpenFileManager method is well-implemented:

  • Uses InvokeSyncWithError for thread safety
  • Properly forwards parameters to the fileexplorer package

@leaanthony leaanthony merged commit d03f4ce into wailsapp:v3-alpha Dec 13, 2024
2 of 3 checks passed
@rcalixte rcalixte deleted the file_manager branch December 13, 2024 19:45
@coderabbitai coderabbitai bot mentioned this pull request Dec 18, 2024
15 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants