Skip to content

Comments

Support relative paths for Python/Node.js executables#4230

Open
Jack251970 wants to merge 19 commits intodevfrom
copilot/support-relative-paths
Open

Support relative paths for Python/Node.js executables#4230
Jack251970 wants to merge 19 commits intodevfrom
copilot/support-relative-paths

Conversation

@Jack251970
Copy link
Member

Flow Launcher required absolute paths for Python and Node.js executables, breaking portability when the application is moved. Embedded runtimes within the portable directory structure were not supported.

CHANGES

  • ResolveAbsolutePath(): Resolves relative paths to absolute at runtime, based on ProgramDirectory
  • Path resolution integrated at file existence checks and plugin instantiation

Usage

Users can now configure:

Python Path: .\runtimes\python\pythonw.exe
Node.js Path: .\runtimes\nodejs\node.exe

Paths are stored as-entered (relative or absolute), resolved to absolute only at execution. File picker selections within ProgramDirectory are automatically stored as relative paths.

Enables truly portable setups with embedded runtimes that survive directory moves, USB installations, and restricted environments.

Resolve #4228

Copilot AI and others added 10 commits January 24, 2026 07:43
Co-authored-by: Jack251970 <53996452+Jack251970@users.noreply.github.com>
Co-authored-by: Jack251970 <53996452+Jack251970@users.noreply.github.com>
…portability

Co-authored-by: Jack251970 <53996452+Jack251970@users.noreply.github.com>
Removed logic that converted selected Python and Node executable
paths to relative if within the program directory. Now, the
selected file paths are stored as absolute paths without
conversion. This simplifies path handling and improves clarity.
Removed the PathResolutionTest.cs file, which contained unit tests for the Constant class's path resolution methods. These tests covered absolute, relative, UNC, null, and empty path scenarios, as well as round-trip conversions.
Move ResolveAbsolutePath and ConvertToRelativePathIfPossible from Constant to DataLocation for better organization. Update all references accordingly; implementations remain unchanged. This improves code clarity around file path management.
Eliminated the unnecessary using statement for Flow.Launcher.Infrastructure in AbstractPluginEnvironment.cs, as its types or members are no longer referenced in this file. This helps clean up the code and avoid redundant dependencies.
Removed logic that converted absolute paths to relative paths within the ProgramDirectory. Now, plugin settings file paths are always stored as absolute paths. Deleted the ConvertToRelativePathIfPossible method and updated usages accordingly.
Copilot AI review requested due to automatic review settings January 24, 2026 08:09
@github-actions github-actions bot added this to the 2.1.0 milestone Jan 24, 2026
@gitstream-cm
Copy link

gitstream-cm bot commented Jan 24, 2026

Be a legend 🏆 by adding a before and after screenshot of the changes you made, especially if they are around UI/UX.

@coderabbitai coderabbitai bot added the enhancement New feature or request label Jan 24, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 24, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Resolves plugin settings file paths to absolute paths by adding DataLocation.ResolveAbsolutePath and updating AbstractPluginEnvironment to use the resolved path for file existence checks, conditional plugin installation, and returned settings paths.

Changes

Cohort / File(s) Summary
Path resolution utility
Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs
Add public static string ResolveAbsolutePath(string path) which returns null/empty unchanged, returns absolute paths as-is, resolves relative paths against Constant.ProgramDirectory via Path.GetFullPath, and catches path-related exceptions to return the original input.
Plugin environment path usage
Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs
Add private ResolvedPluginsSettingsFilePath => DataLocation.ResolveAbsolutePath(PluginsSettingsFilePath) and replace direct uses of PluginsSettingsFilePath with the resolved path for File.Exists checks, the EnsureLatestInstalled decision, post-interaction checks, and returned plugin pairs/settings path. Minor control-flow adjustments to derive and reuse the resolved path consistently.

Sequence Diagram(s)

sequenceDiagram
    participant Env as AbstractPluginEnvironment
    participant Locator as DataLocation
    participant FS as FileSystem
    participant Installer as PluginInstaller
    participant Caller as Caller

    Env->>Locator: ResolveAbsolutePath(PluginsSettingsFilePath)
    Locator-->>Env: resolvedPath
    Env->>FS: File.Exists(resolvedPath)?
    alt exists
        Env->>Installer: EnsureLatestInstalled(resolvedPath) [conditional]
        Installer-->>Env: installedPairs
        Env-->>Caller: return installedPairs (using resolvedPath)
    else not exists
        Env-->>Caller: proceed without settings file
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested reviewers

  • jjw24
  • taooceros
  • VictoriousRaptor
  • Garulf
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly relates to the main changeset, which adds relative path support for Python/Node.js executables.
Description check ✅ Passed The description is related to the changeset, explaining relative path support, the ResolveAbsolutePath implementation, and usage examples.
Linked Issues check ✅ Passed The changes implement the core coding requirement from issue #4228: ResolveAbsolutePath method enables relative paths to be resolved at runtime against ProgramDirectory, supporting portable embedded runtimes.
Out of Scope Changes check ✅ Passed All changes are scoped to implementing relative path resolution: a new public method in DataLocation and integration into AbstractPluginEnvironment for resolving paths at execution.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch copilot/support-relative-paths

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.

