Fix: creating a locator should not affect static state

This commit is contained in:
Caelan Sayler
2025-05-23 20:13:46 +01:00
parent 1177ec864e
commit 9f27e4d975
7 changed files with 45 additions and 36 deletions

View File

@@ -57,6 +57,12 @@ namespace Velopack.Locators
/// </summary> /// </summary>
IProcessImpl Process { get; } IProcessImpl Process { get; }
/// <summary>
/// Add a logger to the list of loggers. This will be used to log messages from Velopack.
/// </summary>
/// <param name="logger"></param>
void AddLogger(IVelopackLogger logger);
/// <summary> /// <summary>
/// Finds .nupkg files in the PackagesDir and returns a list of ReleaseEntryName objects. /// Finds .nupkg files in the PackagesDir and returns a list of ReleaseEntryName objects.
/// </summary> /// </summary>

View File

@@ -36,9 +36,6 @@ namespace Velopack.Locators
/// <inheritdoc /> /// <inheritdoc />
public override string? Channel { get; } public override string? Channel { get; }
/// <inheritdoc />
public override IVelopackLogger Log { get; }
/// <inheritdoc /> /// <inheritdoc />
public override string? AppTempDir => CreateSubDirIfDoesNotExist(TempUtil.GetDefaultTempBaseDirectory(), AppId); public override string? AppTempDir => CreateSubDirIfDoesNotExist(TempUtil.GetDefaultTempBaseDirectory(), AppId);
@@ -63,15 +60,13 @@ namespace Velopack.Locators
if (!VelopackRuntimeInfo.IsLinux) if (!VelopackRuntimeInfo.IsLinux)
throw new NotSupportedException($"Cannot instantiate {nameof(LinuxVelopackLocator)} on a non-linux system."); throw new NotSupportedException($"Cannot instantiate {nameof(LinuxVelopackLocator)} on a non-linux system.");
var combinedLog = new CombinedVelopackLogger(); CombinedLogger = new CombinedVelopackLogger(customLog);
combinedLog.Add(customLog);
Log = combinedLog;
Process = processImpl ??= new DefaultProcessImpl(combinedLog); Process = processImpl ??= new DefaultProcessImpl(CombinedLogger);
var ourPath = processImpl.GetCurrentProcessPath(); var ourPath = processImpl.GetCurrentProcessPath();
var currentProcessId = processImpl.GetCurrentProcessId(); var currentProcessId = processImpl.GetCurrentProcessId();
using var initLog = new CachedVelopackLogger(combinedLog); using var initLog = new CachedVelopackLogger(CombinedLogger);
initLog.Info($"Initializing {nameof(LinuxVelopackLocator)}"); initLog.Info($"Initializing {nameof(LinuxVelopackLocator)}");
var logFilePath = Path.Combine(Path.GetTempPath(), DefaultLoggingFileName); var logFilePath = Path.Combine(Path.GetTempPath(), DefaultLoggingFileName);
@@ -107,7 +102,7 @@ namespace Velopack.Locators
try { try {
var fileLog = new FileVelopackLogger(logFilePath, currentProcessId); var fileLog = new FileVelopackLogger(logFilePath, currentProcessId);
combinedLog.Add(fileLog); CombinedLogger.Add(fileLog);
} catch (Exception ex) { } catch (Exception ex) {
initLog.Error("Unable to create file logger: " + ex); initLog.Error("Unable to create file logger: " + ex);
} }

View File

@@ -39,9 +39,6 @@ namespace Velopack.Locators
/// <inheritdoc /> /// <inheritdoc />
public override string? PackagesDir => CreateSubDirIfDoesNotExist(CachesAppDir, "packages"); public override string? PackagesDir => CreateSubDirIfDoesNotExist(CachesAppDir, "packages");
/// <inheritdoc />
public override IVelopackLogger Log { get; }
private string? CachesAppDir => CreateSubDirIfDoesNotExist(CachesVelopackDir, AppId); private string? CachesAppDir => CreateSubDirIfDoesNotExist(CachesVelopackDir, AppId);
private string? CachesVelopackDir => CreateSubDirIfDoesNotExist(CachesDir, "velopack"); private string? CachesVelopackDir => CreateSubDirIfDoesNotExist(CachesDir, "velopack");
private string? CachesDir => CreateSubDirIfDoesNotExist(LibraryDir, "Caches"); private string? CachesDir => CreateSubDirIfDoesNotExist(LibraryDir, "Caches");
@@ -60,15 +57,13 @@ namespace Velopack.Locators
if (!VelopackRuntimeInfo.IsOSX) if (!VelopackRuntimeInfo.IsOSX)
throw new NotSupportedException($"Cannot instantiate {nameof(OsxVelopackLocator)} on a non-osx system."); throw new NotSupportedException($"Cannot instantiate {nameof(OsxVelopackLocator)} on a non-osx system.");
var combinedLog = new CombinedVelopackLogger(); CombinedLogger = new CombinedVelopackLogger(customLog);
combinedLog.Add(customLog);
Log = combinedLog;
Process = processImpl ??= new DefaultProcessImpl(combinedLog); Process = processImpl ??= new DefaultProcessImpl(CombinedLogger);
var ourPath = processImpl.GetCurrentProcessPath(); var ourPath = processImpl.GetCurrentProcessPath();
var currentProcessId = processImpl.GetCurrentProcessId(); var currentProcessId = processImpl.GetCurrentProcessId();
using var initLog = new CachedVelopackLogger(combinedLog); using var initLog = new CachedVelopackLogger(CombinedLogger);
initLog.Info($"Initializing {nameof(OsxVelopackLocator)}"); initLog.Info($"Initializing {nameof(OsxVelopackLocator)}");
string logFolder = Path.GetTempPath(); string logFolder = Path.GetTempPath();
@@ -107,7 +102,7 @@ namespace Velopack.Locators
try { try {
var logFilePath = Path.Combine(logFolder, logFileName); var logFilePath = Path.Combine(logFolder, logFileName);
var fileLog = new FileVelopackLogger(logFilePath, currentProcessId); var fileLog = new FileVelopackLogger(logFilePath, currentProcessId);
combinedLog.Add(fileLog); CombinedLogger.Add(fileLog);
} catch (Exception ex) { } catch (Exception ex) {
initLog.Error("Unable to create file logger: " + ex); initLog.Error("Unable to create file logger: " + ex);
} }

