Skip to content

linux: don't resolve symlink on executable#508

Merged
creativeprojects merged 1 commit intomasterfrom
linux-executable
Jun 12, 2025
Merged

linux: don't resolve symlink on executable#508
creativeprojects merged 1 commit intomasterfrom
linux-executable

Conversation

@creativeprojects
Copy link
Copy Markdown
Owner

Linux fix only:
Don't resolve symlink on executable to keep a constant name (the physical path of the binary might change for each version)

Fixes #490

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 31, 2025

Walkthrough

The changes introduce a cross-platform utility function for retrieving the current executable path, replacing direct calls to os.Executable() in favour of a custom util.Executable() function. Platform-specific implementations are provided for Linux and non-Linux systems, and usage is updated in relevant parts of the codebase. A test validates the new utility.

Changes

File(s) Change Summary
commands_display.go Updated to use util.Executable() for displaying the executable path in verbose version info.
schedule_jobs.go Replaced os.Executable() with util.Executable() for resolving the executable path.
util/executable.go, util/executable_linux.go Added platform-specific implementations of util.Executable() for retrieving executable path.
util/executable_test.go Added a test to ensure util.Executable() returns an absolute, non-empty path.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI_Command
    participant util.Executable

    User->>CLI_Command: Run command (e.g., schedule or display version)
    CLI_Command->>util.Executable: Call Executable()
    util.Executable-->>CLI_Command: Return executable path (platform-specific)
    CLI_Command-->>User: Use path in output or systemd unit
Loading

Assessment against linked issues

Objective Addressed Explanation
Use the correct, non-versioned executable path in generated systemd unit files and version output (#490)
Ensure cross-platform compatibility for executable path retrieval (#490)
Provide test coverage for the new executable path utility (#490)

Assessment against linked issues: Out-of-scope changes

No out-of-scope changes found.

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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
Copy Markdown

@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

🧹 Nitpick comments (2)
util/executable_test.go (1)

11-17: Well-structured test that validates the function contract.

The test correctly verifies that util.Executable() returns an absolute, non-empty path without errors. This ensures consistent behaviour across all platforms.

Consider adding a platform-specific test to verify that on Linux, the function returns the same result even when the binary is invoked via a symlink, which is the core use case this PR addresses.

util/executable.go (1)

7-12: Clean implementation with good documentation.

The function correctly delegates to os.Executable() for non-Linux platforms, maintaining existing behaviour. The documentation clearly explains the platform differences.

Consider updating the comment to be more specific about what "path to the executable as specified in the command line arguments" means (i.e., os.Args[0]) for better clarity.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 77b1f30 and f160554.

📒 Files selected for processing (5)
  • commands_display.go (2 hunks)
  • schedule_jobs.go (1 hunks)
  • util/executable.go (1 hunks)
  • util/executable_linux.go (1 hunks)
  • util/executable_test.go (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (5)
schedule_jobs.go (2)
util/executable_linux.go (1)
  • Executable (14-28)
util/executable.go (1)
  • Executable (10-12)
util/executable_test.go (2)
util/executable_linux.go (1)
  • Executable (14-28)
util/executable.go (1)
  • Executable (10-12)
util/executable.go (1)
util/executable_linux.go (1)
  • Executable (14-28)
commands_display.go (2)
util/executable_linux.go (1)
  • Executable (14-28)
util/executable.go (1)
  • Executable (10-12)
util/executable_linux.go (1)
util/executable.go (1)
  • Executable (10-12)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Build and test (1.24, windows-latest)
  • GitHub Check: Build and test (1.24, ubuntu-latest)
  • GitHub Check: Build and test (1.24, macos-latest)
  • GitHub Check: Analyze (go)
🔇 Additional comments (9)
schedule_jobs.go (2)

11-11: LGTM: Import addition aligns with the new utility function.

The import of the util package is correctly added to support the new util.Executable() function.


19-19: LGTM: Correctly replaces os.Executable() with util.Executable().

This change implements the PR objective by using the new platform-specific executable path resolution. On Linux, this will use os.Args[0] to avoid symlink resolution, whilst maintaining the original behaviour on other platforms.

util/executable.go (1)

1-2: Correct build constraint for non-Linux platforms.

The build constraint !linux ensures this implementation is used on all platforms except Linux, which aligns with the PR objective.

commands_display.go (2)

19-19: LGTM: Import addition supports the new utility function.

The import of the util package is correctly added to support the updated executable path retrieval.


262-267: Excellent error handling for display purposes.

The implementation correctly uses util.Executable() and gracefully handles errors by setting the executable path to "unknown". This is appropriate for diagnostic output where a missing path shouldn't cause the entire version display to fail.

util/executable_linux.go (4)

1-2: LGTM: Correct build constraint for Linux-specific code.

The build constraint properly restricts this implementation to Linux systems only.


5-9: LGTM: Appropriate imports for the implementation.

The imports are minimal and necessary for the functionality.


11-13: LGTM: Clear documentation explaining the Linux-specific behaviour.

The comment clearly explains the difference from os.Executable() and the Linux-specific implementation rationale.


14-28: Consider security implications and edge cases of using os.Args[0].

The implementation correctly avoids symlink resolution by using os.Args[0], which aligns with the PR objective. However, there are important considerations:

  1. Security consideration: os.Args[0] can be manipulated by the process invoker, unlike os.Executable() which uses system calls. This is less secure but might be acceptable for the use case.

  2. Edge case: The code should handle the case where os.Args slice is empty.

Consider adding a guard for empty os.Args slice:

 func Executable() (string, error) {
+	if len(os.Args) == 0 {
+		return "", errors.New("no command line arguments available")
+	}
 	executable := os.Args[0]
 	if len(executable) == 0 {
 		return "", errors.New("executable path is empty")
 	}

Please verify if this security trade-off is acceptable for your use case, considering that attackers could potentially manipulate the executable path through os.Args[0].

@codecov
Copy link
Copy Markdown

codecov Bot commented May 31, 2025

Codecov Report

Attention: Patch coverage is 40.00000% with 12 lines in your changes missing coverage. Please review.

Project coverage is 79.27%. Comparing base (77b1f30) to head (f160554).
Report is 3 commits behind head on master.

Files with missing lines Patch % Lines
util/executable_linux.go 25.00% 7 Missing and 2 partials ⚠️
commands_display.go 40.00% 2 Missing and 1 partial ⚠️

❌ Your patch status has failed because the patch coverage (40.00%) is below the target coverage (70.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #508      +/-   ##
==========================================
- Coverage   79.33%   79.27%   -0.06%     
==========================================
  Files         134      136       +2     
  Lines       13233    13252      +19     
==========================================
+ Hits        10498    10505       +7     
- Misses       2317     2326       +9     
- Partials      418      421       +3     
Flag Coverage Δ
unittests 79.27% <40.00%> (-0.06%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
60.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@creativeprojects creativeprojects merged commit 25c2f06 into master Jun 12, 2025
9 of 11 checks passed
@creativeprojects creativeprojects deleted the linux-executable branch June 12, 2025 21:26
@creativeprojects creativeprojects added this to the v0.32.0 milestone Jul 28, 2025
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.

Schedule command hard-codes version number when resticprofile is installed via Homebrew

1 participant