Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ internal AbstractPluginEnvironment(List<PluginMetadata> pluginMetadataList, Plug
PluginSettings = pluginSettings;
}

/// <summary>
/// Resolves the configured runtime executable path to an absolute path.
/// Supports both absolute paths and relative paths (relative to ProgramDirectory).
/// </summary>
private string ResolvedPluginsSettingsFilePath => DataLocation.ResolveAbsolutePath(PluginsSettingsFilePath);

internal IEnumerable<PluginPair> Setup()
{
// If no plugin is using the language, return empty list
Expand All @@ -48,13 +54,16 @@ internal IEnumerable<PluginPair> Setup()
return new List<PluginPair>();
}

if (!string.IsNullOrEmpty(PluginsSettingsFilePath) && FilesFolders.FileExists(PluginsSettingsFilePath))
var resolvedPath = ResolvedPluginsSettingsFilePath;
if (!string.IsNullOrEmpty(resolvedPath) && FilesFolders.FileExists(resolvedPath))
{
// Ensure latest only if user is using Flow's environment setup.
if (PluginsSettingsFilePath.StartsWith(EnvPath, StringComparison.OrdinalIgnoreCase))
EnsureLatestInstalled(ExecutablePath, PluginsSettingsFilePath, EnvPath);
if (resolvedPath.StartsWith(EnvPath, StringComparison.OrdinalIgnoreCase))
EnsureLatestInstalled(ExecutablePath, resolvedPath, EnvPath);

return SetPathForPluginPairs(PluginsSettingsFilePath, Language);
// Ensure the path is updated in settings in case environment was updated
resolvedPath = ResolvedPluginsSettingsFilePath;
return SetPathForPluginPairs(resolvedPath, Language);
}

var noRuntimeMessage = Localize.runtimePluginInstalledChooseRuntimePrompt(Language, EnvName, Environment.NewLine);
Expand Down Expand Up @@ -103,9 +112,11 @@ internal IEnumerable<PluginPair> Setup()
InstallEnvironment();
}

if (FilesFolders.FileExists(PluginsSettingsFilePath))
// Ensure the path is updated when user has chosen to install or select environment executable
resolvedPath = ResolvedPluginsSettingsFilePath;
if (FilesFolders.FileExists(resolvedPath))
{
return SetPathForPluginPairs(PluginsSettingsFilePath, Language);
return SetPathForPluginPairs(resolvedPath, Language);
}
else
{
Expand Down
29 changes: 29 additions & 0 deletions Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,34 @@ public static bool PortableDataLocationInUse()
public const string PluginEnvironments = "Environments";
public const string PluginDeleteFile = "NeedDelete.txt";
public static readonly string PluginEnvironmentsPath = Path.Combine(DataDirectory(), PluginEnvironments);

/// <summary>
/// Resolves a path that may be relative to an absolute path.
/// If the path is already absolute, returns it as-is.
/// If the path is not rooted (as determined by <see cref="Path.IsPathRooted(string)"/>), resolves it relative to ProgramDirectory.
/// </summary>
/// <param name="path">The path to resolve</param>
/// <returns>An absolute path</returns>
public static string ResolveAbsolutePath(string path)
{
if (string.IsNullOrEmpty(path))
return path;

// If already absolute, return as-is
if (Path.IsPathFullyQualified(path))
return path;

// Resolve relative to ProgramDirectory, handling invalid path formats gracefully
try
{
return Path.GetFullPath(Path.Combine(Constant.ProgramDirectory, path));
}
catch (System.Exception)
{
// If the path cannot be resolved (invalid characters, format, or too long),
// return the original path to avoid crashing the application.
return path;
}
}
}
}
Loading