mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Address code review feedback: convert absolute to relative paths for portability
Co-authored-by: Jack251970 <53996452+Jack251970@users.noreply.github.com>
This commit is contained in:
parent
864eedd255
commit
3de9e535ec
4 changed files with 134 additions and 5 deletions
|
|
@ -42,7 +42,7 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resolves the configured executable path to an absolute path.
|
/// Resolves the configured plugin settings file path to an absolute path.
|
||||||
/// Supports both absolute paths and relative paths (relative to ProgramDirectory).
|
/// Supports both absolute paths and relative paths (relative to ProgramDirectory).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private string ResolvedPluginsSettingsFilePath => Constant.ResolveAbsolutePath(PluginsSettingsFilePath);
|
private string ResolvedPluginsSettingsFilePath => Constant.ResolveAbsolutePath(PluginsSettingsFilePath);
|
||||||
|
|
@ -74,7 +74,8 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(selectedFile))
|
if (!string.IsNullOrEmpty(selectedFile))
|
||||||
{
|
{
|
||||||
PluginsSettingsFilePath = selectedFile;
|
// Convert to relative path if within ProgramDirectory for portability
|
||||||
|
PluginsSettingsFilePath = Constant.ConvertToRelativePathIfPossible(selectedFile);
|
||||||
}
|
}
|
||||||
// Nothing selected because user pressed cancel from the file dialog window
|
// Nothing selected because user pressed cancel from the file dialog window
|
||||||
else
|
else
|
||||||
|
|
@ -98,7 +99,8 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(selectedFile))
|
if (!string.IsNullOrEmpty(selectedFile))
|
||||||
{
|
{
|
||||||
PluginsSettingsFilePath = selectedFile;
|
// Convert to relative path if within ProgramDirectory for portability
|
||||||
|
PluginsSettingsFilePath = Constant.ConvertToRelativePathIfPossible(selectedFile);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -76,5 +76,46 @@ namespace Flow.Launcher.Infrastructure
|
||||||
// Resolve relative to ProgramDirectory
|
// Resolve relative to ProgramDirectory
|
||||||
return Path.GetFullPath(Path.Combine(ProgramDirectory, path));
|
return Path.GetFullPath(Path.Combine(ProgramDirectory, path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts an absolute path to a relative path if it's within ProgramDirectory.
|
||||||
|
/// This enables portability by storing paths relative to the program directory when possible.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="absolutePath">The absolute path to convert</param>
|
||||||
|
/// <returns>A relative path if the path is within ProgramDirectory, otherwise the original absolute path</returns>
|
||||||
|
public static string ConvertToRelativePathIfPossible(string absolutePath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(absolutePath))
|
||||||
|
return absolutePath;
|
||||||
|
|
||||||
|
if (!Path.IsPathRooted(absolutePath))
|
||||||
|
return absolutePath;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Get the full absolute paths for comparison
|
||||||
|
var fullAbsolutePath = Path.GetFullPath(absolutePath);
|
||||||
|
var fullProgramDir = Path.GetFullPath(ProgramDirectory);
|
||||||
|
|
||||||
|
// Check if the absolute path is within ProgramDirectory
|
||||||
|
if (fullAbsolutePath.StartsWith(fullProgramDir, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// Convert to relative path
|
||||||
|
var relativePath = Path.GetRelativePath(fullProgramDir, fullAbsolutePath);
|
||||||
|
|
||||||
|
// Prefix with .\ for clarity
|
||||||
|
if (!relativePath.StartsWith("."))
|
||||||
|
relativePath = ".\\" + relativePath;
|
||||||
|
|
||||||
|
return relativePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// If conversion fails, return the original path
|
||||||
|
}
|
||||||
|
|
||||||
|
return absolutePath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,5 +100,89 @@ namespace Flow.Launcher.Test
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(uncPath, result);
|
Assert.Equal(uncPath, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ConvertToRelativePathIfPossible_WithPathInProgramDirectory_ReturnsRelativePath()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var absolutePath = Path.Combine(Constant.ProgramDirectory, "runtimes", "python", "pythonw.exe");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = Constant.ConvertToRelativePathIfPossible(absolutePath);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.True(result.StartsWith(".\\"), "Result should start with .\\");
|
||||||
|
Assert.Contains("runtimes", result);
|
||||||
|
Assert.Contains("python", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ConvertToRelativePathIfPossible_WithPathOutsideProgramDirectory_ReturnsAbsolutePath()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var absolutePath = @"C:\Python\python.exe";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = Constant.ConvertToRelativePathIfPossible(absolutePath);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(absolutePath, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ConvertToRelativePathIfPossible_WithRelativePath_ReturnsOriginalPath()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var relativePath = @".\runtimes\python\pythonw.exe";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = Constant.ConvertToRelativePathIfPossible(relativePath);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(relativePath, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ConvertToRelativePathIfPossible_WithNullPath_ReturnsNull()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
string nullPath = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = Constant.ConvertToRelativePathIfPossible(nullPath);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Null(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ConvertToRelativePathIfPossible_WithEmptyPath_ReturnsEmpty()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var emptyPath = string.Empty;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = Constant.ConvertToRelativePathIfPossible(emptyPath);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(string.Empty, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void RoundTripTest_RelativePathResolutionAndConversion()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var originalRelative = @".\runtimes\python\pythonw.exe";
|
||||||
|
|
||||||
|
// Act - Resolve to absolute
|
||||||
|
var absolute = Constant.ResolveAbsolutePath(originalRelative);
|
||||||
|
// Convert back to relative
|
||||||
|
var backToRelative = Constant.ConvertToRelativePathIfPossible(absolute);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.True(Path.IsPathRooted(absolute), "Resolved path should be absolute");
|
||||||
|
Assert.True(backToRelative.StartsWith(".\\"), "Converted path should be relative");
|
||||||
|
Assert.Contains("runtimes\\python\\pythonw.exe", backToRelative);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -377,7 +377,8 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(selectedFile))
|
if (!string.IsNullOrEmpty(selectedFile))
|
||||||
Settings.PluginSettings.PythonExecutablePath = selectedFile;
|
// Convert to relative path if within ProgramDirectory for portability
|
||||||
|
Settings.PluginSettings.PythonExecutablePath = Constant.ConvertToRelativePathIfPossible(selectedFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
|
|
@ -389,7 +390,8 @@ public partial class SettingsPaneGeneralViewModel : BaseModel
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(selectedFile))
|
if (!string.IsNullOrEmpty(selectedFile))
|
||||||
Settings.PluginSettings.NodeExecutablePath = selectedFile;
|
// Convert to relative path if within ProgramDirectory for portability
|
||||||
|
Settings.PluginSettings.NodeExecutablePath = Constant.ConvertToRelativePathIfPossible(selectedFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue