plugin env paths correction after update or mode change

This commit is contained in:
Jeremy 2022-12-01 14:40:24 +11:00
parent d297779e4b
commit 5975b6e5c8
6 changed files with 133 additions and 61 deletions

View file

@ -1,4 +1,4 @@
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
@ -7,11 +7,12 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
internal abstract class AbstractPluginEnvironment
public abstract class AbstractPluginEnvironment
{
internal abstract string Language { get; }
@ -31,6 +32,12 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
internal PluginsSettings PluginSettings;
private const string updatePythonIndicatorFilename = ".updatePythonPath";
private const string updateNodeIndicatorFilename = ".updateNodePath";
private const string appDataRegex = @"app-\d\.\d\.\d";
internal AbstractPluginEnvironment(List<PluginMetadata> pluginMetadataList, PluginsSettings pluginSettings)
{
PluginMetadataList = pluginMetadataList;
@ -149,5 +156,117 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
return string.Empty;
}
}
public static void IndicatePluginEnvPathsUpdate(Settings settings, string newVer)
{
var appVer = $"app-{newVer}";
var updatePythonIndicatorFilePath
= Regex.Replace(Path.Combine(DataLocation.PluginEnvironments, updatePythonIndicatorFilename), appDataRegex, appVer);
var updateNodeIndicatorFilePath
= Regex.Replace(Path.Combine(DataLocation.PluginEnvironments, updateNodeIndicatorFilename), appDataRegex, appVer);
if (!string.IsNullOrEmpty(settings.PluginSettings.PythonExecutablePath)
&& settings.PluginSettings.PythonExecutablePath.StartsWith(DataLocation.PluginEnvironments))
using (var _ = File.CreateText(updatePythonIndicatorFilePath)) { }
if (!string.IsNullOrEmpty(settings.PluginSettings.NodeExecutablePath)
&& settings.PluginSettings.NodeExecutablePath.StartsWith(DataLocation.PluginEnvironments))
using (var _ = File.CreateText(updateNodeIndicatorFilePath)) { }
}
public static void PreStartPluginFilePathCorrection(Settings settings)
{
PreStartCorrectionAfterUpdate(settings);
PreStartCorrectionAfterModeChange(settings);
}
private static void PreStartCorrectionAfterUpdate(Settings settings)
{
// After updating flow, update plugin env paths.
var appVer = $"app-{Constant.Version}";
var updatePythonIndicatorFilePath = Path.Combine(DataLocation.PluginEnvironments, updatePythonIndicatorFilename);
var updateNodeIndicatorFilePath = Path.Combine(DataLocation.PluginEnvironments, updateNodeIndicatorFilename);
if (File.Exists(updatePythonIndicatorFilePath))
{
settings.PluginSettings.PythonExecutablePath
= Regex.Replace(settings.PluginSettings.PythonExecutablePath, appDataRegex, appVer);
File.Delete(updatePythonIndicatorFilePath);
}
if (File.Exists(updateNodeIndicatorFilePath))
{
settings.PluginSettings.NodeExecutablePath
= Regex.Replace(settings.PluginSettings.NodeExecutablePath, appDataRegex, appVer);
File.Delete(updateNodeIndicatorFilePath);
}
}
private static void PreStartCorrectionAfterModeChange(Settings settings)
{
// After enabling/disabling portable mode, update plugin env paths.
if (DataLocation.PortableDataLocationInUse())
{
// When user is using portable but has moved flow to a different location
if (IsUsingPortablePath(settings.PluginSettings.PythonExecutablePath, DataLocation.PythonEnvironmentName)
&& !settings.PluginSettings.PythonExecutablePath.StartsWith(DataLocation.PortableDataPath))
{
settings.PluginSettings.PythonExecutablePath
= GetUpdatedPortablePath(settings.PluginSettings.PythonExecutablePath, DataLocation.PythonEnvironmentName);
}
if (IsUsingPortablePath(settings.PluginSettings.NodeExecutablePath, DataLocation.NodeEnvironmentName)
&& !settings.PluginSettings.NodeExecutablePath.StartsWith(DataLocation.PortableDataPath))
{
settings.PluginSettings.NodeExecutablePath
= GetUpdatedPortablePath(settings.PluginSettings.NodeExecutablePath, DataLocation.NodeEnvironmentName);
}
// When user has switched from roaming to portable
if (IsUsingRoamingPath(settings.PluginSettings.PythonExecutablePath))
{
settings.PluginSettings.PythonExecutablePath
= settings.PluginSettings.PythonExecutablePath.Replace(DataLocation.RoamingDataPath, DataLocation.PortableDataPath);
}
if (IsUsingRoamingPath(settings.PluginSettings.NodeExecutablePath))
{
settings.PluginSettings.NodeExecutablePath
= settings.PluginSettings.NodeExecutablePath.Replace(DataLocation.RoamingDataPath, DataLocation.PortableDataPath);
}
}
else
{
if (IsUsingPortablePath(settings.PluginSettings.PythonExecutablePath, DataLocation.PythonEnvironmentName))
settings.PluginSettings.PythonExecutablePath
= GetUpdatedPortablePath(settings.PluginSettings.PythonExecutablePath, DataLocation.PythonEnvironmentName);
if (IsUsingPortablePath(settings.PluginSettings.NodeExecutablePath, DataLocation.NodeEnvironmentName))
settings.PluginSettings.NodeExecutablePath
= GetUpdatedPortablePath(settings.PluginSettings.NodeExecutablePath, DataLocation.NodeEnvironmentName);
}
}
private static bool IsUsingPortablePath(string filePath, string pluginEnvironmentName)
{
var portableAppEnvLocation = $"UserData\\{DataLocation.PluginEnvironments}\\{pluginEnvironmentName}";
return filePath.Contains(portableAppEnvLocation);
}
private static bool IsUsingRoamingPath(string filePath)
{
return filePath.StartsWith(DataLocation.RoamingDataPath);
}
private static string GetUpdatedPortablePath(string filePath, string pluginEnvironmentName)
{
var index = filePath.IndexOf(DataLocation.PluginEnvironments);
// get the substring after "Environments" because we can not determine it
var updatedPath = filePath.Substring(index + DataLocation.PluginEnvironments.Count());
return $"{DataLocation.PluginEnvironmentsPath}{updatedPath}";
}
}
}

View file

@ -12,9 +12,9 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
internal override string Language => AllowedLanguage.Python;
internal override string EnvName => "Python";
internal override string EnvName => DataLocation.PythonEnvironmentName;
internal override string EnvPath => Path.Combine(DataLocation.PluginEnvironments, EnvName);
internal override string EnvPath => Path.Combine(DataLocation.PluginEnvironmentsPath, EnvName);
internal override string InstallPath => Path.Combine(EnvPath, "PythonEmbeddable-v3.8.9");

View file

@ -12,9 +12,9 @@ namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
internal override string Language => AllowedLanguage.TypeScript;
internal override string EnvName => "Node.js";
internal override string EnvName => DataLocation.NodeEnvironmentName;
internal override string EnvPath => Path.Combine(DataLocation.PluginEnvironments, EnvName);
internal override string EnvPath => Path.Combine(DataLocation.PluginEnvironmentsPath, EnvName);
internal override string InstallPath => Path.Combine(EnvPath, "Node-v16.18.0");
internal override string ExecutablePath => Path.Combine(InstallPath, "node-v16.18.0-win-x64\\node.exe");

View file

@ -17,8 +17,7 @@ using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using System.Text.Json.Serialization;
using System.Threading;
using System.IO;
using System.Text.RegularExpressions;
using Flow.Launcher.Core.ExternalPlugins.Environments;
namespace Flow.Launcher.Core
{
@ -26,12 +25,6 @@ namespace Flow.Launcher.Core
{
public string GitHubRepository { get; }
private string updatePythonIndicatorFilename = ".updatePythonPath";
private string updateNodeIndicatorFilename = ".updateNodePath";
private string appDataRegex = @"app-\d\.\d\.\d";
public Updater(string gitHubRepository)
{
GitHubRepository = gitHubRepository;
@ -82,7 +75,7 @@ namespace Flow.Launcher.Core
DataLocation.PortableDataPath,
targetDestination));
UpdatePluginEnvPaths(settings, newReleaseVersion.ToString());
AbstractPluginEnvironment.IndicatePluginEnvPathsUpdate(settings, newReleaseVersion.ToString());
}
else
{
@ -154,45 +147,5 @@ namespace Flow.Launcher.Core
return tips;
}
private void UpdatePluginEnvPaths(Settings settings, string newVer)
{
var appVer = $"app-{newVer}";
var updatePythonIndicatorFilePath
= Regex.Replace(Path.Combine(DataLocation.PluginEnvironments, updatePythonIndicatorFilename), appDataRegex, appVer);
var updateNodeIndicatorFilePath
= Regex.Replace(Path.Combine(DataLocation.PluginEnvironments, updateNodeIndicatorFilename), appDataRegex, appVer);
if (!string.IsNullOrEmpty(settings.PluginSettings.PythonExecutablePath)
&& settings.PluginSettings.PythonExecutablePath.StartsWith(DataLocation.PluginEnvironments))
using (var _ = File.CreateText(updatePythonIndicatorFilePath)){}
if (!string.IsNullOrEmpty(settings.PluginSettings.NodeExecutablePath)
&& settings.PluginSettings.NodeExecutablePath.StartsWith(DataLocation.PluginEnvironments))
using (var _ = File.CreateText(updateNodeIndicatorFilePath)) { }
}
public void PreStartSetupAfterAppUpdate(Settings settings)
{
var appVer = $"app-{Constant.Version}";
var updatePythonIndicatorFilePath = Path.Combine(DataLocation.PluginEnvironments, updatePythonIndicatorFilename);
var updateNodeIndicatorFilePath = Path.Combine(DataLocation.PluginEnvironments, updateNodeIndicatorFilename);
if (File.Exists(updatePythonIndicatorFilePath))
{
settings.PluginSettings.PythonExecutablePath
= Regex.Replace(settings.PluginSettings.PythonExecutablePath, appDataRegex, appVer);
File.Delete(updatePythonIndicatorFilePath);
}
if (File.Exists(updateNodeIndicatorFilePath))
{
settings.PluginSettings.NodeExecutablePath
= Regex.Replace(settings.PluginSettings.NodeExecutablePath, appDataRegex, appVer);
File.Delete(updateNodeIndicatorFilePath);
}
}
}
}

