mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Remove Msft.Logging from C# lib
This commit is contained in:
@@ -4,20 +4,20 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.Exceptions;
|
||||
using Velopack.Logging;
|
||||
using Velopack.Util;
|
||||
|
||||
namespace Velopack.Compression
|
||||
{
|
||||
internal abstract class DeltaPackage
|
||||
{
|
||||
protected readonly ILogger Log;
|
||||
protected readonly IVelopackLogger Log;
|
||||
protected readonly string BaseTempDir;
|
||||
|
||||
private static Regex DIFF_SUFFIX = new Regex(@"\.(bs|zs)?diff$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
public DeltaPackage(ILogger logger, string baseTmpDir)
|
||||
public DeltaPackage(IVelopackLogger logger, string baseTmpDir)
|
||||
{
|
||||
Log = logger;
|
||||
BaseTempDir = baseTmpDir;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.Logging;
|
||||
using Velopack.Util;
|
||||
|
||||
namespace Velopack.Compression
|
||||
@@ -9,7 +9,7 @@ namespace Velopack.Compression
|
||||
{
|
||||
private readonly string _updateExePath;
|
||||
|
||||
public DeltaUpdateExe(ILogger logger, string baseTmpDir, string updateExePath) : base(logger, baseTmpDir)
|
||||
public DeltaUpdateExe(IVelopackLogger logger, string baseTmpDir, string updateExePath) : base(logger, baseTmpDir)
|
||||
{
|
||||
_updateExePath = updateExePath;
|
||||
}
|
||||
@@ -19,11 +19,12 @@ namespace Velopack.Compression
|
||||
var psi = new ProcessStartInfo(_updateExePath);
|
||||
psi.AppendArgumentListSafe(new string[] { "patch", "--old", baseFile, "--patch", patchFile, "--output", outputFile }, out var _);
|
||||
psi.CreateNoWindow = true;
|
||||
var p = psi.StartRedirectOutputToILogger(Log, LogLevel.Debug);
|
||||
var p = psi.StartRedirectOutputToILogger(Log, VelopackLogLevel.Debug);
|
||||
if (!p.WaitForExit(30_000)) {
|
||||
p.Kill();
|
||||
throw new TimeoutException("zstd patch process timed out (30s).");
|
||||
}
|
||||
|
||||
if (p.ExitCode != 0) {
|
||||
throw new Exception($"zstd patch process failed with exit code {p.ExitCode}.");
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.Logging;
|
||||
using Velopack.Util;
|
||||
|
||||
namespace Velopack.Compression
|
||||
@@ -15,7 +15,7 @@ namespace Velopack.Compression
|
||||
{
|
||||
private const string SYMLINK_EXT = ".__symlink";
|
||||
|
||||
public static void ExtractZipToDirectory(ILogger logger, string inputFile, string outputDirectory, bool expandSymlinks = false)
|
||||
public static void ExtractZipToDirectory(IVelopackLogger logger, string inputFile, string outputDirectory, bool expandSymlinks = false)
|
||||
{
|
||||
logger.Debug($"Extracting '{inputFile}' to '{outputDirectory}' using System.IO.Compression...");
|
||||
IoUtil.DeleteFileOrDirectoryHard(outputDirectory);
|
||||
@@ -85,7 +85,7 @@ namespace Velopack.Compression
|
||||
|
||||
internal static string SanitizeEntryFilePath(string entryPath) => entryPath.Replace('\0', '_');
|
||||
|
||||
public static async Task CreateZipFromDirectoryAsync(ILogger logger, string outputFile, string directoryToCompress, Action<int>? progress = null,
|
||||
public static async Task CreateZipFromDirectoryAsync(IVelopackLogger logger, string outputFile, string directoryToCompress, Action<int>? progress = null,
|
||||
CompressionLevel compressionLevel = CompressionLevel.Optimal, CancellationToken cancelToken = default)
|
||||
{
|
||||
progress ??= (x => { });
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NuGet.Versioning;
|
||||
using Velopack.Logging;
|
||||
|
||||
namespace Velopack.Locators
|
||||
{
|
||||
@@ -38,7 +39,10 @@ namespace Velopack.Locators
|
||||
|
||||
/// <summary> The release channel this package was built for. </summary>
|
||||
public string? Channel { get; }
|
||||
|
||||
|
||||
/// <summary> The logging interface to use for Velopack diagnostic messages. </summary>
|
||||
public IVelopackLogger Log { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A flag indicating if this is a portable build, and that the settings should be self-contained in the package.
|
||||
/// On Windows, this is true for portable builds, and false for non-portable builds which were installed by Setup.exe
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.Versioning;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NuGet.Versioning;
|
||||
using Velopack.Logging;
|
||||
using Velopack.NuGet;
|
||||
using Velopack.Util;
|
||||
|
||||
@@ -33,6 +33,9 @@ namespace Velopack.Locators
|
||||
/// <inheritdoc />
|
||||
public override string? Channel { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IVelopackLogger Log { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string? AppTempDir => CreateSubDirIfDoesNotExist(TempUtil.GetDefaultTempBaseDirectory(), AppId);
|
||||
|
||||
@@ -58,8 +61,7 @@ namespace Velopack.Locators
|
||||
/// Creates a new <see cref="OsxVelopackLocator"/> and auto-detects the
|
||||
/// app information from metadata embedded in the .app.
|
||||
/// </summary>
|
||||
public LinuxVelopackLocator(string currentProcessPath, uint currentProcessId, ILogger logger)
|
||||
: base(logger)
|
||||
public LinuxVelopackLocator(string currentProcessPath, uint currentProcessId, IVelopackLogger? logger)
|
||||
{
|
||||
if (!VelopackRuntimeInfo.IsLinux)
|
||||
throw new NotSupportedException("Cannot instantiate LinuxVelopackLocator on a non-linux system.");
|
||||
@@ -67,12 +69,16 @@ namespace Velopack.Locators
|
||||
ProcessId = currentProcessId;
|
||||
var ourPath = ProcessExePath = currentProcessPath;
|
||||
|
||||
Log.Info($"Initialising {nameof(LinuxVelopackLocator)}");
|
||||
logger ??= new FileVelopackLogger("/tmp/velopack.log", currentProcessId);
|
||||
logger.Info($"Initialising {nameof(LinuxVelopackLocator)}");
|
||||
Log = logger;
|
||||
|
||||
// are we inside a mounted .AppImage?
|
||||
var ix = ourPath.IndexOf("/usr/bin/", StringComparison.InvariantCultureIgnoreCase);
|
||||
if (ix <= 0) {
|
||||
Log.Warn($"Unable to locate .AppImage root from '{ourPath}'. This warning indicates that the application is not running from a mounted .AppImage, for example during development.");
|
||||
logger.Warn(
|
||||
$"Unable to locate .AppImage root from '{ourPath}'. " +
|
||||
$"This warning indicates that the application is not running from a mounted .AppImage, for example during development.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -83,7 +89,7 @@ namespace Velopack.Locators
|
||||
|
||||
if (!String.IsNullOrEmpty(AppImagePath) && File.Exists(AppImagePath)) {
|
||||
if (File.Exists(updateExe) && PackageManifest.TryParseFromFile(metadataPath, out var manifest)) {
|
||||
Log.Info("Located valid manifest file at: " + metadataPath);
|
||||
logger.Info("Located valid manifest file at: " + metadataPath);
|
||||
AppId = manifest.Id;
|
||||
RootAppDir = rootDir;
|
||||
AppContentDir = contentsDir;
|
||||
@@ -98,4 +104,4 @@ namespace Velopack.Locators
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.Versioning;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NuGet.Versioning;
|
||||
using Velopack.Logging;
|
||||
using Velopack.NuGet;
|
||||
using Velopack.Util;
|
||||
|
||||
@@ -36,6 +36,9 @@ namespace Velopack.Locators
|
||||
/// <inheritdoc />
|
||||
public override string? PackagesDir => CreateSubDirIfDoesNotExist(CachesAppDir, "packages");
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IVelopackLogger Log { get; }
|
||||
|
||||
private string? CachesAppDir => CreateSubDirIfDoesNotExist(CachesVelopackDir, AppId);
|
||||
private string? CachesVelopackDir => CreateSubDirIfDoesNotExist(CachesDir, "velopack");
|
||||
private string? CachesDir => CreateSubDirIfDoesNotExist(LibraryDir, "Caches");
|
||||
@@ -55,8 +58,7 @@ namespace Velopack.Locators
|
||||
/// Creates a new <see cref="OsxVelopackLocator"/> and auto-detects the
|
||||
/// app information from metadata embedded in the .app.
|
||||
/// </summary>
|
||||
public OsxVelopackLocator(string currentProcessPath, uint currentProcessId, ILogger logger)
|
||||
: base(logger)
|
||||
public OsxVelopackLocator(string currentProcessPath, uint currentProcessId, IVelopackLogger? logger)
|
||||
{
|
||||
if (!VelopackRuntimeInfo.IsOSX)
|
||||
throw new NotSupportedException("Cannot instantiate OsxLocator on a non-osx system.");
|
||||
@@ -64,12 +66,16 @@ namespace Velopack.Locators
|
||||
ProcessId = currentProcessId;
|
||||
var ourPath = ProcessExePath = currentProcessPath;
|
||||
|
||||
Log.Info($"Initialising {nameof(OsxVelopackLocator)}");
|
||||
var userLogDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Library", "Logs");
|
||||
var logPath = Directory.Exists(userLogDir) ? Path.Combine(userLogDir, "velopack.log") : "/tmp/velopack.log";
|
||||
logger ??= new FileVelopackLogger(logPath, currentProcessId);
|
||||
logger.Info($"Initialising {nameof(OsxVelopackLocator)}");
|
||||
Log = logger;
|
||||
|
||||
// are we inside a .app?
|
||||
var ix = ourPath.IndexOf(".app/", StringComparison.InvariantCultureIgnoreCase);
|
||||
if (ix <= 0) {
|
||||
Log.Warn($"Unable to locate .app root from '{ourPath}'");
|
||||
logger.Warn($"Unable to locate .app root from '{ourPath}'");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -80,7 +86,7 @@ namespace Velopack.Locators
|
||||
var metadataPath = Path.Combine(macosDir, CoreUtil.SpecVersionFileName);
|
||||
|
||||
if (File.Exists(updateExe) && PackageManifest.TryParseFromFile(metadataPath, out var manifest)) {
|
||||
Log.Info("Located valid manifest file at: " + metadataPath);
|
||||
logger.Info("Located valid manifest file at: " + metadataPath);
|
||||
AppId = manifest.Id;
|
||||
RootAppDir = appPath;
|
||||
UpdateExePath = updateExe;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NuGet.Versioning;
|
||||
using Velopack.Logging;
|
||||
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
namespace Velopack.Locators
|
||||
@@ -19,6 +20,7 @@ namespace Velopack.Locators
|
||||
if (_id == null) {
|
||||
throw new NotSupportedException("AppId is not supported in this test implementation.");
|
||||
}
|
||||
|
||||
return _id;
|
||||
}
|
||||
}
|
||||
@@ -28,6 +30,7 @@ namespace Velopack.Locators
|
||||
if (_root == null) {
|
||||
throw new NotSupportedException("RootAppDir is not supported in this test implementation.");
|
||||
}
|
||||
|
||||
return _root;
|
||||
}
|
||||
}
|
||||
@@ -37,6 +40,7 @@ namespace Velopack.Locators
|
||||
if (_packages == null) {
|
||||
throw new NotSupportedException("PackagesDir is not supported in this test implementation.");
|
||||
}
|
||||
|
||||
return _packages;
|
||||
}
|
||||
}
|
||||
@@ -46,6 +50,7 @@ namespace Velopack.Locators
|
||||
if (_updatePath == null) {
|
||||
throw new NotSupportedException("UpdateExePath is not supported in this test implementation.");
|
||||
}
|
||||
|
||||
return _updatePath;
|
||||
}
|
||||
}
|
||||
@@ -55,6 +60,7 @@ namespace Velopack.Locators
|
||||
if (_version == null) {
|
||||
throw new NotSupportedException("CurrentlyInstalledVersion is not supported in this test implementation.");
|
||||
}
|
||||
|
||||
return _version;
|
||||
}
|
||||
}
|
||||
@@ -64,6 +70,7 @@ namespace Velopack.Locators
|
||||
if (_appContent == null) {
|
||||
throw new NotSupportedException("AppContentDir is not supported in this test implementation.");
|
||||
}
|
||||
|
||||
return _appContent;
|
||||
}
|
||||
}
|
||||
@@ -74,11 +81,14 @@ namespace Velopack.Locators
|
||||
}
|
||||
}
|
||||
|
||||
public override IVelopackLogger Log { get; }
|
||||
|
||||
public override VelopackAsset? GetLatestLocalFullPackage()
|
||||
{
|
||||
if (_asset != null) {
|
||||
return _asset;
|
||||
}
|
||||
|
||||
return base.GetLatestLocalFullPackage();
|
||||
}
|
||||
|
||||
@@ -96,15 +106,14 @@ namespace Velopack.Locators
|
||||
private readonly VelopackAsset? _asset;
|
||||
|
||||
/// <inheritdoc cref="TestVelopackLocator" />
|
||||
public TestVelopackLocator(string appId, string version, string packagesDir, ILogger? logger = null)
|
||||
public TestVelopackLocator(string appId, string version, string packagesDir, IVelopackLogger? logger = null)
|
||||
: this(appId, version, packagesDir, null, null, null, null, logger)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="TestVelopackLocator" />
|
||||
public TestVelopackLocator(string appId, string version, string packagesDir, string? appDir,
|
||||
string? rootDir, string? updateExe, string? channel = null, ILogger? logger = null, VelopackAsset? localPackage = null, string processPath = null!)
|
||||
: base(logger)
|
||||
string? rootDir, string? updateExe, string? channel = null, IVelopackLogger? logger = null, VelopackAsset? localPackage = null, string processPath = null!)
|
||||
{
|
||||
_id = appId;
|
||||
_packages = packagesDir;
|
||||
@@ -115,6 +124,7 @@ namespace Velopack.Locators
|
||||
_channel = channel;
|
||||
_asset = localPackage;
|
||||
ProcessExePath = processPath;
|
||||
Log = logger ?? new NullVelopackLogger();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,11 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using NuGet.Versioning;
|
||||
using Velopack.Util;
|
||||
using Velopack.Logging;
|
||||
|
||||
namespace Velopack.Locators
|
||||
{
|
||||
@@ -16,34 +14,57 @@ namespace Velopack.Locators
|
||||
/// </summary>
|
||||
public abstract class VelopackLocator : IVelopackLocator
|
||||
{
|
||||
private static VelopackLocator? _current;
|
||||
private static IVelopackLocator? _current;
|
||||
|
||||
/// <summary>
|
||||
/// Auto-detect the platform from the current operating system.
|
||||
/// Check if a VelopackLocator has been set for the current process.
|
||||
/// </summary>
|
||||
public static VelopackLocator GetDefault(ILogger? logger)
|
||||
{
|
||||
var log = logger ?? NullLogger.Instance;
|
||||
public static bool IsCurrentSet => _current != null;
|
||||
|
||||
if (_current != null)
|
||||
/// <summary>
|
||||
/// Get the current locator in use, this process-wide locator can be set/overriden during VelopackApp.Build().
|
||||
/// Alternatively, most methods which use locators also accept an IVelopackLocator as a parameter.
|
||||
/// </summary>
|
||||
public static IVelopackLocator Current {
|
||||
get {
|
||||
if (_current == null)
|
||||
throw new InvalidOperationException(
|
||||
"No VelopackLocator has been set. Either call VelopackApp.Build() or provide IVelopackLocator as a method parameter.");
|
||||
return _current;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Create a new default locator based on the current operating system. </summary>
|
||||
public static IVelopackLocator CreateDefaultForPlatform(IVelopackLogger? logger = null)
|
||||
{
|
||||
var process = Process.GetCurrentProcess();
|
||||
var processExePath = process.MainModule?.FileName ?? throw new InvalidOperationException("Could not determine process path.");
|
||||
var processId = (uint)process.Id;
|
||||
var processExePath = process.MainModule?.FileName
|
||||
?? throw new InvalidOperationException("Could not determine process path, please construct IVelopackLocator manually.");
|
||||
var processId = (uint) process.Id;
|
||||
|
||||
if (VelopackRuntimeInfo.IsWindows)
|
||||
return _current = new WindowsVelopackLocator(processExePath, processId, log);
|
||||
return _current = new WindowsVelopackLocator(processExePath, processId, logger);
|
||||
|
||||
if (VelopackRuntimeInfo.IsOSX)
|
||||
return _current = new OsxVelopackLocator(processExePath, processId, log);
|
||||
return _current = new OsxVelopackLocator(processExePath, processId, logger);
|
||||
|
||||
if (VelopackRuntimeInfo.IsLinux)
|
||||
return _current = new LinuxVelopackLocator(processExePath, processId, log);
|
||||
return _current = new LinuxVelopackLocator(processExePath, processId, logger);
|
||||
|
||||
throw new PlatformNotSupportedException($"OS platform '{VelopackRuntimeInfo.SystemOs.GetOsLongName()}' is not supported.");
|
||||
}
|
||||
|
||||
internal static void SetCurrentLocator(IVelopackLocator locator)
|
||||
{
|
||||
_current = locator;
|
||||
}
|
||||
|
||||
internal static IVelopackLocator GetCurrentOrCreateDefault(IVelopackLogger? logger = null)
|
||||
{
|
||||
_current ??= CreateDefaultForPlatform(logger);
|
||||
return _current;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract string? AppId { get; }
|
||||
|
||||
@@ -65,12 +86,15 @@ namespace Velopack.Locators
|
||||
/// <inheritdoc/>
|
||||
public abstract string? Channel { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract IVelopackLogger Log { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract uint ProcessId { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public abstract string ProcessExePath { get; }
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual bool IsPortable => false;
|
||||
|
||||
@@ -90,15 +114,6 @@ namespace Velopack.Locators
|
||||
/// <inheritdoc/>
|
||||
public abstract SemanticVersion? CurrentlyInstalledVersion { get; }
|
||||
|
||||
/// <summary> The log interface to use for diagnostic messages. </summary>
|
||||
protected ILogger Log { get; }
|
||||
|
||||
/// <inheritdoc cref="VelopackLocator"/>
|
||||
protected VelopackLocator(ILogger? logger)
|
||||
{
|
||||
Log = logger ?? NullLogger.Instance;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual List<VelopackAsset> GetLocalPackages()
|
||||
{
|
||||
@@ -119,6 +134,7 @@ namespace Velopack.Locators
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
} catch (Exception ex) {
|
||||
Log.Error(ex, "Error while reading local packages.");
|
||||
@@ -131,8 +147,7 @@ namespace Velopack.Locators
|
||||
{
|
||||
return GetLocalPackages()
|
||||
.OrderByDescending(x => x.Version)
|
||||
.Where(a => a.Type == VelopackAssetType.Full)
|
||||
.FirstOrDefault();
|
||||
.FirstOrDefault(a => a.Type == VelopackAssetType.Full);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -161,6 +176,7 @@ namespace Velopack.Locators
|
||||
if (!Guid.TryParse(File.ReadAllText(stagedUserIdFile, Encoding.UTF8), out ret)) {
|
||||
throw new Exception("File was read but contents were invalid");
|
||||
}
|
||||
|
||||
Log.Info($"Loaded existing staging userId: {ret}");
|
||||
return ret;
|
||||
} catch (Exception ex) {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.Versioning;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NuGet.Versioning;
|
||||
using Velopack.Logging;
|
||||
using Velopack.NuGet;
|
||||
using Velopack.Util;
|
||||
|
||||
@@ -32,6 +33,9 @@ namespace Velopack.Locators
|
||||
/// <inheritdoc />
|
||||
public override string? PackagesDir => CreateSubDirIfDoesNotExist(RootAppDir, "packages");
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IVelopackLogger Log { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsPortable => RootAppDir != null && File.Exists(Path.Combine(RootAppDir, ".portable"));
|
||||
|
||||
@@ -40,13 +44,12 @@ namespace Velopack.Locators
|
||||
|
||||
/// <inheritdoc />
|
||||
public override uint ProcessId { get; }
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ProcessExePath { get; }
|
||||
|
||||
/// <inheritdoc cref="WindowsVelopackLocator" />
|
||||
public WindowsVelopackLocator(string currentProcessPath, uint currentProcessId, ILogger logger)
|
||||
: base(logger)
|
||||
public WindowsVelopackLocator(string currentProcessPath, uint currentProcessId, IVelopackLogger? logger)
|
||||
{
|
||||
if (!VelopackRuntimeInfo.IsWindows)
|
||||
throw new NotSupportedException("Cannot instantiate WindowsLocator on a non-Windows system.");
|
||||
@@ -66,29 +69,31 @@ namespace Velopack.Locators
|
||||
var possibleUpdateExe = Path.GetFullPath(Path.Combine(myDirPath, "..", "Update.exe"));
|
||||
var ixCurrent = ourPath.LastIndexOf("/current/", StringComparison.InvariantCultureIgnoreCase);
|
||||
|
||||
Log.Info($"Initializing {nameof(WindowsVelopackLocator)}");
|
||||
|
||||
if (File.Exists(possibleUpdateExe)) {
|
||||
Log.Info("Update.exe found in parent directory");
|
||||
// we're running in a directory with an Update.exe in the parent directory
|
||||
var manifestFile = Path.Combine(myDirPath, CoreUtil.SpecVersionFileName);
|
||||
var rootDir = Path.GetDirectoryName(possibleUpdateExe)!;
|
||||
logger ??= new FileVelopackLogger(Path.Combine(rootDir, "velopack.log"), currentProcessId);
|
||||
Log = logger;
|
||||
if (PackageManifest.TryParseFromFile(manifestFile, out var manifest)) {
|
||||
// ideal, the info we need is in a manifest file.
|
||||
Log.Info("Located valid manifest file at: " + manifestFile);
|
||||
logger.Info($"{nameof(WindowsVelopackLocator)}: Update.exe in parent dir, Located valid manifest file at: " + manifestFile);
|
||||
AppId = manifest.Id;
|
||||
CurrentlyInstalledVersion = manifest.Version;
|
||||
RootAppDir = Path.GetDirectoryName(possibleUpdateExe);
|
||||
RootAppDir = rootDir;
|
||||
UpdateExePath = possibleUpdateExe;
|
||||
AppContentDir = myDirPath;
|
||||
Channel = manifest.Channel;
|
||||
} else if (PathUtil.PathPartStartsWith(myDirName, "app-") && NuGetVersion.TryParse(myDirName.Substring(4), out var version)) {
|
||||
// this is a legacy case, where we're running in an 'root/app-*/' directory, and there is no manifest.
|
||||
Log.Warn("Legacy app-* directory detected, sq.version not found. Using directory name for AppId and Version.");
|
||||
logger.Warn("Update.exe in parent dir, Legacy app-* directory detected, sq.version not found. Using directory name for AppId and Version.");
|
||||
AppId = Path.GetFileName(Path.GetDirectoryName(possibleUpdateExe));
|
||||
CurrentlyInstalledVersion = version;
|
||||
RootAppDir = Path.GetDirectoryName(possibleUpdateExe);
|
||||
RootAppDir = rootDir;
|
||||
UpdateExePath = possibleUpdateExe;
|
||||
AppContentDir = myDirPath;
|
||||
} else {
|
||||
logger.Error("Update.exe in parent dir, but unable to locate a valid manifest file at: " + manifestFile);
|
||||
}
|
||||
} else if (ixCurrent > 0) {
|
||||
// this is an attempt to handle the case where we are running in a nested current directory.
|
||||
@@ -98,8 +103,10 @@ namespace Velopack.Locators
|
||||
possibleUpdateExe = Path.GetFullPath(Path.Combine(rootDir, "Update.exe"));
|
||||
// we only support parsing a manifest when we're in a nested current directory. no legacy fallback.
|
||||
if (File.Exists(possibleUpdateExe) && PackageManifest.TryParseFromFile(manifestFile, out var manifest)) {
|
||||
Log.Warn("Running in deeply nested directory. This is not an advised use-case.");
|
||||
Log.Info("Located valid manifest file at: " + manifestFile);
|
||||
logger ??= new FileVelopackLogger(Path.Combine(rootDir, "velopack.log"), currentProcessId);
|
||||
Log = logger;
|
||||
logger.Warn("Running in deeply nested directory. This is not an advised use-case.");
|
||||
logger.Info("Located valid manifest file at: " + manifestFile);
|
||||
RootAppDir = Path.GetDirectoryName(possibleUpdateExe);
|
||||
UpdateExePath = possibleUpdateExe;
|
||||
AppId = manifest.Id;
|
||||
@@ -108,6 +115,15 @@ namespace Velopack.Locators
|
||||
Channel = manifest.Channel;
|
||||
}
|
||||
}
|
||||
|
||||
if (Log == null) {
|
||||
try {
|
||||
Log = new FileVelopackLogger(Path.Combine(AppContext.BaseDirectory, "velopack.log"), currentProcessId);
|
||||
} catch (Exception ex) {
|
||||
Debug.WriteLine("Error creating Velopack logger: " + ex);
|
||||
Log = new NullVelopackLogger();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
18
src/lib-csharp/Logging/ConsoleVelopackLogger.cs
Normal file
18
src/lib-csharp/Logging/ConsoleVelopackLogger.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
using System;
|
||||
|
||||
namespace Velopack.Logging
|
||||
{
|
||||
public class ConsoleVelopackLogger : IVelopackLogger
|
||||
{
|
||||
public void Log(VelopackLogLevel logLevel, string? message, Exception? exception)
|
||||
{
|
||||
var logMessage = $"[{DateTime.Now.ToShortTimeString()}] [{logLevel}] {message}";
|
||||
if (exception != null) {
|
||||
logMessage += Environment.NewLine + exception;
|
||||
}
|
||||
|
||||
Console.WriteLine(logMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
51
src/lib-csharp/Logging/FileVelopackLogger.cs
Normal file
51
src/lib-csharp/Logging/FileVelopackLogger.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace Velopack.Logging
|
||||
{
|
||||
public class FileVelopackLogger : IVelopackLogger, IDisposable
|
||||
{
|
||||
public uint ProcessId { get; }
|
||||
private readonly object _lock = new();
|
||||
private readonly StreamWriter _writer;
|
||||
private readonly FileStream _fileStream;
|
||||
|
||||
public FileVelopackLogger(string filePath, uint processId)
|
||||
{
|
||||
ProcessId = processId;
|
||||
_fileStream = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
|
||||
_writer = new StreamWriter(_fileStream);
|
||||
}
|
||||
|
||||
public void Log(VelopackLogLevel logLevel, string? message, Exception? exception)
|
||||
{
|
||||
try {
|
||||
lock (_lock) {
|
||||
var logMessage = $"[lib-csharp:{ProcessId}] [{DateTime.Now.ToShortTimeString()}] [{logLevel}] {message}";
|
||||
if (exception != null) {
|
||||
logMessage += Environment.NewLine + exception;
|
||||
}
|
||||
|
||||
_writer.WriteLine(logMessage);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Debug.WriteLine($"Error writing to log file: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
try {
|
||||
lock (_lock) {
|
||||
_writer.Flush();
|
||||
_writer.Dispose();
|
||||
_fileStream.Dispose();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Debug.WriteLine($"Error disposing log file: {ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
src/lib-csharp/Logging/IVelopackLogger.cs
Normal file
11
src/lib-csharp/Logging/IVelopackLogger.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
using System;
|
||||
|
||||
namespace Velopack.Logging
|
||||
{
|
||||
public interface IVelopackLogger
|
||||
{
|
||||
void Log(VelopackLogLevel logLevel, string? message, Exception? exception);
|
||||
}
|
||||
}
|
||||
166
src/lib-csharp/Logging/LoggingExtensions.cs
Normal file
166
src/lib-csharp/Logging/LoggingExtensions.cs
Normal file
@@ -0,0 +1,166 @@
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Velopack.Logging
|
||||
{
|
||||
[ExcludeFromCodeCoverage]
|
||||
public static class LoggerExtensions
|
||||
{
|
||||
public static void Log(this IVelopackLogger logger, VelopackLogLevel logLevel, string message)
|
||||
{
|
||||
logger.Log(logLevel, message, null);
|
||||
}
|
||||
|
||||
public static void LogTrace(this IVelopackLogger logger, string message)
|
||||
{
|
||||
logger.Log(VelopackLogLevel.Trace, message, null);
|
||||
}
|
||||
|
||||
public static void LogTrace(this IVelopackLogger logger, Exception ex, string message)
|
||||
{
|
||||
logger.Log(VelopackLogLevel.Trace, message, ex);
|
||||
}
|
||||
|
||||
public static void LogDebug(this IVelopackLogger logger, string message)
|
||||
{
|
||||
logger.Log(VelopackLogLevel.Debug, message, null);
|
||||
}
|
||||
|
||||
public static void LogDebug(this IVelopackLogger logger, Exception ex, string message)
|
||||
{
|
||||
logger.Log(VelopackLogLevel.Debug, message, ex);
|
||||
}
|
||||
|
||||
public static void LogInformation(this IVelopackLogger logger, string message)
|
||||
{
|
||||
logger.Log(VelopackLogLevel.Information, message, null);
|
||||
}
|
||||
|
||||
public static void LogInformation(this IVelopackLogger logger, Exception ex, string message)
|
||||
{
|
||||
logger.Log(VelopackLogLevel.Information, message, ex);
|
||||
}
|
||||
|
||||
public static void LogWarning(this IVelopackLogger logger, string message)
|
||||
{
|
||||
logger.Log(VelopackLogLevel.Warning, message, null);
|
||||
}
|
||||
|
||||
public static void LogWarning(this IVelopackLogger logger, Exception ex, string message)
|
||||
{
|
||||
logger.Log(VelopackLogLevel.Warning, message, ex);
|
||||
}
|
||||
|
||||
public static void LogError(this IVelopackLogger logger, string message)
|
||||
{
|
||||
logger.Log(VelopackLogLevel.Error, message, null);
|
||||
}
|
||||
|
||||
public static void LogError(this IVelopackLogger logger, Exception ex, string message)
|
||||
{
|
||||
logger.Log(VelopackLogLevel.Error, message, ex);
|
||||
}
|
||||
|
||||
public static void LogCritical(this IVelopackLogger logger, string message)
|
||||
{
|
||||
logger.Log(VelopackLogLevel.Critical, message, null);
|
||||
}
|
||||
|
||||
public static void LogCritical(this IVelopackLogger logger, Exception ex, string message)
|
||||
{
|
||||
logger.Log(VelopackLogLevel.Critical, message, ex);
|
||||
}
|
||||
|
||||
public static void Trace(this IVelopackLogger logger, string message)
|
||||
{
|
||||
logger.LogTrace(message);
|
||||
}
|
||||
|
||||
public static void Trace(this IVelopackLogger logger, Exception ex, string message)
|
||||
{
|
||||
logger.LogTrace(ex, message);
|
||||
}
|
||||
|
||||
public static void Trace(this IVelopackLogger logger, Exception ex)
|
||||
{
|
||||
logger.LogTrace(ex, ex.Message);
|
||||
}
|
||||
|
||||
public static void Debug(this IVelopackLogger logger, string message)
|
||||
{
|
||||
logger.LogDebug(message);
|
||||
}
|
||||
|
||||
public static void Debug(this IVelopackLogger logger, Exception ex, string message)
|
||||
{
|
||||
logger.LogDebug(ex, message);
|
||||
}
|
||||
|
||||
public static void Debug(this IVelopackLogger logger, Exception ex)
|
||||
{
|
||||
logger.LogDebug(ex, ex.Message);
|
||||
}
|
||||
|
||||
public static void Info(this IVelopackLogger logger, string message)
|
||||
{
|
||||
logger.LogInformation(message);
|
||||
}
|
||||
|
||||
public static void Info(this IVelopackLogger logger, Exception ex, string message)
|
||||
{
|
||||
logger.LogInformation(ex, message);
|
||||
}
|
||||
|
||||
public static void Info(this IVelopackLogger logger, Exception ex)
|
||||
{
|
||||
logger.LogInformation(ex, ex.Message);
|
||||
}
|
||||
|
||||
public static void Warn(this IVelopackLogger logger, string message)
|
||||
{
|
||||
logger.LogWarning(message);
|
||||
}
|
||||
|
||||
public static void Warn(this IVelopackLogger logger, Exception ex, string message)
|
||||
{
|
||||
logger.LogWarning(ex, message);
|
||||
}
|
||||
|
||||
public static void Warn(this IVelopackLogger logger, Exception ex)
|
||||
{
|
||||
logger.LogWarning(ex, ex.Message);
|
||||
}
|
||||
|
||||
public static void Error(this IVelopackLogger logger, string message)
|
||||
{
|
||||
logger.LogError(message);
|
||||
}
|
||||
|
||||
public static void Error(this IVelopackLogger logger, Exception ex, string message)
|
||||
{
|
||||
logger.LogError(ex, message);
|
||||
}
|
||||
|
||||
public static void Error(this IVelopackLogger logger, Exception ex)
|
||||
{
|
||||
logger.LogError(ex, ex.Message);
|
||||
}
|
||||
|
||||
public static void Fatal(this IVelopackLogger logger, string message)
|
||||
{
|
||||
logger.LogCritical(message);
|
||||
}
|
||||
|
||||
public static void Fatal(this IVelopackLogger logger, Exception ex, string message)
|
||||
{
|
||||
logger.LogCritical(ex, message);
|
||||
}
|
||||
|
||||
public static void Fatal(this IVelopackLogger logger, Exception ex)
|
||||
{
|
||||
logger.LogCritical(ex, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
15
src/lib-csharp/Logging/NullVelopackLogger.cs
Normal file
15
src/lib-csharp/Logging/NullVelopackLogger.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
using System;
|
||||
|
||||
namespace Velopack.Logging
|
||||
{
|
||||
public class NullVelopackLogger : IVelopackLogger
|
||||
{
|
||||
public static readonly NullVelopackLogger Instance = new();
|
||||
|
||||
public void Log(VelopackLogLevel logLevel, string? message, Exception? exception)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/lib-csharp/Logging/VelopackLogLevel.cs
Normal file
14
src/lib-csharp/Logging/VelopackLogLevel.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
namespace Velopack.Logging
|
||||
{
|
||||
public enum VelopackLogLevel
|
||||
{
|
||||
Trace = 0,
|
||||
Debug = 1,
|
||||
Information = 2,
|
||||
Warning = 3,
|
||||
Error = 4,
|
||||
Critical = 5,
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.Logging;
|
||||
using Velopack.Util;
|
||||
|
||||
namespace Velopack.Sources
|
||||
@@ -49,7 +49,7 @@ namespace Velopack.Sources
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual Task DownloadReleaseEntry(ILogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken)
|
||||
public virtual Task DownloadReleaseEntry(IVelopackLogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken)
|
||||
{
|
||||
if (releaseEntry is GitBaseAsset githubEntry) {
|
||||
// this might be a browser url or an api url (depending on whether we have a AccessToken or not)
|
||||
@@ -62,7 +62,8 @@ namespace Velopack.Sources
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual async Task<VelopackAssetFeed> GetReleaseFeed(ILogger logger, string channel, Guid? stagingId = null, VelopackAsset? latestLocalRelease = null)
|
||||
public virtual async Task<VelopackAssetFeed> GetReleaseFeed(IVelopackLogger logger, string? appId, string channel, Guid? stagingId = null,
|
||||
VelopackAsset? latestLocalRelease = null)
|
||||
{
|
||||
var releases = await GetReleases(Prerelease).ConfigureAwait(false);
|
||||
if (releases == null || releases.Length == 0) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.Logging;
|
||||
|
||||
namespace Velopack.Sources
|
||||
{
|
||||
@@ -14,21 +14,22 @@ namespace Velopack.Sources
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieve the list of available remote releases from the package source. These releases
|
||||
/// can subsequently be downloaded with <see cref="DownloadReleaseEntry(ILogger, VelopackAsset, string, Action{int}, CancellationToken)"/>.
|
||||
/// can subsequently be downloaded with <see cref="DownloadReleaseEntry(IVelopackLogger, VelopackAsset, string, Action{int}, CancellationToken)"/>.
|
||||
/// </summary>
|
||||
/// <param name="channel">Release channel to filter packages by. Can be null, which is the
|
||||
/// default channel for this operating system.</param>
|
||||
/// <param name="stagingId">A persistent user-id, used for calculating whether a specific
|
||||
/// release should be available to this user or not. (eg, for the purposes of rolling out
|
||||
/// an update to only a small portion of users at a time).</param>
|
||||
/// <param name="latestLocalRelease">The latest / current local release. If specified,
|
||||
/// metadata from this package may be provided to the remote server (such as package id,
|
||||
/// or cpu architecture) to ensure that the correct package is downloaded for this user.
|
||||
/// </param>
|
||||
/// <param name="logger">The logger to use for any diagnostic messages.</param>
|
||||
/// <param name="appId"></param>
|
||||
/// <param name="channel">Release channel to filter packages by. Can be null, which is the
|
||||
/// default channel for this operating system.</param>
|
||||
/// <param name="stagingId">A persistent user-id, used for calculating whether a specific
|
||||
/// release should be available to this user or not. (eg, for the purposes of rolling out
|
||||
/// an update to only a small portion of users at a time).</param>
|
||||
/// <param name="latestLocalRelease">The latest / current local release. If specified,
|
||||
/// metadata from this package may be provided to the remote server (such as package id,
|
||||
/// or cpu architecture) to ensure that the correct package is downloaded for this user.
|
||||
/// </param>
|
||||
/// <returns>An array of <see cref="ReleaseEntry"/> objects that are available for download
|
||||
/// and are applicable to this user.</returns>
|
||||
Task<VelopackAssetFeed> GetReleaseFeed(ILogger logger, string channel, Guid? stagingId = null, VelopackAsset? latestLocalRelease = null);
|
||||
Task<VelopackAssetFeed> GetReleaseFeed(IVelopackLogger logger, string? appId, string channel, Guid? stagingId = null, VelopackAsset? latestLocalRelease = null);
|
||||
|
||||
/// <summary>
|
||||
/// Download the specified <see cref="VelopackAsset"/> to the provided local file path.
|
||||
@@ -40,6 +41,6 @@ namespace Velopack.Sources
|
||||
/// download is being processed.</param>
|
||||
/// <param name="logger">The logger to use for any diagnostic messages.</param>
|
||||
/// <param name="cancelToken">A token to use to cancel the request.</param>
|
||||
Task DownloadReleaseEntry(ILogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken = default);
|
||||
Task DownloadReleaseEntry(IVelopackLogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken = default);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.Logging;
|
||||
using Velopack.NuGet;
|
||||
using Velopack.Util;
|
||||
|
||||
@@ -25,7 +25,8 @@ namespace Velopack.Sources
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual Task<VelopackAssetFeed> GetReleaseFeed(ILogger logger, string channel, Guid? stagingId = null, VelopackAsset? latestLocalRelease = null)
|
||||
public virtual Task<VelopackAssetFeed> GetReleaseFeed(IVelopackLogger logger, string? appId, string channel, Guid? stagingId = null,
|
||||
VelopackAsset? latestLocalRelease = null)
|
||||
{
|
||||
if (!BaseDirectory.Exists) {
|
||||
logger.Error($"The local update directory '{BaseDirectory.FullName}' does not exist.");
|
||||
@@ -65,7 +66,7 @@ namespace Velopack.Sources
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual Task DownloadReleaseEntry(ILogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken)
|
||||
public virtual Task DownloadReleaseEntry(IVelopackLogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken)
|
||||
{
|
||||
var releasePath = Path.Combine(BaseDirectory.FullName, releaseEntry.FileName);
|
||||
if (!File.Exists(releasePath))
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.Logging;
|
||||
using Velopack.Util;
|
||||
|
||||
namespace Velopack.Sources
|
||||
@@ -37,7 +37,8 @@ namespace Velopack.Sources
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async virtual Task<VelopackAssetFeed> GetReleaseFeed(ILogger logger, string channel, Guid? stagingId = null, VelopackAsset? latestLocalRelease = null)
|
||||
public async virtual Task<VelopackAssetFeed> GetReleaseFeed(IVelopackLogger logger, string? appId, string channel, Guid? stagingId = null,
|
||||
VelopackAsset? latestLocalRelease = null)
|
||||
{
|
||||
var releaseFilename = CoreUtil.GetVeloReleaseIndexName(channel);
|
||||
var uri = HttpUtil.AppendPathToUri(BaseUri, releaseFilename);
|
||||
@@ -66,7 +67,7 @@ namespace Velopack.Sources
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async virtual Task DownloadReleaseEntry(ILogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken)
|
||||
public async virtual Task DownloadReleaseEntry(IVelopackLogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken)
|
||||
{
|
||||
if (releaseEntry == null) throw new ArgumentNullException(nameof(releaseEntry));
|
||||
if (localFile == null) throw new ArgumentNullException(nameof(localFile));
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.Util;
|
||||
using Velopack.Locators;
|
||||
using Velopack.Logging;
|
||||
|
||||
namespace Velopack.Sources
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves updates from the hosted Velopack service.
|
||||
/// </summary>
|
||||
public sealed class VelopackFlowUpdateSource : IUpdateSource
|
||||
public sealed class VelopackFlowSource : IUpdateSource
|
||||
{
|
||||
/// <inheritdoc cref="SimpleWebSource" />
|
||||
public VelopackFlowUpdateSource(
|
||||
public VelopackFlowSource(
|
||||
string baseUri = "https://api.velopack.io/",
|
||||
IFileDownloader? downloader = null)
|
||||
{
|
||||
@@ -29,17 +29,13 @@ namespace Velopack.Sources
|
||||
public IFileDownloader Downloader { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<VelopackAssetFeed> GetReleaseFeed(ILogger logger, string channel, Guid? stagingId = null,
|
||||
public async Task<VelopackAssetFeed> GetReleaseFeed(IVelopackLogger logger, string? appId, string channel, Guid? stagingId = null,
|
||||
VelopackAsset? latestLocalRelease = null)
|
||||
{
|
||||
string? packageId = latestLocalRelease?.PackageId ?? VelopackLocator.GetDefault(logger).AppId;
|
||||
if (string.IsNullOrWhiteSpace(packageId)) {
|
||||
//Without a package id, we can't get a feed.
|
||||
return new VelopackAssetFeed();
|
||||
}
|
||||
if (appId is null) return new VelopackAssetFeed(); // without an appId, we can't get any releases.
|
||||
|
||||
Uri baseUri = new(BaseUri, $"v1.0/manifest/");
|
||||
Uri uri = HttpUtil.AppendPathToUri(baseUri, $"{packageId}/{channel}");
|
||||
Uri uri = HttpUtil.AppendPathToUri(baseUri, $"{appId}/{channel}");
|
||||
var args = new Dictionary<string, string>();
|
||||
|
||||
if (VelopackRuntimeInfo.SystemArch != RuntimeCpu.Unknown) {
|
||||
@@ -61,30 +57,37 @@ namespace Velopack.Sources
|
||||
|
||||
var uriAndQuery = HttpUtil.AddQueryParamsToUri(uri, args);
|
||||
|
||||
logger.LogInformation("Downloading releases from '{Uri}'.", uriAndQuery);
|
||||
logger.LogInformation($"Downloading releases from '{uriAndQuery}'.");
|
||||
|
||||
var json = await Downloader.DownloadString(uriAndQuery.ToString()).ConfigureAwait(false);
|
||||
|
||||
var releaseAssets = CompiledJson.DeserializeVelopackFlowAssetArray(json);
|
||||
if (releaseAssets is null) {
|
||||
return new VelopackAssetFeed();
|
||||
}
|
||||
|
||||
return new VelopackAssetFeed() {
|
||||
Assets = releaseAssets
|
||||
Assets = releaseAssets.Cast<VelopackAsset>().ToArray()
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task DownloadReleaseEntry(ILogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken = default)
|
||||
public async Task DownloadReleaseEntry(IVelopackLogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress,
|
||||
CancellationToken cancelToken = default)
|
||||
{
|
||||
if (releaseEntry is null) throw new ArgumentNullException(nameof(releaseEntry));
|
||||
if (releaseEntry is not VelopackFlowReleaseAsset velopackRelease) {
|
||||
throw new ArgumentException($"Expected {nameof(releaseEntry)} to be {nameof(VelopackFlowReleaseAsset)} but was {releaseEntry.GetType().FullName}");
|
||||
throw new ArgumentException(
|
||||
$"Expected {nameof(releaseEntry)} to be {nameof(VelopackFlowReleaseAsset)} but was {releaseEntry.GetType().FullName}");
|
||||
}
|
||||
|
||||
if (localFile is null) throw new ArgumentNullException(nameof(localFile));
|
||||
|
||||
Uri sourceBaseUri = HttpUtil.EnsureTrailingSlash(BaseUri);
|
||||
|
||||
Uri downloadUri = new(sourceBaseUri, $"v1.0/download/{velopackRelease.Id}");
|
||||
|
||||
logger.LogInformation("Downloading '{ReleaseFileName}' from '{Uri}'.", releaseEntry.FileName, downloadUri);
|
||||
logger.LogInformation($"Downloading '{releaseEntry.FileName}' from '{downloadUri}'.");
|
||||
await Downloader.DownloadFile(downloadUri.AbsoluteUri, localFile, progress, cancelToken: cancelToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -93,4 +96,4 @@ namespace Velopack.Sources
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
@@ -6,9 +6,8 @@ using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Velopack.Locators;
|
||||
using Velopack.Logging;
|
||||
using Velopack.Util;
|
||||
|
||||
namespace Velopack
|
||||
@@ -24,7 +23,7 @@ namespace Velopack
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool AllowSetForegroundWindow(int dwProcessId);
|
||||
|
||||
private static Process StartUpdateExe(ILogger logger, IVelopackLocator locator, IEnumerable<string> args)
|
||||
private static Process StartUpdateExe(IVelopackLogger logger, IVelopackLocator locator, IEnumerable<string> args)
|
||||
{
|
||||
var psi = new ProcessStartInfo() {
|
||||
CreateNoWindow = true,
|
||||
@@ -61,11 +60,9 @@ namespace Velopack
|
||||
/// <param name="waitPid">Optionally wait for the specified process to exit before continuing.</param>
|
||||
/// <param name="locator">The locator to use to find the path to Update.exe and the packages directory.</param>
|
||||
/// <param name="startArgs">The arguments to pass to the application when it is restarted.</param>
|
||||
/// <param name="logger">The logger to use for diagnostic messages</param>
|
||||
public static void Start(IVelopackLocator? locator = null, uint waitPid = 0, string[]? startArgs = null, ILogger? logger = null)
|
||||
public static void Start(IVelopackLocator? locator = null, uint waitPid = 0, string[]? startArgs = null)
|
||||
{
|
||||
logger ??= NullLogger.Instance;
|
||||
locator ??= VelopackLocator.GetDefault(logger);
|
||||
locator ??= VelopackLocator.Current;
|
||||
|
||||
var args = new List<string>();
|
||||
args.Add("start");
|
||||
@@ -82,14 +79,13 @@ namespace Velopack
|
||||
}
|
||||
}
|
||||
|
||||
StartUpdateExe(logger, locator, args);
|
||||
StartUpdateExe(locator.Log, locator, args);
|
||||
}
|
||||
|
||||
private static Process ApplyImpl(IVelopackLocator? locator, VelopackAsset? toApply, bool silent, uint waitPid, bool restart,
|
||||
string[]? restartArgs = null, ILogger? logger = null)
|
||||
string[]? restartArgs = null)
|
||||
{
|
||||
logger ??= NullLogger.Instance;
|
||||
locator ??= VelopackLocator.GetDefault(logger);
|
||||
locator ??= VelopackLocator.Current;
|
||||
|
||||
var args = new List<string>();
|
||||
if (silent) args.Add("--silent");
|
||||
@@ -118,7 +114,7 @@ namespace Velopack
|
||||
}
|
||||
}
|
||||
|
||||
return StartUpdateExe(logger, locator, args);
|
||||
return StartUpdateExe(locator.Log, locator, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -132,12 +128,11 @@ namespace Velopack
|
||||
/// <param name="toApply">The update package you wish to apply, can be left null.</param>
|
||||
/// <param name="waitPid">Optionally wait for the specified process to exit before continuing.</param>
|
||||
/// <param name="restartArgs">The arguments to pass to the application when it is restarted.</param>
|
||||
/// <param name="logger">The logger to use for diagnostic messages</param>
|
||||
/// <exception cref="Exception">Thrown if Update.exe does not initialize properly.</exception>
|
||||
public static void Apply(IVelopackLocator? locator, VelopackAsset? toApply, bool silent, uint waitPid, bool restart,
|
||||
string[]? restartArgs = null, ILogger? logger = null)
|
||||
public static void Apply(IVelopackLocator? locator, VelopackAsset? toApply, bool silent, uint waitPid, bool restart,
|
||||
string[]? restartArgs = null)
|
||||
{
|
||||
var process = ApplyImpl(locator, toApply, silent, waitPid, restart, restartArgs, logger);
|
||||
var process = ApplyImpl(locator, toApply, silent, waitPid, restart, restartArgs);
|
||||
Thread.Sleep(500);
|
||||
|
||||
if (process.HasExited) {
|
||||
@@ -146,10 +141,10 @@ namespace Velopack
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Apply"/>
|
||||
public static async Task ApplyAsync(IVelopackLocator? locator, VelopackAsset? toApply, bool silent, uint waitPid, bool restart, string[]? restartArgs = null,
|
||||
ILogger? logger = null)
|
||||
public static async Task ApplyAsync(IVelopackLocator? locator, VelopackAsset? toApply, bool silent, uint waitPid, bool restart,
|
||||
string[]? restartArgs = null)
|
||||
{
|
||||
var process = ApplyImpl(locator, toApply, silent, waitPid, restart, restartArgs, logger);
|
||||
var process = ApplyImpl(locator, toApply, silent, waitPid, restart, restartArgs);
|
||||
await Task.Delay(500).ConfigureAwait(false);
|
||||
|
||||
if (process.HasExited) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -45,13 +45,13 @@ namespace Velopack
|
||||
/// <param name="restartArgs">The arguments to pass to the application when it is restarted.</param>
|
||||
public void WaitExitThenApplyUpdates(VelopackAsset? toApply, bool silent = false, bool restart = true, string[]? restartArgs = null)
|
||||
{
|
||||
UpdateExe.Apply(Locator, toApply, silent, Locator.ProcessId, restart, restartArgs, Log);
|
||||
UpdateExe.Apply(Locator, toApply, silent, Locator.ProcessId, restart, restartArgs);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="WaitExitThenApplyUpdates"/>
|
||||
public async Task WaitExitThenApplyUpdatesAsync(VelopackAsset? toApply, bool silent = false, bool restart = true, string[]? restartArgs = null)
|
||||
{
|
||||
await UpdateExe.ApplyAsync(Locator, toApply, silent, Locator.ProcessId, restart, restartArgs, Log).ConfigureAwait(false);
|
||||
await UpdateExe.ApplyAsync(Locator, toApply, silent, Locator.ProcessId, restart, restartArgs).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,14 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using NuGet.Versioning;
|
||||
using Velopack.Compression;
|
||||
using Velopack.Exceptions;
|
||||
using Velopack.Locators;
|
||||
using Velopack.Logging;
|
||||
using Velopack.NuGet;
|
||||
using Velopack.Sources;
|
||||
using Velopack.Util;
|
||||
@@ -52,7 +51,7 @@ namespace Velopack
|
||||
protected IUpdateSource Source { get; }
|
||||
|
||||
/// <summary> The logger to use for diagnostic messages. </summary>
|
||||
protected ILogger Log { get; }
|
||||
protected IVelopackLogger Log { get; }
|
||||
|
||||
/// <summary> The locator to use when searching for local file paths. </summary>
|
||||
protected IVelopackLocator Locator { get; }
|
||||
@@ -74,12 +73,10 @@ namespace Velopack
|
||||
/// </summary>
|
||||
/// <param name="urlOrPath">A basic URL or file path to use when checking for updates.</param>
|
||||
/// <param name="options">Override / configure default update behaviors.</param>
|
||||
/// <param name="logger">The logger to use for diagnostic messages. If one was provided to <see cref="VelopackApp.Run(ILogger)"/> but is null here,
|
||||
/// it will be cached and used again.</param>
|
||||
/// <param name="locator">This should usually be left null. Providing an <see cref="IVelopackLocator" /> allows you to mock up certain application paths.
|
||||
/// For example, if you wanted to test that updates are working in a unit test, you could provide an instance of <see cref="TestVelopackLocator"/>. </param>
|
||||
public UpdateManager(string urlOrPath, UpdateOptions? options = null, ILogger? logger = null, IVelopackLocator? locator = null)
|
||||
: this(CreateSimpleSource(urlOrPath), options, logger, locator)
|
||||
public UpdateManager(string urlOrPath, UpdateOptions? options = null, IVelopackLocator? locator = null)
|
||||
: this(CreateSimpleSource(urlOrPath), options, locator)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -89,19 +86,13 @@ namespace Velopack
|
||||
/// <param name="source">The source describing where to search for updates. This can be a custom source, if you are integrating with some private resource,
|
||||
/// or it could be one of the predefined sources. (eg. <see cref="SimpleWebSource"/> or <see cref="GithubSource"/>, etc).</param>
|
||||
/// <param name="options">Override / configure default update behaviors.</param>
|
||||
/// <param name="logger">The logger to use for diagnostic messages. If one was provided to <see cref="VelopackApp.Run(ILogger)"/> but is null here,
|
||||
/// it will be cached and used again.</param>
|
||||
/// <param name="locator">This should usually be left null. Providing an <see cref="IVelopackLocator" /> allows you to mock up certain application paths.
|
||||
/// For example, if you wanted to test that updates are working in a unit test, you could provide an instance of <see cref="TestVelopackLocator"/>. </param>
|
||||
public UpdateManager(IUpdateSource source, UpdateOptions? options = null, ILogger? logger = null, IVelopackLocator? locator = null)
|
||||
public UpdateManager(IUpdateSource source, UpdateOptions? options = null, IVelopackLocator? locator = null)
|
||||
{
|
||||
if (source == null) {
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
}
|
||||
|
||||
Source = source;
|
||||
Log = logger ?? VelopackApp.DefaultLogger ?? NullLogger.Instance;
|
||||
Locator = locator ?? VelopackApp.DefaultLocator ?? VelopackLocator.GetDefault(Log);
|
||||
Source = source ?? throw new ArgumentNullException(nameof(source));
|
||||
Locator = locator ?? VelopackLocator.Current;
|
||||
Log = Locator.Log;
|
||||
Channel = options?.ExplicitChannel ?? DefaultChannel;
|
||||
ShouldAllowVersionDowngrade = options?.AllowVersionDowngrade ?? false;
|
||||
}
|
||||
@@ -126,7 +117,7 @@ namespace Velopack
|
||||
var latestLocalFull = Locator.GetLatestLocalFullPackage();
|
||||
|
||||
Log.Debug("Retrieving latest release feed.");
|
||||
var feedObj = await Source.GetReleaseFeed(Log, Channel, stagedUserId, latestLocalFull).ConfigureAwait(false);
|
||||
var feedObj = await Source.GetReleaseFeed(Log, AppId, Channel, stagedUserId, latestLocalFull).ConfigureAwait(false);
|
||||
var feed = feedObj.Assets;
|
||||
|
||||
var latestRemoteFull = feed.Where(r => r.Type == VelopackAssetType.Full).MaxByPolyfill(x => x.Version).FirstOrDefault();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
@@ -6,8 +6,7 @@ using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Velopack.Logging;
|
||||
|
||||
namespace Velopack.Util
|
||||
{
|
||||
@@ -73,9 +72,9 @@ namespace Velopack.Util
|
||||
/// <param name="renameFirst">Try to rename this object first before deleting. Can help prevent partial delete of folders.</param>
|
||||
/// <param name="logger">Logger for diagnostic messages.</param>
|
||||
/// <returns>True if the file system object was deleted, false otherwise.</returns>
|
||||
public static bool DeleteFileOrDirectoryHard(string path, bool throwOnFailure = true, bool renameFirst = false, ILogger? logger = null)
|
||||
public static bool DeleteFileOrDirectoryHard(string path, bool throwOnFailure = true, bool renameFirst = false, IVelopackLogger? logger = null)
|
||||
{
|
||||
logger ??= NullLogger.Instance;
|
||||
logger ??= NullVelopackLogger.Instance;
|
||||
logger.Debug($"Starting to delete: {path}");
|
||||
|
||||
string? currentExePath = null;
|
||||
@@ -111,7 +110,7 @@ namespace Velopack.Util
|
||||
}
|
||||
}
|
||||
|
||||
private static void DeleteFsiTree(FileSystemInfo fileSystemInfo, string? currentExePath, ILogger logger)
|
||||
private static void DeleteFsiTree(FileSystemInfo fileSystemInfo, string? currentExePath, IVelopackLogger logger)
|
||||
{
|
||||
// if junction / symlink, don't iterate, just delete it.
|
||||
if (fileSystemInfo.Attributes.HasFlag(FileAttributes.ReparsePoint)) {
|
||||
@@ -135,7 +134,7 @@ namespace Velopack.Util
|
||||
DeleteFsiVeryHard(fileSystemInfo, currentExePath, logger);
|
||||
}
|
||||
|
||||
private static void DeleteFsiVeryHard(FileSystemInfo fileSystemInfo, string? currentExePath, ILogger logger)
|
||||
private static void DeleteFsiVeryHard(FileSystemInfo fileSystemInfo, string? currentExePath, IVelopackLogger logger)
|
||||
{
|
||||
// don't try to delete the running process
|
||||
if (currentExePath != null && PathUtil.FullPathEquals(fileSystemInfo.FullName, currentExePath)) {
|
||||
@@ -171,7 +170,7 @@ namespace Velopack.Util
|
||||
}
|
||||
}
|
||||
|
||||
public static void Retry(this Action block, int retries = 4, int retryDelay = 250, ILogger? logger = null)
|
||||
public static void Retry(this Action block, int retries = 4, int retryDelay = 250, IVelopackLogger? logger = null)
|
||||
{
|
||||
Retry(
|
||||
() => {
|
||||
@@ -183,7 +182,7 @@ namespace Velopack.Util
|
||||
logger);
|
||||
}
|
||||
|
||||
public static T Retry<T>(this Func<T> block, int retries = 4, int retryDelay = 250, ILogger? logger = null)
|
||||
public static T Retry<T>(this Func<T> block, int retries = 4, int retryDelay = 250, IVelopackLogger? logger = null)
|
||||
{
|
||||
while (true) {
|
||||
try {
|
||||
@@ -198,7 +197,7 @@ namespace Velopack.Util
|
||||
}
|
||||
}
|
||||
|
||||
public static Task RetryAsync(this Func<Task> block, int retries = 4, int retryDelay = 250, ILogger? logger = null)
|
||||
public static Task RetryAsync(this Func<Task> block, int retries = 4, int retryDelay = 250, IVelopackLogger? logger = null)
|
||||
{
|
||||
return RetryAsync(
|
||||
async () => {
|
||||
@@ -210,7 +209,7 @@ namespace Velopack.Util
|
||||
logger);
|
||||
}
|
||||
|
||||
public static async Task<T> RetryAsync<T>(this Func<Task<T>> block, int retries = 4, int retryDelay = 250, ILogger? logger = null)
|
||||
public static async Task<T> RetryAsync<T>(this Func<Task<T>> block, int retries = 4, int retryDelay = 250, IVelopackLogger? logger = null)
|
||||
{
|
||||
while (true) {
|
||||
try {
|
||||
|
||||
@@ -6,7 +6,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.Logging;
|
||||
|
||||
namespace Velopack.Util
|
||||
{
|
||||
@@ -56,7 +56,7 @@ namespace Velopack.Util
|
||||
}
|
||||
#endif
|
||||
|
||||
public static Process StartRedirectOutputToILogger(this ProcessStartInfo psi, ILogger log, LogLevel outputLevel)
|
||||
public static Process StartRedirectOutputToILogger(this ProcessStartInfo psi, IVelopackLogger log, VelopackLogLevel outputLevel)
|
||||
{
|
||||
psi.RedirectStandardOutput = true;
|
||||
psi.RedirectStandardError = true;
|
||||
|
||||
@@ -24,26 +24,15 @@
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.IO.Compression.FileSystem" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="[2.2.0,)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard2')) ">
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="[2.2.0,)" />
|
||||
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" $(TargetFramework) == 'net6.0' ">
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="[6.0.0,)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" $(TargetFramework) == 'net8.0' ">
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="[8.0.0,)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" $(TargetFramework) == 'net9.0' ">
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="[9.0.0,)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using NuGet.Versioning;
|
||||
using Velopack.Locators;
|
||||
using Velopack.Logging;
|
||||
using Velopack.Util;
|
||||
|
||||
namespace Velopack
|
||||
@@ -27,18 +26,15 @@ namespace Velopack
|
||||
[DllImport("shell32.dll", SetLastError = true)]
|
||||
private static extern void SetCurrentProcessExplicitAppUserModelID([MarshalAs(UnmanagedType.LPWStr)] string AppID);
|
||||
|
||||
internal static ILogger DefaultLogger { get; private set; } = NullLogger.Instance;
|
||||
|
||||
internal static IVelopackLocator? DefaultLocator { get; private set; }
|
||||
|
||||
VelopackHook? _install;
|
||||
VelopackHook? _update;
|
||||
VelopackHook? _obsolete;
|
||||
VelopackHook? _uninstall;
|
||||
VelopackHook? _firstrun;
|
||||
VelopackHook? _restarted;
|
||||
string[]? _args;
|
||||
bool _autoApply = true;
|
||||
private VelopackHook? _install;
|
||||
private VelopackHook? _update;
|
||||
private VelopackHook? _obsolete;
|
||||
private VelopackHook? _uninstall;
|
||||
private VelopackHook? _firstrun;
|
||||
private VelopackHook? _restarted;
|
||||
private string[]? _args;
|
||||
private bool _autoApply = true;
|
||||
private IVelopackLocator? _customLocator;
|
||||
|
||||
private VelopackApp()
|
||||
{
|
||||
@@ -47,7 +43,7 @@ namespace Velopack
|
||||
/// <summary>
|
||||
/// Creates and returns a new Velopack application builder.
|
||||
/// </summary>
|
||||
public static VelopackApp Build() => new VelopackApp();
|
||||
public static VelopackApp Build() => new();
|
||||
|
||||
/// <summary>
|
||||
/// Override the command line arguments used to determine the Velopack hook to run.
|
||||
@@ -74,14 +70,14 @@ namespace Velopack
|
||||
/// </summary>
|
||||
public VelopackApp SetLocator(IVelopackLocator locator)
|
||||
{
|
||||
DefaultLocator = locator;
|
||||
_customLocator = locator;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This hook is triggered when the application is started for the first time after installation.
|
||||
/// </summary>
|
||||
public VelopackApp WithFirstRun(VelopackHook hook)
|
||||
public VelopackApp OnFirstRun(VelopackHook hook)
|
||||
{
|
||||
_firstrun += hook;
|
||||
return this;
|
||||
@@ -90,7 +86,7 @@ namespace Velopack
|
||||
/// <summary>
|
||||
/// This hook is triggered when the application is restarted by Velopack after installing updates.
|
||||
/// </summary>
|
||||
public VelopackApp WithRestarted(VelopackHook hook)
|
||||
public VelopackApp OnRestarted(VelopackHook hook)
|
||||
{
|
||||
_restarted += hook;
|
||||
return this;
|
||||
@@ -103,7 +99,7 @@ namespace Velopack
|
||||
/// Only supported on windows; On other operating systems, this will never be called.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
public VelopackApp WithAfterInstallFastCallback(VelopackHook hook)
|
||||
public VelopackApp OnAfterInstallFastCallback(VelopackHook hook)
|
||||
{
|
||||
_install += hook;
|
||||
return this;
|
||||
@@ -116,7 +112,7 @@ namespace Velopack
|
||||
/// Only supported on windows; On other operating systems, this will never be called.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
public VelopackApp WithAfterUpdateFastCallback(VelopackHook hook)
|
||||
public VelopackApp OnAfterUpdateFastCallback(VelopackHook hook)
|
||||
{
|
||||
_update += hook;
|
||||
return this;
|
||||
@@ -129,7 +125,7 @@ namespace Velopack
|
||||
/// Only supported on windows; On other operating systems, this will never be called.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
public VelopackApp WithBeforeUpdateFastCallback(VelopackHook hook)
|
||||
public VelopackApp OnBeforeUpdateFastCallback(VelopackHook hook)
|
||||
{
|
||||
_obsolete += hook;
|
||||
return this;
|
||||
@@ -142,7 +138,7 @@ namespace Velopack
|
||||
/// Only supported on windows; On other operating systems, this will never be called.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
public VelopackApp WithBeforeUninstallFastCallback(VelopackHook hook)
|
||||
public VelopackApp OnBeforeUninstallFastCallback(VelopackHook hook)
|
||||
{
|
||||
_uninstall += hook;
|
||||
return this;
|
||||
@@ -151,9 +147,7 @@ namespace Velopack
|
||||
/// <summary>
|
||||
/// Runs the Velopack application startup code and triggers any configured hooks.
|
||||
/// </summary>
|
||||
/// <param name="logger">A logging interface for diagnostic messages. This will be
|
||||
/// cached and potentially re-used throughout the lifetime of the application.</param>
|
||||
public void Run(ILogger? logger = null)
|
||||
public void Run()
|
||||
{
|
||||
var args = _args ?? Environment.GetCommandLineArgs().Skip(1).ToArray();
|
||||
|
||||
@@ -164,11 +158,19 @@ namespace Velopack
|
||||
return;
|
||||
}
|
||||
|
||||
var log = logger ?? NullLogger.Instance;
|
||||
var locator = DefaultLocator ?? VelopackLocator.GetDefault(log);
|
||||
DefaultLogger = log;
|
||||
if (VelopackLocator.IsCurrentSet) {
|
||||
VelopackLocator.Current.Log.Error(
|
||||
"VelopackApp.Build().Run() was called more than once. This is not allowed and can lead to unexpected behaviour.");
|
||||
}
|
||||
|
||||
log.Info("Starting Velopack App (Run).");
|
||||
if (_customLocator != null) {
|
||||
VelopackLocator.SetCurrentLocator(_customLocator);
|
||||
}
|
||||
|
||||
var locator = VelopackLocator.GetCurrentOrCreateDefault();
|
||||
var log = locator.Log;
|
||||
|
||||
log.Info($"Starting VelopackApp.Run (library version {VelopackRuntimeInfo.VelopackNugetVersion}).");
|
||||
|
||||
if (VelopackRuntimeInfo.IsWindows && locator.AppId != null) {
|
||||
var appUserModelId = CoreUtil.GetAppUserModelId(locator.AppId);
|
||||
@@ -224,7 +226,7 @@ namespace Velopack
|
||||
log.Info($"Launching app is out-dated. Current: {myVersion}, Newest Local Available: {latestLocal.Version}");
|
||||
if (!restarted && _autoApply) {
|
||||
log.Info("Auto apply is true, so restarting to apply update...");
|
||||
UpdateExe.Apply(locator, latestLocal, false, locator.ProcessId, true, args, log);
|
||||
UpdateExe.Apply(locator, latestLocal, false, locator.ProcessId, true, args);
|
||||
Exit(0);
|
||||
} else {
|
||||
log.Info("Pre-condition failed, we will not restart to apply updates. (restarted: " + restarted + ", autoApply: " + _autoApply + ")");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#nullable disable
|
||||
#nullable disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@@ -7,9 +7,9 @@ using System.Linq;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Win32;
|
||||
using NuGet.Versioning;
|
||||
using Velopack.Logging;
|
||||
using Velopack.Sources;
|
||||
using Velopack.Util;
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Velopack.Windows
|
||||
public abstract Task<bool> CheckIsSupported();
|
||||
|
||||
/// <summary> Download the latest installer for this runtime to the specified file </summary>
|
||||
public virtual async Task DownloadToFile(string localPath, Action<int> progress = null, IFileDownloader downloader = null, ILogger log = null)
|
||||
public virtual async Task DownloadToFile(string localPath, Action<int> progress = null, IFileDownloader downloader = null, IVelopackLogger log = null)
|
||||
{
|
||||
var url = await GetDownloadUrl().ConfigureAwait(false);
|
||||
log?.Info($"Downloading {Id} from {url} to {localPath}");
|
||||
@@ -86,7 +86,7 @@ namespace Velopack.Windows
|
||||
|
||||
/// <summary> Execute a runtime installer at a local file path. Typically used after <see cref="DownloadToFile"/> </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
public virtual async Task<RuntimeInstallResult> InvokeInstaller(string pathToInstaller, bool isQuiet, ILogger log = null)
|
||||
public virtual async Task<RuntimeInstallResult> InvokeInstaller(string pathToInstaller, bool isQuiet, IVelopackLogger log = null)
|
||||
{
|
||||
var args = new string[] { "/passive", "/norestart", "/showrmui" };
|
||||
var quietArgs = new string[] { "/q", "/norestart" };
|
||||
|
||||
@@ -5,9 +5,8 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Versioning;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Velopack.Locators;
|
||||
using Velopack.Logging;
|
||||
using Velopack.NuGet;
|
||||
using Velopack.Util;
|
||||
|
||||
@@ -58,16 +57,16 @@ namespace Velopack.Windows
|
||||
public class Shortcuts
|
||||
{
|
||||
/// <summary> Log for diagnostic messages. </summary>
|
||||
protected ILogger Log { get; }
|
||||
protected IVelopackLogger Log { get; }
|
||||
|
||||
/// <summary> Locator to use for finding important application paths. </summary>
|
||||
protected IVelopackLocator Locator { get; }
|
||||
|
||||
/// <inheritdoc cref="Shortcuts"/>
|
||||
public Shortcuts(ILogger logger = null, IVelopackLocator locator = null)
|
||||
public Shortcuts(IVelopackLocator locator = null)
|
||||
{
|
||||
Log = logger ?? NullLogger.Instance;
|
||||
Locator = locator ?? VelopackLocator.GetDefault(Log);
|
||||
Locator = locator ?? VelopackLocator.Current;
|
||||
Log = Locator.Log;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -80,7 +79,7 @@ namespace Velopack.Windows
|
||||
Locator.ThisExeRelativePath,
|
||||
location,
|
||||
false,
|
||||
null, // shortcut arguments
|
||||
null, // shortcut arguments
|
||||
null); // shortcut icon
|
||||
}
|
||||
|
||||
@@ -166,30 +165,31 @@ namespace Velopack.Windows
|
||||
Log.Info($"Creating shortcut for {relativeExeName} => {file}");
|
||||
|
||||
ShellLink sl;
|
||||
IoUtil.Retry(() => {
|
||||
File.Delete(file);
|
||||
IoUtil.Retry(
|
||||
() => {
|
||||
File.Delete(file);
|
||||
|
||||
var target = Path.Combine(currentDir, relativeExeName);
|
||||
sl = new ShellLink {
|
||||
Target = target,
|
||||
IconPath = icon ?? target,
|
||||
IconIndex = 0,
|
||||
WorkingDirectory = Path.GetDirectoryName(exePath),
|
||||
Description = zf.ProductDescription,
|
||||
};
|
||||
var target = Path.Combine(currentDir, relativeExeName);
|
||||
sl = new ShellLink {
|
||||
Target = target,
|
||||
IconPath = icon ?? target,
|
||||
IconIndex = 0,
|
||||
WorkingDirectory = Path.GetDirectoryName(exePath),
|
||||
Description = zf.ProductDescription,
|
||||
};
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(programArguments)) {
|
||||
sl.Arguments += String.Format(" -a \"{0}\"", programArguments);
|
||||
}
|
||||
if (!String.IsNullOrWhiteSpace(programArguments)) {
|
||||
sl.Arguments += String.Format(" -a \"{0}\"", programArguments);
|
||||
}
|
||||
|
||||
//var appUserModelId = Utility.GetAppUserModelId(zf.Id, exeName);
|
||||
//var toastActivatorCLSID = Utility.CreateGuidFromHash(appUserModelId).ToString();
|
||||
//sl.SetAppUserModelId(appUserModelId);
|
||||
//sl.SetToastActivatorCLSID(toastActivatorCLSID);
|
||||
//var appUserModelId = Utility.GetAppUserModelId(zf.Id, exeName);
|
||||
//var toastActivatorCLSID = Utility.CreateGuidFromHash(appUserModelId).ToString();
|
||||
//sl.SetAppUserModelId(appUserModelId);
|
||||
//sl.SetToastActivatorCLSID(toastActivatorCLSID);
|
||||
|
||||
Log.Info($"About to save shortcut: {file} (target {sl.Target}, workingDir {sl.WorkingDirectory}, args {sl.Arguments})");
|
||||
sl.Save(file);
|
||||
});
|
||||
Log.Info($"About to save shortcut: {file} (target {sl.Target}, workingDir {sl.WorkingDirectory}, args {sl.Arguments})");
|
||||
sl.Save(file);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,16 +230,16 @@ namespace Velopack.Windows
|
||||
protected virtual string LinkPathForVersionInfo(ShortcutLocation location, ZipPackage package, FileVersionInfo versionInfo, string rootdir)
|
||||
{
|
||||
var possibleProductNames = new[] {
|
||||
versionInfo.ProductName,
|
||||
package.ProductName,
|
||||
versionInfo.FileDescription,
|
||||
Path.GetFileNameWithoutExtension(versionInfo.FileName)
|
||||
};
|
||||
versionInfo.ProductName,
|
||||
package.ProductName,
|
||||
versionInfo.FileDescription,
|
||||
Path.GetFileNameWithoutExtension(versionInfo.FileName)
|
||||
};
|
||||
|
||||
var possibleCompanyNames = new[] {
|
||||
versionInfo.CompanyName,
|
||||
package.ProductCompany,
|
||||
};
|
||||
versionInfo.CompanyName,
|
||||
package.ProductCompany,
|
||||
};
|
||||
|
||||
var prodName = possibleCompanyNames.First(x => !String.IsNullOrWhiteSpace(x));
|
||||
var pkgName = possibleProductNames.First(x => !String.IsNullOrWhiteSpace(x));
|
||||
@@ -250,7 +250,8 @@ namespace Velopack.Windows
|
||||
/// <summary>
|
||||
/// Given the application info, return the shortcut target path.
|
||||
/// </summary>
|
||||
protected virtual string GetLinkPath(ShortcutLocation location, string title, string applicationName, string rootdir, bool createDirectoryIfNecessary = true)
|
||||
protected virtual string GetLinkPath(ShortcutLocation location, string title, string applicationName, string rootdir,
|
||||
bool createDirectoryIfNecessary = true)
|
||||
{
|
||||
var dir = default(string);
|
||||
|
||||
@@ -288,4 +289,4 @@ namespace Velopack.Windows
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,45 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.Logging;
|
||||
|
||||
namespace Velopack.Util
|
||||
namespace Velopack.Core
|
||||
{
|
||||
[ExcludeFromCodeCoverage]
|
||||
internal static class LoggerExtensions
|
||||
public static class LoggerExtensions
|
||||
{
|
||||
public static IVelopackLogger ToVelopackLogger(this ILogger logger)
|
||||
{
|
||||
return new MicrosoftExtensionsLoggerAdapter(logger);
|
||||
}
|
||||
|
||||
private class MicrosoftExtensionsLoggerAdapter(ILogger logger) : IVelopackLogger
|
||||
{
|
||||
public void Log(VelopackLogLevel logLevel, string? message, Exception? exception)
|
||||
{
|
||||
switch (logLevel) {
|
||||
case VelopackLogLevel.Trace:
|
||||
logger.LogTrace(exception, message);
|
||||
break;
|
||||
case VelopackLogLevel.Debug:
|
||||
logger.LogDebug(exception, message);
|
||||
break;
|
||||
case VelopackLogLevel.Information:
|
||||
logger.LogInformation(exception, message);
|
||||
break;
|
||||
case VelopackLogLevel.Warning:
|
||||
logger.LogWarning(exception, message);
|
||||
break;
|
||||
case VelopackLogLevel.Error:
|
||||
logger.LogError(exception, message);
|
||||
break;
|
||||
case VelopackLogLevel.Critical:
|
||||
logger.LogCritical(exception, message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Trace(this ILogger logger, string message)
|
||||
{
|
||||
logger.LogTrace(message);
|
||||
@@ -16,6 +49,7 @@ namespace Velopack.Util
|
||||
{
|
||||
logger.LogTrace(ex, message);
|
||||
}
|
||||
|
||||
public static void Trace(this ILogger logger, Exception ex)
|
||||
{
|
||||
logger.LogTrace(ex, ex.Message);
|
||||
@@ -15,6 +15,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -3,6 +3,7 @@ using Azure.Storage;
|
||||
using Azure.Storage.Blobs;
|
||||
using Azure.Storage.Blobs.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.Core;
|
||||
using Velopack.Util;
|
||||
|
||||
namespace Velopack.Deployment;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.Core;
|
||||
using Velopack.Packaging;
|
||||
using Velopack.Sources;
|
||||
using Velopack.Util;
|
||||
@@ -68,12 +69,12 @@ public class LocalRepository(ILogger logger) : ObjectRepository<LocalDownloadOpt
|
||||
protected override Task SaveEntryToFileAsync(LocalDownloadOptions options, VelopackAsset entry, string filePath)
|
||||
{
|
||||
var source = new SimpleFileSource(options.TargetPath);
|
||||
return source.DownloadReleaseEntry(Log, entry, filePath, (i) => { }, default);
|
||||
return source.DownloadReleaseEntry(Log.ToVelopackLogger(), entry, filePath, (i) => { }, default);
|
||||
}
|
||||
|
||||
protected override Task<VelopackAssetFeed> GetReleasesAsync(LocalDownloadOptions options)
|
||||
{
|
||||
var source = new SimpleFileSource(options.TargetPath);
|
||||
return source.GetReleaseFeed(channel: options.Channel, logger: Log);
|
||||
return source.GetReleaseFeed(Log.ToVelopackLogger(), null, options.Channel);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using Amazon.Runtime;
|
||||
using Amazon.S3;
|
||||
using Amazon.S3.Model;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.Core;
|
||||
using Velopack.Util;
|
||||
|
||||
namespace Velopack.Deployment;
|
||||
|
||||
@@ -32,25 +32,20 @@ public interface IRepositoryCanDownload<TDown> where TDown : RepositoryOptions
|
||||
Task DownloadLatestFullPackageAsync(TDown options);
|
||||
}
|
||||
|
||||
public abstract class SourceRepository<TDown, TSource> : DownRepository<TDown>
|
||||
public abstract class SourceRepository<TDown, TSource>(ILogger logger) : DownRepository<TDown>(logger)
|
||||
where TDown : RepositoryOptions
|
||||
where TSource : IUpdateSource
|
||||
{
|
||||
public SourceRepository(ILogger logger)
|
||||
: base(logger)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Task<VelopackAssetFeed> GetReleasesAsync(TDown options)
|
||||
{
|
||||
var source = CreateSource(options);
|
||||
return source.GetReleaseFeed(channel: options.Channel, logger: Log);
|
||||
return source.GetReleaseFeed(Log.ToVelopackLogger(), null, options.Channel);
|
||||
}
|
||||
|
||||
protected override Task SaveEntryToFileAsync(TDown options, VelopackAsset entry, string filePath)
|
||||
{
|
||||
var source = CreateSource(options);
|
||||
return source.DownloadReleaseEntry(Log, entry, filePath, (i) => { });
|
||||
return source.DownloadReleaseEntry(Log.ToVelopackLogger(), entry, filePath, (i) => { });
|
||||
}
|
||||
|
||||
public abstract TSource CreateSource(TDown options);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using ICSharpCode.SharpZipLib.Tar;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.Compression;
|
||||
using Velopack.Core;
|
||||
using Velopack.Util;
|
||||
|
||||
namespace Velopack.Packaging.Unix;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Runtime.Versioning;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.Core;
|
||||
using Velopack.Core.Abstractions;
|
||||
using Velopack.Util;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// https://raw.githubusercontent.com/egramtel/dotnet-bundle/master/DotNet.Bundle/PlistWriter.cs
|
||||
using System.Xml;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.Core;
|
||||
using Velopack.Util;
|
||||
|
||||
namespace Velopack.Packaging.Unix;
|
||||
|
||||
@@ -248,7 +248,7 @@ public class WindowsPackCommandRunner : PackageBuilder<WindowsPackOptions>
|
||||
// create a .portable file to indicate this is a portable package
|
||||
File.Create(Path.Combine(dir.FullName, ".portable")).Close();
|
||||
|
||||
await EasyZip.CreateZipFromDirectoryAsync(Log, outputPath, dir.FullName, CoreUtil.CreateProgressDelegate(progress, 40, 100));
|
||||
await EasyZip.CreateZipFromDirectoryAsync(Log.ToVelopackLogger(), outputPath, dir.FullName, CoreUtil.CreateProgressDelegate(progress, 40, 100));
|
||||
progress(100);
|
||||
}
|
||||
|
||||
@@ -301,7 +301,8 @@ public class WindowsPackCommandRunner : PackageBuilder<WindowsPackOptions>
|
||||
Log.Info($"Use Azure Trusted Signing service for code signing. Metadata file path: {trustedSignMetadataPath}");
|
||||
|
||||
string dlibPath = GetDlibPath(CancellationToken.None);
|
||||
signParams = $"/fd SHA256 /tr http://timestamp.acs.microsoft.com /v /debug /td SHA256 /dlib {HelperFile.AzureDlibFileName} /dmdf \"{trustedSignMetadataPath}\"";
|
||||
signParams =
|
||||
$"/fd SHA256 /tr http://timestamp.acs.microsoft.com /v /debug /td SHA256 /dlib {HelperFile.AzureDlibFileName} /dmdf \"{trustedSignMetadataPath}\"";
|
||||
helper.Sign(filePaths, signParams, signParallel, progress, false);
|
||||
} else if (!string.IsNullOrEmpty(signParams)) {
|
||||
helper.Sign(filePaths, signParams, signParallel, progress, false);
|
||||
|
||||
@@ -33,7 +33,8 @@ public class DeltaPatchCommandRunner : ICommand<DeltaPatchOptions>
|
||||
using var _1 = TempUtil.GetTempDirectory(out var workDir);
|
||||
|
||||
var delta = new DeltaEmbedded(HelperFile.GetZstdPath(), _logger, tmp);
|
||||
EasyZip.ExtractZipToDirectory(_logger, options.BasePackage, workDir);
|
||||
var veloLogger = _logger.ToVelopackLogger();
|
||||
EasyZip.ExtractZipToDirectory(veloLogger, options.BasePackage, workDir);
|
||||
|
||||
await _console.ExecuteProgressAsync(
|
||||
async (ctx) => {
|
||||
@@ -50,7 +51,7 @@ public class DeltaPatchCommandRunner : ICommand<DeltaPatchOptions>
|
||||
await ctx.RunTask(
|
||||
$"Building {Path.GetFileName(options.OutputFile)}",
|
||||
async (progress) => {
|
||||
await EasyZip.CreateZipFromDirectoryAsync(_logger, options.OutputFile, workDir, progress);
|
||||
await EasyZip.CreateZipFromDirectoryAsync(veloLogger, options.OutputFile, workDir, progress);
|
||||
progress(100);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.Compression;
|
||||
using Velopack.Core;
|
||||
|
||||
namespace Velopack.Packaging;
|
||||
|
||||
@@ -21,7 +22,7 @@ public class DeltaEmbedded
|
||||
{
|
||||
private readonly Zstd _zstd;
|
||||
|
||||
public DeltaImpl(string zstdPath, ILogger logger, string baseTmpDir) : base(logger, baseTmpDir)
|
||||
public DeltaImpl(string zstdPath, ILogger logger, string baseTmpDir) : base(logger.ToVelopackLogger(), baseTmpDir)
|
||||
{
|
||||
_zstd = new Zstd(zstdPath);
|
||||
}
|
||||
|
||||
@@ -76,8 +76,9 @@ public class DeltaPackageBuilder
|
||||
_logger.Info($"Creating delta for {basePackage.Version} -> {newPackage.Version} with {numParallel} parallel threads.");
|
||||
_logger.Debug($"Extracting {Path.GetFileName(basePackage.PackageFile)} and {Path.GetFileName(newPackage.PackageFile)} into {tempPath}");
|
||||
|
||||
EasyZip.ExtractZipToDirectory(_logger, basePackage.PackageFile, baseTempInfo.FullName);
|
||||
EasyZip.ExtractZipToDirectory(_logger, newPackage.PackageFile, tempInfo.FullName);
|
||||
var veloLogger = _logger.ToVelopackLogger();
|
||||
EasyZip.ExtractZipToDirectory(veloLogger, basePackage.PackageFile, baseTempInfo.FullName);
|
||||
EasyZip.ExtractZipToDirectory(veloLogger, newPackage.PackageFile, tempInfo.FullName);
|
||||
|
||||
// Collect a list of relative paths under 'lib' and map them
|
||||
// to their full name. We'll use this later to determine in
|
||||
@@ -191,7 +192,7 @@ public class DeltaPackageBuilder
|
||||
"Delta creation failed for one or more files. See log for details. To skip delta generation, use the '--delta none' argument.");
|
||||
}
|
||||
|
||||
EasyZip.CreateZipFromDirectoryAsync(_logger, outputFile, tempInfo.FullName, CoreUtil.CreateProgressDelegate(progress, 70, 100)).GetAwaiterResult();
|
||||
EasyZip.CreateZipFromDirectoryAsync(_logger.ToVelopackLogger(), outputFile, tempInfo.FullName, CoreUtil.CreateProgressDelegate(progress, 70, 100)).GetAwaiterResult();
|
||||
progress(100);
|
||||
fRemoved = baseLibFiles.Count;
|
||||
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
using System.Text;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
#if !DEBUG
|
||||
using Velopack.Util;
|
||||
#endif
|
||||
|
||||
namespace Velopack.Packaging;
|
||||
|
||||
public static class HelperFile
|
||||
@@ -23,7 +19,7 @@ public static class HelperFile
|
||||
#else
|
||||
case RuntimeOs.Linux:
|
||||
if (!target.HasArchitecture) {
|
||||
log.Warn("No architecture specified with --runtime, defaulting to x64. If this was not intended please specify via the --runtime parameter");
|
||||
log.LogWarning("No architecture specified with --runtime, defaulting to x64. If this was not intended please specify via the --runtime parameter");
|
||||
return FindHelperFile("UpdateNix_x64");
|
||||
}
|
||||
|
||||
|
||||
@@ -293,7 +293,7 @@ public abstract class PackageBuilder<T> : ICommand<T>
|
||||
|
||||
AddContentTypesAndRel(nuspecPath);
|
||||
|
||||
await EasyZip.CreateZipFromDirectoryAsync(Log, outputPath, stagingDir.FullName, CoreUtil.CreateProgressDelegate(progress, 30, 100));
|
||||
await EasyZip.CreateZipFromDirectoryAsync(Log.ToVelopackLogger(), outputPath, stagingDir.FullName, CoreUtil.CreateProgressDelegate(progress, 30, 100));
|
||||
progress(100);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Velopack.Core.Abstractions;
|
||||
using Velopack.Core;
|
||||
using Velopack.Core.Abstractions;
|
||||
using Velopack.Util;
|
||||
|
||||
namespace Velopack.Vpk.Logging;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Threading;
|
||||
using Spectre.Console;
|
||||
using Velopack.Core;
|
||||
using Velopack.Core.Abstractions;
|
||||
using Velopack.Util;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Threading;
|
||||
using NuGet.Protocol.Core.Types;
|
||||
using Velopack.Core;
|
||||
using Velopack.Packaging.NuGet;
|
||||
using Velopack.Util;
|
||||
|
||||
@@ -21,7 +22,6 @@ public class UpdateChecker
|
||||
{
|
||||
if (_defaults.SkipUpdates) return false;
|
||||
try {
|
||||
|
||||
var myVer = VelopackRuntimeInfo.VelopackNugetVersion;
|
||||
var isPre = myVer.IsPrerelease || myVer.HasMetadata;
|
||||
|
||||
@@ -38,6 +38,7 @@ public class UpdateChecker
|
||||
} else {
|
||||
_logger.Warn($"[bold]There is a newer version of vpk available. Run 'dotnet tool update -g vpk --version {cacheVersion}'[/]");
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
_logger.Debug($"vpk is up to date (latest online = {cacheVersion})");
|
||||
@@ -45,6 +46,7 @@ public class UpdateChecker
|
||||
} catch (Exception ex) {
|
||||
_logger.Debug(ex, "Failed to check for updates.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
class ConsoleLogger : ILogger
|
||||
{
|
||||
public IDisposable BeginScope<TState>(TState state) where TState : notnull
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool IsEnabled(LogLevel logLevel)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
|
||||
{
|
||||
Console.WriteLine(formatter(state, exception));
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,9 @@
|
||||
using System.Diagnostics;
|
||||
using Velopack;
|
||||
using Velopack.Locators;
|
||||
using Velopack.Logging;
|
||||
|
||||
var locator = VelopackLocator.CreateDefaultForPlatform(new ConsoleVelopackLogger());
|
||||
|
||||
try {
|
||||
bool shouldExit = false;
|
||||
@@ -14,21 +17,24 @@ try {
|
||||
#if !NO_VELO_BUILDER
|
||||
VelopackApp.Build()
|
||||
.SetAutoApplyOnStartup(shouldAutoUpdate)
|
||||
.WithFirstRun((v) => {
|
||||
debugFile("firstrun", v.ToString());
|
||||
Console.WriteLine("was first run");
|
||||
shouldExit = true;
|
||||
})
|
||||
.WithRestarted((v) => {
|
||||
debugFile("restarted", v.ToString() + "," + String.Join(",", args));
|
||||
Console.WriteLine("app just restarted");
|
||||
shouldExit = true;
|
||||
})
|
||||
.WithAfterInstallFastCallback((v) => debugFile("args.txt", String.Join(" ", args)))
|
||||
.WithBeforeUpdateFastCallback((v) => debugFile("args.txt", String.Join(" ", args)))
|
||||
.WithAfterUpdateFastCallback((v) => debugFile("args.txt", String.Join(" ", args)))
|
||||
.WithBeforeUninstallFastCallback((v) => debugFile("args.txt", String.Join(" ", args)))
|
||||
.Run(new ConsoleLogger());
|
||||
.OnFirstRun(
|
||||
(v) => {
|
||||
debugFile("firstrun", v.ToString());
|
||||
Console.WriteLine("was first run");
|
||||
shouldExit = true;
|
||||
})
|
||||
.OnRestarted(
|
||||
(v) => {
|
||||
debugFile("restarted", v.ToString() + "," + String.Join(",", args));
|
||||
Console.WriteLine("app just restarted");
|
||||
shouldExit = true;
|
||||
})
|
||||
.SetLocator(locator)
|
||||
.OnAfterInstallFastCallback((v) => debugFile("args.txt", String.Join(" ", args)))
|
||||
.OnBeforeUpdateFastCallback((v) => debugFile("args.txt", String.Join(" ", args)))
|
||||
.OnAfterUpdateFastCallback((v) => debugFile("args.txt", String.Join(" ", args)))
|
||||
.OnBeforeUninstallFastCallback((v) => debugFile("args.txt", String.Join(" ", args)))
|
||||
.Run();
|
||||
|
||||
if (shouldAutoUpdate) {
|
||||
// this shouldn't be reached
|
||||
@@ -41,7 +47,6 @@ try {
|
||||
#endif
|
||||
|
||||
if (args.Length == 1 && args[0] == "version") {
|
||||
var locator = VelopackLocator.GetDefault(new ConsoleLogger());
|
||||
Console.WriteLine(locator.CurrentlyInstalledVersion?.ToString() ?? "unknown_version");
|
||||
return 0;
|
||||
}
|
||||
@@ -53,7 +58,7 @@ try {
|
||||
|
||||
if (args.Length == 2) {
|
||||
if (args[0] == "check") {
|
||||
var um = new UpdateManager(args[1], null, new ConsoleLogger());
|
||||
var um = new UpdateManager(args[1], null, locator);
|
||||
var info = um.CheckForUpdates();
|
||||
if (info == null) {
|
||||
Console.WriteLine("no updates");
|
||||
@@ -65,28 +70,29 @@ try {
|
||||
}
|
||||
|
||||
if (args[0] == "download") {
|
||||
var um = new UpdateManager(args[1], null, new ConsoleLogger());
|
||||
var um = new UpdateManager(args[1], null, locator);
|
||||
var info = um.CheckForUpdates();
|
||||
if (info == null) {
|
||||
Console.WriteLine("no updates");
|
||||
return -1;
|
||||
}
|
||||
|
||||
um.DownloadUpdates(info, (x) => Console.WriteLine(x));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (args[0] == "apply") {
|
||||
var um = new UpdateManager(args[1], null, new ConsoleLogger());
|
||||
var um = new UpdateManager(args[1], null, locator);
|
||||
if (um.UpdatePendingRestart == null) {
|
||||
Console.WriteLine("not pending restart");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Console.WriteLine("applying...");
|
||||
um.ApplyUpdatesAndRestart((VelopackAsset) null, new[] { "test", "args !!" });
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
Console.WriteLine("exception: " + ex.ToString());
|
||||
if (Debugger.IsAttached) throw;
|
||||
@@ -100,4 +106,4 @@ void debugFile(string name, string message)
|
||||
{
|
||||
var path = Path.Combine(AppContext.BaseDirectory, "..", name);
|
||||
File.AppendAllText(path, message + Environment.NewLine);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using Azure.Storage.Blobs;
|
||||
using NuGet.Versioning;
|
||||
using Velopack.Core;
|
||||
using Velopack.Deployment;
|
||||
using Velopack.Locators;
|
||||
using Velopack.Sources;
|
||||
using Velopack.Util;
|
||||
|
||||
@@ -92,8 +94,9 @@ public class DeploymentTests
|
||||
// get the latest
|
||||
var source = new SimpleWebSource(updateUrl);
|
||||
VelopackAssetFeed feed = new VelopackAssetFeed();
|
||||
|
||||
try {
|
||||
feed = await source.GetReleaseFeed(logger, CHANNEL);
|
||||
feed = await source.GetReleaseFeed(logger.ToVelopackLogger(), null, CHANNEL);
|
||||
} catch (Exception ex) {
|
||||
logger.Warn(ex, "Failed to fetch release feed.");
|
||||
}
|
||||
@@ -116,7 +119,7 @@ public class DeploymentTests
|
||||
await repo.UploadMissingAssetsAsync(options);
|
||||
|
||||
// verify that new version has been uploaded
|
||||
feed = await source.GetReleaseFeed(logger, CHANNEL);
|
||||
feed = await source.GetReleaseFeed(logger.ToVelopackLogger(), null, CHANNEL);
|
||||
latestOnline = feed.Assets.Where(a => a.Version != null && a.Type == VelopackAssetType.Full).MaxBy(a => a.Version);
|
||||
|
||||
Assert.True(latestOnline != null, "No latest version found.");
|
||||
|
||||
@@ -173,7 +173,7 @@ This is just a _test_!
|
||||
|
||||
// update
|
||||
var source = new GiteaSource(GITEA_REPOURL, GITEA_TOKEN, false);
|
||||
var releases = source.GetReleaseFeed(channel: uniqueSuffix, logger: logger).GetAwaiterResult();
|
||||
var releases = source.GetReleaseFeed(logger.ToVelopackLogger(), null, channel: uniqueSuffix).GetAwaiterResult();
|
||||
|
||||
var ghrel = releases.Assets.Select(r => (GiteaSource.GitBaseAsset) r).ToArray();
|
||||
foreach (var g in ghrel) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Velopack.Sources;
|
||||
using Octokit;
|
||||
using Velopack.Core;
|
||||
using Velopack.Locators;
|
||||
using Velopack.Packaging.Exceptions;
|
||||
using Velopack.Util;
|
||||
|
||||
@@ -167,7 +168,7 @@ public class GithubDeploymentTests
|
||||
|
||||
// update
|
||||
var source = new GithubSource(GITHUB_REPOURL, GITHUB_TOKEN, false);
|
||||
var releases = source.GetReleaseFeed(channel: uniqueSuffix, logger: logger).GetAwaiterResult();
|
||||
var releases = source.GetReleaseFeed(logger.ToVelopackLogger(), null, channel: uniqueSuffix).GetAwaiterResult();
|
||||
|
||||
var ghrel = releases.Assets.Select(r => (GithubSource.GitBaseAsset) r).ToArray();
|
||||
foreach (var g in ghrel) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Runtime.Versioning;
|
||||
using Velopack.Compression;
|
||||
using Velopack.Core;
|
||||
using Velopack.Util;
|
||||
|
||||
namespace Velopack.Packaging.Tests;
|
||||
@@ -32,7 +33,7 @@ public class OsxPackTests
|
||||
TestApp.PackTestApp(id, "0.0.1", string.Empty, tmpReleaseDir, logger, channel: channel, packTitle: title);
|
||||
|
||||
var portablePath = Path.Combine(tmpReleaseDir, $"{id}-{channel}-Portable.zip");
|
||||
EasyZip.ExtractZipToDirectory(logger, portablePath, unzipDir);
|
||||
EasyZip.ExtractZipToDirectory(logger.ToVelopackLogger(), portablePath, unzipDir);
|
||||
|
||||
var bundlePath = Path.Combine(unzipDir, $"{title}.app");
|
||||
Assert.True(Directory.Exists(bundlePath));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#nullable enable
|
||||
using System.Diagnostics;
|
||||
using Velopack.Core;
|
||||
using Velopack.Packaging.Unix.Commands;
|
||||
using Velopack.Packaging.Windows.Commands;
|
||||
using Velopack.Util;
|
||||
|
||||
@@ -79,7 +79,7 @@ public class WindowsPackTests
|
||||
var releasesPath2 = Path.Combine(tmpReleaseDir, $"releases.asd123.json");
|
||||
Assert.True(File.Exists(releasesPath2));
|
||||
|
||||
EasyZip.ExtractZipToDirectory(logger, nupkgPath, unzipDir);
|
||||
EasyZip.ExtractZipToDirectory(logger.ToVelopackLogger(), nupkgPath, unzipDir);
|
||||
|
||||
// does nuspec exist and is it valid
|
||||
var nuspecPath = Path.Combine(unzipDir, $"{id}.nuspec");
|
||||
@@ -310,7 +310,7 @@ public class WindowsPackTests
|
||||
var deltaPath = Path.Combine(releaseDir, $"{id}-2.0.0-delta.nupkg");
|
||||
Assert.True(File.Exists(deltaPath));
|
||||
using var _2 = TempUtil.GetTempDirectory(out var extractDir);
|
||||
EasyZip.ExtractZipToDirectory(logger, deltaPath, extractDir);
|
||||
EasyZip.ExtractZipToDirectory(logger.ToVelopackLogger(), deltaPath, extractDir);
|
||||
var extractDllDiff = Path.Combine(extractDir, "lib", "app", "testapp.dll.zsdiff");
|
||||
var extractDllShasum = Path.Combine(extractDir, "lib", "app", "testapp.dll.shasum");
|
||||
Assert.True(File.Exists(extractDllDiff));
|
||||
@@ -659,7 +659,7 @@ public class WindowsPackTests
|
||||
() => {
|
||||
return File.ReadAllText(path);
|
||||
},
|
||||
logger: logger,
|
||||
logger: logger.ToVelopackLogger(),
|
||||
retries: 10,
|
||||
retryDelay: 1000);
|
||||
}
|
||||
@@ -730,7 +730,7 @@ public class WindowsPackTests
|
||||
},
|
||||
10,
|
||||
1000,
|
||||
logger);
|
||||
logger.ToVelopackLogger());
|
||||
|
||||
using var reader = new StreamReader(fs);
|
||||
var output = reader.ReadToEnd();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
using System.Runtime.Versioning;
|
||||
using Velopack.Core;
|
||||
using Velopack.Locators;
|
||||
using Velopack.Util;
|
||||
using Velopack.Windows;
|
||||
@@ -29,8 +30,16 @@ public class ShortcutTests
|
||||
PathHelper.CopyFixtureTo("AvaloniaCrossPlat-1.0.15-win-full.nupkg", packages.FullName);
|
||||
PathHelper.CopyFixtureTo(exeName, current.FullName);
|
||||
|
||||
var locator = new TestVelopackLocator("AvaloniaCrossPlat", "1.0.0", packages.FullName, current.FullName, rootDir, null, null, logger);
|
||||
var sh = new Shortcuts(logger, locator);
|
||||
var locator = new TestVelopackLocator(
|
||||
"AvaloniaCrossPlat",
|
||||
"1.0.0",
|
||||
packages.FullName,
|
||||
current.FullName,
|
||||
rootDir,
|
||||
null,
|
||||
null,
|
||||
logger.ToVelopackLogger());
|
||||
var sh = new Shortcuts(locator);
|
||||
var flag = ShortcutLocation.StartMenuRoot | ShortcutLocation.Desktop;
|
||||
sh.DeleteShortcuts(exeName, flag);
|
||||
sh.CreateShortcut(exeName, flag, false, "");
|
||||
@@ -54,4 +63,4 @@ public class ShortcutTests
|
||||
var after = sh.FindShortcuts(exeName, flag);
|
||||
Assert.Equal(0, after.Keys.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.IO.Compression;
|
||||
using NCode.ReparsePoints;
|
||||
using Velopack.Compression;
|
||||
using Velopack.Logging;
|
||||
using Velopack.Util;
|
||||
|
||||
namespace Velopack.Tests;
|
||||
@@ -247,7 +248,7 @@ public class SymbolicLinkTests
|
||||
using var _2 = TempUtil.GetTempDirectory(out var tempOutput);
|
||||
var output = Path.Combine(tempOutput, "output.zip");
|
||||
|
||||
await EasyZip.CreateZipFromDirectoryAsync(NullLogger.Instance, output, tempFolder);
|
||||
await EasyZip.CreateZipFromDirectoryAsync(NullVelopackLogger.Instance, output, tempFolder);
|
||||
ZipFile.ExtractToDirectory(output, tempOutput);
|
||||
|
||||
var appSym = Path.Combine(tempOutput, "App.__symlink");
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#pragma warning disable CS0612 // Type or member is obsolete
|
||||
using System.Text;
|
||||
using Velopack.Core;
|
||||
using Velopack.Logging;
|
||||
using Velopack.Sources;
|
||||
using Velopack.Util;
|
||||
|
||||
@@ -25,7 +26,7 @@ internal class FakeFixtureRepository : IFileDownloader
|
||||
.ToList();
|
||||
|
||||
var releasesNew = new SimpleFileSource(new DirectoryInfo(PathHelper.GetFixturesDir()))
|
||||
.GetReleaseFeed(NullLogger.Instance, null).GetAwaiterResult().Assets
|
||||
.GetReleaseFeed(NullVelopackLogger.Instance, null, null).GetAwaiterResult().Assets
|
||||
.Where(r => r.FileName.StartsWith(_pkgId))
|
||||
.ToList();
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ public class UpdateManagerTests
|
||||
{
|
||||
var feed = new VelopackAssetFeed {
|
||||
Assets = new VelopackAsset[] {
|
||||
new VelopackAsset() {
|
||||
new VelopackAsset() {
|
||||
PackageId = "MyCoolApp",
|
||||
Version = new SemanticVersion(1, 1, 0),
|
||||
Type = VelopackAssetType.Full,
|
||||
@@ -81,7 +81,7 @@ public class UpdateManagerTests
|
||||
SHA1 = "14db31d2647c6d2284882a2e101924a9c409ee67",
|
||||
Size = 80396,
|
||||
},
|
||||
new VelopackAsset() {
|
||||
new VelopackAsset() {
|
||||
PackageId = "MyCoolApp",
|
||||
Version = new SemanticVersion(1, 2, 0),
|
||||
Type = VelopackAssetType.Delta,
|
||||
@@ -111,22 +111,24 @@ public class UpdateManagerTests
|
||||
using var logger = _output.BuildLoggerFor<UpdateManagerTests>();
|
||||
using var _1 = TempUtil.GetTempDirectory(out var tempPath);
|
||||
var dl = new FakeDownloader() {
|
||||
MockedResponseBytes = Encoding.UTF8.GetBytes(SimpleJson.SerializeObject(
|
||||
new VelopackAssetFeed {
|
||||
Assets = new VelopackAsset[] {
|
||||
new VelopackAsset() {
|
||||
PackageId = "AvaloniaCrossPlat",
|
||||
Version = new SemanticVersion(1, 0, 11),
|
||||
Type = VelopackAssetType.Full,
|
||||
FileName = $"https://mysite.com/releases/AvaloniaCrossPlat$-1.1.0.nupkg",
|
||||
SHA1 = IoUtil.CalculateFileSHA1(fixture),
|
||||
Size = new FileInfo(fixture).Length,
|
||||
} }
|
||||
}))
|
||||
MockedResponseBytes = Encoding.UTF8.GetBytes(
|
||||
SimpleJson.SerializeObject(
|
||||
new VelopackAssetFeed {
|
||||
Assets = new VelopackAsset[] {
|
||||
new VelopackAsset() {
|
||||
PackageId = "AvaloniaCrossPlat",
|
||||
Version = new SemanticVersion(1, 0, 11),
|
||||
Type = VelopackAssetType.Full,
|
||||
FileName = $"https://mysite.com/releases/AvaloniaCrossPlat$-1.1.0.nupkg",
|
||||
SHA1 = IoUtil.CalculateFileSHA1(fixture),
|
||||
Size = new FileInfo(fixture).Length,
|
||||
}
|
||||
}
|
||||
}))
|
||||
};
|
||||
var source = new SimpleWebSource("http://any.com", dl);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger);
|
||||
var um = new UpdateManager(source, null, logger, locator);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger.ToVelopackLogger());
|
||||
var um = new UpdateManager(source, null, locator);
|
||||
var info = um.CheckForUpdates();
|
||||
Assert.NotNull(info);
|
||||
Assert.True(new SemanticVersion(1, 0, 11) == info.TargetFullRelease.Version);
|
||||
@@ -150,8 +152,8 @@ public class UpdateManagerTests
|
||||
using var _1 = TempUtil.GetTempDirectory(out var tempPath);
|
||||
var dl = GetMockDownloaderNoDelta();
|
||||
var source = new SimpleWebSource("http://any.com", dl);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger);
|
||||
var um = new UpdateManager(source, null, logger, locator);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger.ToVelopackLogger());
|
||||
var um = new UpdateManager(source, null, locator);
|
||||
var info = um.CheckForUpdates();
|
||||
Assert.NotNull(info);
|
||||
Assert.True(new SemanticVersion(1, 1, 0) == info.TargetFullRelease.Version);
|
||||
@@ -167,9 +169,9 @@ public class UpdateManagerTests
|
||||
using var _1 = TempUtil.GetTempDirectory(out var tempPath);
|
||||
var dl = GetMockDownloaderNoDelta();
|
||||
var source = new SimpleWebSource("http://any.com", dl);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger.ToVelopackLogger());
|
||||
var opt = new UpdateOptions { ExplicitChannel = "experimental" };
|
||||
var um = new UpdateManager(source, opt, logger, locator);
|
||||
var um = new UpdateManager(source, opt, locator);
|
||||
var info = um.CheckForUpdates();
|
||||
Assert.NotNull(info);
|
||||
Assert.True(new SemanticVersion(1, 1, 0) == info.TargetFullRelease.Version);
|
||||
@@ -193,23 +195,32 @@ public class UpdateManagerTests
|
||||
Size = 1040561,
|
||||
};
|
||||
var source = new SimpleWebSource("http://any.com", dl);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.2.0", tempPath, null, null, null, logger: logger, localPackage: myVer, channel: "stable");
|
||||
var locator = new TestVelopackLocator(
|
||||
"MyCoolApp",
|
||||
"1.2.0",
|
||||
tempPath,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
logger: logger.ToVelopackLogger(),
|
||||
localPackage: myVer,
|
||||
channel: "stable");
|
||||
|
||||
// checking for same version should return null
|
||||
var um = new UpdateManager(source, null, logger, locator);
|
||||
var um = new UpdateManager(source, null, locator);
|
||||
var info = um.CheckForUpdates();
|
||||
Assert.Null(info);
|
||||
Assert.StartsWith("http://any.com/releases.stable.json?", dl.LastUrl);
|
||||
|
||||
// checking for same version WITHOUT explicit channel should return null
|
||||
var opt = new UpdateOptions { AllowVersionDowngrade = true };
|
||||
um = new UpdateManager(source, opt, logger, locator);
|
||||
um = new UpdateManager(source, opt, locator);
|
||||
Assert.Null(info);
|
||||
Assert.StartsWith("http://any.com/releases.stable.json?", dl.LastUrl);
|
||||
|
||||
// checking for same version with explicit channel & downgrade allowed should return version
|
||||
opt = new UpdateOptions { ExplicitChannel = "experimental", AllowVersionDowngrade = true };
|
||||
um = new UpdateManager(source, opt, logger, locator);
|
||||
um = new UpdateManager(source, opt, locator);
|
||||
info = um.CheckForUpdates();
|
||||
Assert.True(info.IsDowngrade);
|
||||
Assert.NotNull(info);
|
||||
@@ -233,17 +244,26 @@ public class UpdateManagerTests
|
||||
Size = 1040561,
|
||||
};
|
||||
var source = new SimpleWebSource("http://any.com", dl);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "2.0.0", tempPath, null, null, null, logger: logger, localPackage: myVer, channel: "stable");
|
||||
var locator = new TestVelopackLocator(
|
||||
"MyCoolApp",
|
||||
"2.0.0",
|
||||
tempPath,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
logger: logger.ToVelopackLogger(),
|
||||
localPackage: myVer,
|
||||
channel: "stable");
|
||||
|
||||
// checking for lower version should return null
|
||||
var um = new UpdateManager(source, null, logger, locator);
|
||||
var um = new UpdateManager(source, null, locator);
|
||||
var info = um.CheckForUpdates();
|
||||
Assert.Null(info);
|
||||
Assert.StartsWith("http://any.com/releases.stable.json?", dl.LastUrl);
|
||||
|
||||
// checking for lower version with downgrade allowed should return lower version
|
||||
var opt = new UpdateOptions { AllowVersionDowngrade = true };
|
||||
um = new UpdateManager(source, opt, logger, locator);
|
||||
um = new UpdateManager(source, opt, locator);
|
||||
info = um.CheckForUpdates();
|
||||
Assert.True(info.IsDowngrade);
|
||||
Assert.NotNull(info);
|
||||
@@ -268,8 +288,8 @@ public class UpdateManagerTests
|
||||
};
|
||||
var source = new SimpleWebSource("http://any.com", dl);
|
||||
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, null, null, null, logger: logger, localPackage: myVer);
|
||||
var um = new UpdateManager(source, null, logger, locator);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, null, null, null, logger: logger.ToVelopackLogger(), localPackage: myVer);
|
||||
var um = new UpdateManager(source, null, locator);
|
||||
var info = um.CheckForUpdates();
|
||||
Assert.False(info.IsDowngrade);
|
||||
Assert.NotNull(info);
|
||||
@@ -287,8 +307,8 @@ public class UpdateManagerTests
|
||||
using var _1 = TempUtil.GetTempDirectory(out var packagesDir);
|
||||
var repo = new FakeFixtureRepository(id, false);
|
||||
var source = new SimpleWebSource("http://any.com", repo);
|
||||
var locator = new TestVelopackLocator(id, "1.0.0", packagesDir, logger);
|
||||
var um = new UpdateManager(source, null, logger, locator);
|
||||
var locator = new TestVelopackLocator(id, "1.0.0", packagesDir, logger.ToVelopackLogger());
|
||||
var um = new UpdateManager(source, null, locator);
|
||||
|
||||
var info = um.CheckForUpdates();
|
||||
Assert.NotNull(info);
|
||||
@@ -298,7 +318,7 @@ public class UpdateManagerTests
|
||||
string actualHash = info.TargetFullRelease.SHA256;
|
||||
string modifiedHash = info.TargetFullRelease.SHA256.ToLowerInvariant();
|
||||
info.TargetFullRelease.SHA256 = modifiedHash;
|
||||
|
||||
|
||||
var ex = Assert.Throws<ChecksumFailedException>(() => um.DownloadUpdates(info));
|
||||
|
||||
Assert.Contains("SHA256 doesn't match", ex.Message);
|
||||
@@ -321,8 +341,8 @@ public class UpdateManagerTests
|
||||
using var _1 = TempUtil.GetTempDirectory(out var packagesDir);
|
||||
var repo = new FakeFixtureRepository(id, false);
|
||||
var source = new SimpleWebSource("http://any.com", repo);
|
||||
var locator = new TestVelopackLocator(id, "1.0.0", packagesDir, logger);
|
||||
var um = new UpdateManager(source, null, logger, locator);
|
||||
var locator = new TestVelopackLocator(id, "1.0.0", packagesDir, logger.ToVelopackLogger());
|
||||
var um = new UpdateManager(source, null, locator);
|
||||
|
||||
var info = um.CheckForUpdates();
|
||||
Assert.NotNull(info);
|
||||
@@ -352,8 +372,8 @@ public class UpdateManagerTests
|
||||
using var _1 = TempUtil.GetTempDirectory(out var tempPath);
|
||||
var dl = GetMockDownloaderWith2Delta();
|
||||
var source = new SimpleWebSource("http://any.com", dl);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger: logger);
|
||||
var um = new UpdateManager(source, null, logger, locator);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger: logger.ToVelopackLogger());
|
||||
var um = new UpdateManager(source, null, locator);
|
||||
var info = um.CheckForUpdates();
|
||||
Assert.NotNull(info);
|
||||
Assert.False(info.IsDowngrade);
|
||||
@@ -368,8 +388,8 @@ public class UpdateManagerTests
|
||||
using var _1 = TempUtil.GetTempDirectory(out var tempPath);
|
||||
var dl = GetMockDownloaderWith2Delta();
|
||||
var source = new SimpleWebSource("http://any.com", dl);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger: logger);
|
||||
var um = new UpdateManager(source, null, logger, locator);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger: logger.ToVelopackLogger());
|
||||
var um = new UpdateManager(source, null, locator);
|
||||
var info = um.CheckForUpdates();
|
||||
Assert.NotNull(info);
|
||||
Assert.False(info.IsDowngrade);
|
||||
@@ -383,48 +403,51 @@ public class UpdateManagerTests
|
||||
// https://github.com/caesay/SquirrelCustomLauncherTestApp
|
||||
using var logger = _output.BuildLoggerFor<UpdateManagerTests>();
|
||||
using var _1 = TempUtil.GetTempDirectory(out var tempPath);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger.ToVelopackLogger());
|
||||
var source = new GithubSource("https://github.com/caesay/SquirrelCustomLauncherTestApp", null, false);
|
||||
var um = new UpdateManager(source, null, logger, locator);
|
||||
var um = new UpdateManager(source, null, locator);
|
||||
var info = um.CheckForUpdates();
|
||||
Assert.NotNull(info);
|
||||
Assert.True(new SemanticVersion(1, 0, 1) == info.TargetFullRelease.Version);
|
||||
Assert.Equal(0, info.DeltasToTarget.Count());
|
||||
}
|
||||
|
||||
[Fact(Skip = "Consumes API Quota")]
|
||||
public void CheckGithubWithNonExistingChannel()
|
||||
{
|
||||
// https://github.com/caesay/SquirrelCustomLauncherTestApp
|
||||
using var logger = _output.BuildLoggerFor<UpdateManagerTests>();
|
||||
using var _1 = TempUtil.GetTempDirectory(out var tempPath);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger.ToVelopackLogger());
|
||||
var source = new GithubSource("https://github.com/caesay/SquirrelCustomLauncherTestApp", null, false);
|
||||
var opt = new UpdateOptions { ExplicitChannel = "hello" };
|
||||
var um = new UpdateManager(source, opt, logger, locator);
|
||||
var um = new UpdateManager(source, opt, locator);
|
||||
Assert.Throws<ArgumentException>(() => um.CheckForUpdates());
|
||||
}
|
||||
|
||||
[Fact(Skip = "Consumes API Quota")]
|
||||
public void CheckGitea()
|
||||
{
|
||||
// https://github.com/caesay/SquirrelCustomLauncherTestApp
|
||||
using var logger = _output.BuildLoggerFor<UpdateManagerTests>();
|
||||
using var _1 = TempUtil.GetTempDirectory(out var tempPath);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger.ToVelopackLogger());
|
||||
var source = new GiteaSource("https://gitea.com/remco1271/VeloPackTest", null, false);
|
||||
var um = new UpdateManager(source, null, logger, locator);
|
||||
var um = new UpdateManager(source, null, locator);
|
||||
var info = um.CheckForUpdates();
|
||||
Assert.NotNull(info);
|
||||
Assert.True(new SemanticVersion(1, 0, 1) == info.TargetFullRelease.Version);
|
||||
Assert.Equal(0, info.DeltasToTarget.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CheckFromEmptyFileSource()
|
||||
{
|
||||
using var logger = _output.BuildLoggerFor<UpdateManagerTests>();
|
||||
using var _1 = TempUtil.GetTempDirectory(out var tempPath);
|
||||
var source = new SimpleFileSource(new DirectoryInfo(tempPath));
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger);
|
||||
var um = new UpdateManager(source, null, logger, locator);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger.ToVelopackLogger());
|
||||
var um = new UpdateManager(source, null, locator);
|
||||
var info = um.CheckForUpdates();
|
||||
Assert.Null(info);
|
||||
}
|
||||
@@ -436,8 +459,8 @@ public class UpdateManagerTests
|
||||
using var _1 = TempUtil.GetTempDirectory(out var tempPath);
|
||||
var dl = GetMockDownloaderNoDelta();
|
||||
var source = new SimpleWebSource("http://any.com", dl);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.1.0", tempPath, logger);
|
||||
var um = new UpdateManager(source, null, logger, locator);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.1.0", tempPath, logger.ToVelopackLogger());
|
||||
var um = new UpdateManager(source, null, locator);
|
||||
var info = um.CheckForUpdates();
|
||||
Assert.Null(info);
|
||||
}
|
||||
@@ -449,8 +472,8 @@ public class UpdateManagerTests
|
||||
using var _1 = TempUtil.GetTempDirectory(out var tempPath);
|
||||
var dl = GetMockDownloaderNoDelta();
|
||||
var source = new SimpleWebSource("http://any.com", dl);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.2.0", tempPath, logger);
|
||||
var um = new UpdateManager(source, null, logger, locator);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.2.0", tempPath, logger.ToVelopackLogger());
|
||||
var um = new UpdateManager(source, null, locator);
|
||||
var info = um.CheckForUpdates();
|
||||
Assert.Null(info);
|
||||
}
|
||||
@@ -464,8 +487,8 @@ public class UpdateManagerTests
|
||||
using var _1 = TempUtil.GetTempDirectory(out var packagesDir);
|
||||
var repo = new FakeFixtureRepository(id, false);
|
||||
var source = new SimpleWebSource("http://any.com", repo);
|
||||
var locator = new TestVelopackLocator(id, "1.0.0", packagesDir, logger);
|
||||
var um = new UpdateManager(source, null, logger, locator);
|
||||
var locator = new TestVelopackLocator(id, "1.0.0", packagesDir, logger.ToVelopackLogger());
|
||||
var um = new UpdateManager(source, null, locator);
|
||||
|
||||
var info = um.CheckForUpdates();
|
||||
Assert.NotNull(info);
|
||||
@@ -490,7 +513,7 @@ public class UpdateManagerTests
|
||||
var repo = new FakeFixtureRepository(id, true);
|
||||
var source = new SimpleWebSource("http://any.com", repo);
|
||||
|
||||
var feed = await source.GetReleaseFeed(logger, VelopackRuntimeInfo.SystemOs.GetOsShortName());
|
||||
var feed = await source.GetReleaseFeed(logger.ToVelopackLogger(), id, VelopackRuntimeInfo.SystemOs.GetOsShortName());
|
||||
var basePkg = feed.Assets
|
||||
.Where(x => x.Type == VelopackAssetType.Full)
|
||||
.Single(x => x.Version == SemanticVersion.Parse(fromVersion));
|
||||
@@ -499,9 +522,16 @@ public class UpdateManagerTests
|
||||
File.Copy(basePkgFixturePath, basePkgPath);
|
||||
|
||||
var updateExe = PathHelper.CopyUpdateTo(packagesDir);
|
||||
var locator = new TestVelopackLocator(id, fromVersion,
|
||||
packagesDir, null, null, updateExe, null, logger);
|
||||
var um = new UpdateManager(source, null, logger, locator);
|
||||
var locator = new TestVelopackLocator(
|
||||
id,
|
||||
fromVersion,
|
||||
packagesDir,
|
||||
null,
|
||||
null,
|
||||
updateExe,
|
||||
null,
|
||||
logger.ToVelopackLogger());
|
||||
var um = new UpdateManager(source, null, locator);
|
||||
|
||||
var info = await um.CheckForUpdatesAsync();
|
||||
Assert.NotNull(info);
|
||||
@@ -513,4 +543,4 @@ public class UpdateManagerTests
|
||||
var target = Path.Combine(packagesDir, $"{id}-{toVersion}-full.nupkg");
|
||||
Assert.True(File.Exists(target));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Runtime.Versioning;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Velopack.Core;
|
||||
using Velopack.Util;
|
||||
using Velopack.Windows;
|
||||
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
</Choose>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\src\vpk\Velopack.Core\SimpleJson.cs" Link="SimpleJson.cs" />
|
||||
<PackageReference Include="System.IO.Packaging" Version="9.0.2"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.IO.Packaging" Version="9.0.2"/>
|
||||
<ProjectReference Include="..\..\src\vpk\Velopack.Core\Velopack.Core.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" $(TargetFramework.StartsWith('net4')) ">
|
||||
@@ -45,5 +45,5 @@
|
||||
</ItemGroup>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.IO.Packaging;
|
||||
using NuGet.Versioning;
|
||||
using Velopack.Core;
|
||||
using Velopack.NuGet;
|
||||
using Velopack.Tests.TestHelpers;
|
||||
using Velopack.Util;
|
||||
@@ -38,8 +39,8 @@ public class ZipPackageTests
|
||||
SymbolicLink.Create(symlink, actual);
|
||||
SymbolicLink.Create(symfile, actualFile);
|
||||
|
||||
Compression.EasyZip.CreateZipFromDirectoryAsync(logger, zipFile, tempDir).GetAwaiterResult();
|
||||
Compression.EasyZip.ExtractZipToDirectory(logger, zipFile, extractedDir, expandSymlinks: true);
|
||||
Compression.EasyZip.CreateZipFromDirectoryAsync(logger.ToVelopackLogger(), zipFile, tempDir).GetAwaiterResult();
|
||||
Compression.EasyZip.ExtractZipToDirectory(logger.ToVelopackLogger(), zipFile, extractedDir, expandSymlinks: true);
|
||||
|
||||
Assert.True(File.Exists(Path.Combine(extractedDir, "actual", "file.txt")));
|
||||
Assert.Equal("hello", File.ReadAllText(Path.Combine(extractedDir, "actual", "file.txt")));
|
||||
|
||||
Reference in New Issue
Block a user