View File

@@ -15,7 +15,7 @@ namespace Velopack.Locators
public abstract class VelopackLocator : IVelopackLocator public abstract class VelopackLocator : IVelopackLocator
{ {
private static IVelopackLocator? _current; private static IVelopackLocator? _current;
/// <summary> /// <summary>
/// The default log file name for Velopack. /// The default log file name for Velopack.
/// </summary> /// </summary>
@@ -34,7 +34,8 @@ namespace Velopack.Locators
get { get {
if (_current == null) if (_current == null)
throw new InvalidOperationException( throw new InvalidOperationException(
$"No VelopackLocator has been set. Either call {nameof(VelopackApp)}.{nameof(VelopackApp.Build)}() or provide {nameof(IVelopackLocator)} as a method parameter."); $"No VelopackLocator has been set. Either call {nameof(VelopackApp)}.{nameof(VelopackApp.Build)}().Run() " +
$"or provide {nameof(IVelopackLocator)} as a method parameter.");
return _current; return _current;
} }
} }
@@ -43,13 +44,13 @@ namespace Velopack.Locators
public static IVelopackLocator CreateDefaultForPlatform(IProcessImpl? processImpl = null, IVelopackLogger? logger = null) public static IVelopackLocator CreateDefaultForPlatform(IProcessImpl? processImpl = null, IVelopackLogger? logger = null)
{ {
if (VelopackRuntimeInfo.IsWindows) if (VelopackRuntimeInfo.IsWindows)
return _current = new WindowsVelopackLocator(processImpl, logger); return new WindowsVelopackLocator(processImpl, logger);
if (VelopackRuntimeInfo.IsOSX) if (VelopackRuntimeInfo.IsOSX)
return _current = new OsxVelopackLocator(processImpl, logger); return new OsxVelopackLocator(processImpl, logger);
if (VelopackRuntimeInfo.IsLinux) if (VelopackRuntimeInfo.IsLinux)
return _current = new LinuxVelopackLocator(processImpl, logger); return new LinuxVelopackLocator(processImpl, logger);
throw new PlatformNotSupportedException($"OS platform '{VelopackRuntimeInfo.SystemOs.GetOsLongName()}' is not supported."); throw new PlatformNotSupportedException($"OS platform '{VelopackRuntimeInfo.SystemOs.GetOsLongName()}' is not supported.");
} }
@@ -87,7 +88,7 @@ namespace Velopack.Locators
public abstract string? Channel { get; } public abstract string? Channel { get; }
/// <inheritdoc/> /// <inheritdoc/>
public abstract IVelopackLogger Log { get; } public virtual IVelopackLogger Log => ((IVelopackLogger?) CombinedLogger) ?? new NullVelopackLogger();
/// <inheritdoc/> /// <inheritdoc/>
public virtual bool IsPortable => false; public virtual bool IsPortable => false;
@@ -111,6 +112,14 @@ namespace Velopack.Locators
/// <inheritdoc/> /// <inheritdoc/>
public abstract SemanticVersion? CurrentlyInstalledVersion { get; } public abstract SemanticVersion? CurrentlyInstalledVersion { get; }
internal CombinedVelopackLogger? CombinedLogger { get; set; }
/// <inheritdoc/>
public void AddLogger(IVelopackLogger logger)
{
CombinedLogger?.Add(logger);
}
/// <inheritdoc/> /// <inheritdoc/>
public virtual List<VelopackAsset> GetLocalPackages() public virtual List<VelopackAsset> GetLocalPackages()
{ {

View File

@@ -37,9 +37,6 @@ namespace Velopack.Locators
/// <inheritdoc /> /// <inheritdoc />
public override string? PackagesDir => _packagesDir.Value; public override string? PackagesDir => _packagesDir.Value;
/// <inheritdoc />
public override IVelopackLogger Log { get; }
/// <inheritdoc /> /// <inheritdoc />
public override bool IsPortable => RootAppDir != null && File.Exists(Path.Combine(RootAppDir, ".portable")); public override bool IsPortable => RootAppDir != null && File.Exists(Path.Combine(RootAppDir, ".portable"));
@@ -56,16 +53,13 @@ namespace Velopack.Locators
throw new NotSupportedException($"Cannot instantiate {nameof(WindowsVelopackLocator)} on a non-Windows system."); throw new NotSupportedException($"Cannot instantiate {nameof(WindowsVelopackLocator)} on a non-Windows system.");
_packagesDir = new(GetPackagesDir); _packagesDir = new(GetPackagesDir);
CombinedLogger = new CombinedVelopackLogger(customLog);
var combinedLog = new CombinedVelopackLogger(); Process = processImpl ??= new DefaultProcessImpl(CombinedLogger);
combinedLog.Add(customLog);
Log = combinedLog;
Process = processImpl ??= new DefaultProcessImpl(combinedLog);
var ourPath = processImpl.GetCurrentProcessPath(); var ourPath = processImpl.GetCurrentProcessPath();
var currentProcessId = processImpl.GetCurrentProcessId(); var currentProcessId = processImpl.GetCurrentProcessId();
using var initLog = new CachedVelopackLogger(combinedLog); using var initLog = new CachedVelopackLogger(CombinedLogger);
initLog.Info($"Initializing {nameof(WindowsVelopackLocator)}"); initLog.Info($"Initializing {nameof(WindowsVelopackLocator)}");
// We try various approaches here. Firstly, if Update.exe is in the parent directory, // We try various approaches here. Firstly, if Update.exe is in the parent directory,
@@ -133,6 +127,7 @@ namespace Velopack.Locators
Directory.CreateDirectory(TempAppRootDirectory); Directory.CreateDirectory(TempAppRootDirectory);
File.Copy(UpdateExePath, tempTargetUpdateExe); File.Copy(UpdateExePath, tempTargetUpdateExe);
} }
UpdateExePath = tempTargetUpdateExe; UpdateExePath = tempTargetUpdateExe;
} }
@@ -142,7 +137,7 @@ namespace Velopack.Locators
try { try {
var logFilePath = Path.Combine(RootAppDir, DefaultLoggingFileName); var logFilePath = Path.Combine(RootAppDir, DefaultLoggingFileName);
var fileLog = new FileVelopackLogger(logFilePath, currentProcessId); var fileLog = new FileVelopackLogger(logFilePath, currentProcessId);
combinedLog.Add(fileLog); CombinedLogger.Add(fileLog);
//fileLogCreated = true; //fileLogCreated = true;
} catch (Exception ex) { } catch (Exception ex) {
fileLogException = ex; fileLogException = ex;
@@ -156,7 +151,7 @@ namespace Velopack.Locators
var logFileName = String.IsNullOrEmpty(AppId) ? DefaultLoggingFileName : $"velopack_{AppId}.log"; var logFileName = String.IsNullOrEmpty(AppId) ? DefaultLoggingFileName : $"velopack_{AppId}.log";
var logFilePath = Path.Combine(Path.GetTempPath(), logFileName); var logFilePath = Path.Combine(Path.GetTempPath(), logFileName);
var fileLog = new FileVelopackLogger(logFilePath, currentProcessId); var fileLog = new FileVelopackLogger(logFilePath, currentProcessId);
combinedLog.Add(fileLog); CombinedLogger.Add(fileLog);
} catch (Exception ex) { } catch (Exception ex) {
tempFileLogException = ex; tempFileLogException = ex;
} }

View File

@@ -8,6 +8,15 @@ namespace Velopack.Logging
{ {
private readonly List<IVelopackLogger> _loggers = new(); private readonly List<IVelopackLogger> _loggers = new();
public CombinedVelopackLogger(params IVelopackLogger?[] loggers)
{
foreach (var logger in loggers) {
if (logger != null) {
_loggers.Add(logger);
}
}
}
public void Log(VelopackLogLevel logLevel, string? message, Exception? exception) public void Log(VelopackLogLevel logLevel, string? message, Exception? exception)
{ {
foreach (var logger in _loggers) { foreach (var logger in _loggers) {

View File

@@ -4,7 +4,7 @@ using Velopack;
using Velopack.Locators; using Velopack.Locators;
using Velopack.Logging; using Velopack.Logging;
var locator = VelopackLocator.CreateDefaultForPlatform(new ConsoleVelopackLogger()); var locator = VelopackLocator.CreateDefaultForPlatform(logger: new ConsoleVelopackLogger());
try { try {
bool shouldExit = false; bool shouldExit = false;