View file

@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Flow.Launcher.Infrastructure.UserSettings
{
@ -32,6 +28,9 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public static readonly string PluginsDirectory = Path.Combine(DataDirectory(), Constant.Plugins);
public static readonly string PluginSettingsDirectory = Path.Combine(DataDirectory(), "Settings", Constant.Plugins);
public static readonly string PluginEnvironments = Path.Combine(DataDirectory(), "Environments");
public const string PythonEnvironmentName = "Python";
public const string NodeEnvironmentName = "Node.js";
public const string PluginEnvironments = "Environments";
public static readonly string PluginEnvironmentsPath = Path.Combine(DataDirectory(), PluginEnvironments);
}
}

View file

@ -6,6 +6,7 @@ using System.Timers;
using System.Windows;
using Flow.Launcher.Core;
using Flow.Launcher.Core.Configuration;
using Flow.Launcher.Core.ExternalPlugins.Environments;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Core.Resource;
using Flow.Launcher.Helper;
@ -61,7 +62,7 @@ namespace Flow.Launcher
_settingsVM = new SettingWindowViewModel(_updater, _portable);
_settings = _settingsVM.Settings;
_updater.PreStartSetupAfterAppUpdate(_settings);
AbstractPluginEnvironment.PreStartPluginFilePathCorrection(_settings);
_alphabet.Initialize(_settings);
_stringMatcher = new StringMatcher(_alphabet);