@Jack251970 Jack251970 enabled auto-merge January 24, 2026 08:12
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request adds support for relative paths in Python and Node.js executable configuration, enabling truly portable Flow Launcher setups. The changes allow users to configure runtime paths relative to the application directory (e.g., .\runtimes\python\pythonw.exe), which are resolved to absolute paths at runtime.

Changes:

  • Added ResolveAbsolutePath() method to handle relative-to-absolute path resolution
  • Integrated path resolution into plugin environment setup and file existence checks
  • Paths are stored as-entered (relative or absolute) and resolved only at execution time

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs Adds ResolveAbsolutePath() method to resolve relative paths based on ProgramDirectory
Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs Integrates path resolution into plugin setup, using resolved paths for file checks and plugin instantiation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jjw24
Copy link
Member

jjw24 commented Jan 29, 2026

Please include in the portability testing of Python/Node.js when installed by flow.

If I remember correctly when they are installed from flow, they get reinstalled automatically when path is not correct right?

@Jack251970
Copy link
Member Author

Please include in the portability testing of Python/Node.js when installed by flow.

If I remember correctly when they are installed from flow, they get reinstalled automatically when path is not correct right?

This PR focuses on parsing relative paths. Why do we need to check this portability?

@Jack251970
Copy link
Member Author

Even if reinstallation is invoked, the relative paths can still work.

@jjw24 jjw24 disabled auto-merge January 29, 2026 23:07
@jjw24 jjw24 enabled auto-merge (squash) January 29, 2026 23:08
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Jack251970 and others added 2 commits February 21, 2026 20:12
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

2 issues found across 2 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs">

<violation number="1" location="Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs:59">
P2: `Path.IsPathRooted` evaluates partially qualified paths as true. Use `Path.IsPathFullyQualified` to correctly check for absolute paths.</violation>
</file>

<file name="Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs">

<violation number="1" location="Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs:64">
P1: `resolvedPath` becomes stale after `EnsureLatestInstalled()` updates the environment path.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

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.

🧹 Nitpick comments (1)
Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs (1)

59-60: Consider Path.IsPathFullyQualified over Path.IsPathRooted for portability edge cases

Path.IsPathRooted(@"\runtimes\python\pythonw.exe") returns true, so a drive-relative path like \runtimes\python\pythonw.exe would be passed through unchanged rather than resolved against ProgramDirectory. Path.IsPathFullyQualified only returns true for genuinely absolute paths (e.g., C:\... or UNC \\server\share\...), which aligns more precisely with the method's stated intent.

♻️ Proposed change
-            if (Path.IsPathRooted(path))
+            if (Path.IsPathFullyQualified(path))
                return path;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs` around lines 59 -
60, In DataLocation.cs, in the method that returns the resolved path (the block
using Path.IsPathRooted(path)), replace the Path.IsPathRooted check with
Path.IsPathFullyQualified(path) so drive-relative paths like "\runtimes\..." are
not treated as absolute and will be correctly resolved against ProgramDirectory;
ensure System.IO is available and keep the existing return behavior when the
path is fully qualified.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs`:
- Around line 59-60: In DataLocation.cs, in the method that returns the resolved
path (the block using Path.IsPathRooted(path)), replace the Path.IsPathRooted
check with Path.IsPathFullyQualified(path) so drive-relative paths like
"\runtimes\..." are not treated as absolute and will be correctly resolved
against ProgramDirectory; ensure System.IO is available and keep the existing
return behavior when the path is fully qualified.

Updated the catch block in DataLocation.cs to explicitly use System.Exception instead of Exception when handling path resolution errors. This improves code clarity while maintaining the same error handling logic for ArgumentException, NotSupportedException, and PathTooLongException.
@gitstream-cm
Copy link

gitstream-cm bot commented Feb 21, 2026

🥷 Code experts: jjw24

jjw24, Jack251970 have most 👩‍💻 activity in the files.
jjw24, Jack251970 have most 🧠 knowledge in the files.

See details

Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs

Activity based on git-commit:

jjw24 Jack251970
FEB
JAN
DEC
NOV
OCT
SEP 17 additions & 28 deletions

Knowledge based on git-blame:
jjw24: 96%
Jack251970: 4%

Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs

Activity based on git-commit:

jjw24 Jack251970
FEB
JAN
DEC
NOV
OCT
SEP 29 additions & 27 deletions

Knowledge based on git-blame:
jjw24: 70%
Jack251970: 30%

✨ Comment /gs review for LinearB AI review. Learn how to automate it here.

Replaced Path.IsPathRooted with Path.IsPathFullyQualified to more accurately determine if a path is truly absolute, preventing misclassification of certain relative paths.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Jack251970 and others added 3 commits February 21, 2026 20:30
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@jjw24 jjw24 modified the milestones: 2.1.0, 2.2.0 Feb 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

5 min review enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for Relative Path for Portable Version

3 participants