From eabae746633346fa1a3fd4b7107a25603afcadb3 Mon Sep 17 00:00:00 2001 From: Caelan Sayler Date: Sun, 20 Oct 2024 20:05:11 +0100 Subject: [PATCH] Extract .pkg files automatically via --packDir --- .../Commands/OsxPackCommandRunner.cs | 16 ++++++++-- .../Velopack.Packaging.Unix/OsxBuildTools.cs | 29 +++++++++++++++++++ src/vpk/Velopack.Packaging/PackageBuilder.cs | 11 +++++-- src/vpk/Velopack.Vpk/Commands/_PackCommand.cs | 7 ++--- 4 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/vpk/Velopack.Packaging.Unix/Commands/OsxPackCommandRunner.cs b/src/vpk/Velopack.Packaging.Unix/Commands/OsxPackCommandRunner.cs index 543f28ad..b0275e30 100644 --- a/src/vpk/Velopack.Packaging.Unix/Commands/OsxPackCommandRunner.cs +++ b/src/vpk/Velopack.Packaging.Unix/Commands/OsxPackCommandRunner.cs @@ -13,13 +13,25 @@ public class OsxPackCommandRunner : PackageBuilder { } + protected override string ExtractPackDir(string packDirectory) + { + if (packDirectory.EndsWith(".pkg", StringComparison.OrdinalIgnoreCase)) { + Log.Warn("Extracting application bundle from .pkg installer. This is not recommended for production use."); + var dir = Path.Combine(TempDir.FullName, "pkg_extract"); + var helper = new OsxBuildTools(Log); + return helper.ExtractPkgToAppBundle(packDirectory, dir); + } + + return packDirectory; + } + protected override Task PreprocessPackDir(Action progress, string packDir) { var packTitle = Options.PackTitle ?? Options.PackId; var dir = TempDir.CreateSubdirectory(packTitle + ".app"); bool deleteAppBundle = false; - string appBundlePath = Options.PackDirectory; - if (!Options.PackDirectory.EndsWith(".app", StringComparison.OrdinalIgnoreCase)) { + string appBundlePath = packDir; + if (!packDir.EndsWith(".app", StringComparison.OrdinalIgnoreCase)) { appBundlePath = new OsxBundleCommandRunner(Log).Bundle(Options); deleteAppBundle = true; } diff --git a/src/vpk/Velopack.Packaging.Unix/OsxBuildTools.cs b/src/vpk/Velopack.Packaging.Unix/OsxBuildTools.cs index a115c420..f8babeca 100644 --- a/src/vpk/Velopack.Packaging.Unix/OsxBuildTools.cs +++ b/src/vpk/Velopack.Packaging.Unix/OsxBuildTools.cs @@ -262,4 +262,33 @@ exit 0 Log.Debug($"Creating ditto bundle '{outputZip}'"); Log.Debug(Exe.InvokeAndThrowIfNonZero("ditto", args, null)); } + + public string ExtractPkgToAppBundle(string pkgFile, string extractionTmpPath) + { + if (!File.Exists(pkgFile)) { + throw new ArgumentException("Package file does not exist: " + pkgFile); + } + + Log.Debug($"Extracting '{pkgFile}' to '{extractionTmpPath}'"); + + var args = new List { + "--expand-full", + pkgFile, + extractionTmpPath, + }; + + Log.Debug(Exe.InvokeAndThrowIfNonZero("pkgutil", args, null)); + + IEnumerable appPaths = Directory.EnumerateDirectories(extractionTmpPath, "*.app", SearchOption.AllDirectories).ToArray(); + + if (appPaths.Count() > 1) { + throw new Exception("The package contains more than one .app bundle. This is not supported."); + } + + if (!appPaths.Any()) { + throw new Exception("The package does not contain an .app bundle."); + } + + return appPaths.First(); + } } \ No newline at end of file diff --git a/src/vpk/Velopack.Packaging/PackageBuilder.cs b/src/vpk/Velopack.Packaging/PackageBuilder.cs index 758a8f9f..1da9b7fa 100644 --- a/src/vpk/Velopack.Packaging/PackageBuilder.cs +++ b/src/vpk/Velopack.Packaging/PackageBuilder.cs @@ -64,11 +64,17 @@ public abstract class PackageBuilder : ICommand throw new UserInfoException($"There is a release in channel {channel} which is equal or greater to the current version {options.PackVersion}. Please increase the current package version or remove that release."); } } + + using var _1 = TempUtil.GetTempDirectory(out var pkgTempDir); + TempDir = new DirectoryInfo(pkgTempDir); var packId = options.PackId; var packDirectory = options.PackDirectory; var packVersion = options.PackVersion; + // extract pre-bundled apps as required (eg. .AppImage or .pkg) + packDirectory = ExtractPackDir(packDirectory); + // check that entry exe exists var mainExeName = options.EntryExecutableName ?? options.PackId; var mainSearchPaths = GetMainExeSearchPaths(packDirectory, mainExeName); @@ -90,9 +96,6 @@ public abstract class PackageBuilder : ICommand MainExePath = mainExePath; options.EntryExecutableName = Path.GetFileName(mainExePath); - - using var _1 = TempUtil.GetTempDirectory(out var pkgTempDir); - TempDir = new DirectoryInfo(pkgTempDir); Options = options; ConcurrentBag<(string from, string to)> filesToCopy = new(); @@ -170,6 +173,8 @@ public abstract class PackageBuilder : ICommand }); } + protected virtual string ExtractPackDir(string packDirectory) => packDirectory; + protected abstract string[] GetMainExeSearchPaths(string packDirectory, string mainExeName); protected virtual string GenerateNuspecContent() diff --git a/src/vpk/Velopack.Vpk/Commands/_PackCommand.cs b/src/vpk/Velopack.Vpk/Commands/_PackCommand.cs index 0d03a22b..012e6895 100644 --- a/src/vpk/Velopack.Vpk/Commands/_PackCommand.cs +++ b/src/vpk/Velopack.Vpk/Commands/_PackCommand.cs @@ -15,7 +15,7 @@ public abstract class PackCommand : PlatformCommand public string PackDirectory { get; private set; } - protected CliOption PackDirectoryOption { get; private set; } + protected CliOption PackDirectoryOption { get; private set; } public string PackAuthors { get; private set; } @@ -69,11 +69,10 @@ public abstract class PackCommand : PlatformCommand .SetRequired() .RequiresSemverCompliant(); - PackDirectoryOption = AddOption((v) => PackDirectory = v.ToFullNameOrNull(), "--packDir", "-p") + PackDirectoryOption = AddOption((v) => PackDirectory = v.ToFullNameOrNull(), "--packDir", "-p") .SetDescription("Directory containing application files for release.") .SetArgumentHelpName("DIR") - .SetRequired() - .MustNotBeEmpty(); + .SetRequired(); PackAuthorsOption = AddOption((v) => PackAuthors = v, "--packAuthors") .SetDescription("Company name or comma-delimited list of authors.")