Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

Commit

Permalink
Fix .pkg generation so it properly installs to home dir
Browse files Browse the repository at this point in the history
  • Loading branch information
caesay committed Jun 20, 2022
1 parent 6abdeb1 commit e148207
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 28 deletions.
21 changes: 3 additions & 18 deletions src/Squirrel.CommandLine/OSX/Commands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ private static void Pack(PackOptions options)
Log.Info("Copying app to release directory");
if (Directory.Exists(appBundlePath)) Utility.DeleteFileOrDirectoryHard(appBundlePath);
Directory.CreateDirectory(appBundlePath);
CopyFiles(new DirectoryInfo(options.packDirectory), new DirectoryInfo(appBundlePath));
Utility.CopyFiles(new DirectoryInfo(options.packDirectory), new DirectoryInfo(appBundlePath));
} else {
Log.Info("Pack directory is not a bundle. Will generate new '.app' bundle from a directory of application files.");

Expand Down Expand Up @@ -98,7 +98,7 @@ private static void Pack(PackOptions options)
File.Copy(options.icon, Path.Combine(builder.ResourcesDirectory, Path.GetFileName(options.icon)));

Log.Info("Copying application files into new '.app' bundle");
CopyFiles(new DirectoryInfo(options.packDirectory), new DirectoryInfo(builder.MacosDirectory));
Utility.CopyFiles(new DirectoryInfo(options.packDirectory), new DirectoryInfo(builder.MacosDirectory));

appBundlePath = builder.AppDirectory;
}
Expand Down Expand Up @@ -133,7 +133,7 @@ private static void Pack(PackOptions options)
HelperExe.CreateDittoZip(appBundlePath, zipPath);
HelperExe.Notarize(zipPath, options.notaryProfile);
HelperExe.Staple(appBundlePath);

// re-create the zip from the app with the stapled notarization
File.Delete(zipPath);
HelperExe.CreateDittoZip(appBundlePath, zipPath);
Expand Down Expand Up @@ -181,20 +181,5 @@ private static void Pack(PackOptions options)

Log.Info("Done.");
}

private static void CopyFiles(DirectoryInfo source, DirectoryInfo target)
{
Directory.CreateDirectory(target.FullName);

foreach (var fileInfo in source.GetFiles()) {
var path = Path.Combine(target.FullName, fileInfo.Name);
fileInfo.CopyTo(path, true);
}

foreach (var sourceSubDir in source.GetDirectories()) {
var targetSubDir = target.CreateSubdirectory(sourceSubDir.Name);
CopyFiles(sourceSubDir, targetSubDir);
}
}
}
}
53 changes: 43 additions & 10 deletions src/Squirrel.CommandLine/OSX/HelperExe.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Versioning;
using System.Threading;
using Newtonsoft.Json;
Expand Down Expand Up @@ -52,22 +53,54 @@ public static void CreateInstallerPkg(string appBundlePath, string pkgOutputPath
{
Log.Info($"Creating installer '.pkg' for app at '{appBundlePath}'");

var args = new List<string> {
"--install-location", "~/Applications",
"--component", appBundlePath,
using var _1 = Utility.GetTempDirectory(out var tmp);
using var _2 = Utility.GetTempDirectory(out var tmpPayload1);
using var _3 = Utility.GetTempDirectory(out var tmpPayload2);

// copy .app to tmp folder
var bundleName = Path.GetFileName(appBundlePath);
var tmpBundlePath = Path.Combine(tmpPayload1, bundleName);
Utility.CopyFiles(new DirectoryInfo(appBundlePath), new DirectoryInfo(tmpBundlePath));

// generate non-relocatable pkg
var pkgPlistPath = Path.Combine(tmp, "tmp.plist");
InvokeAndThrowIfNonZero("pkgbuild", new[] { "--analyze", "--root", tmpPayload1, pkgPlistPath }, null);
InvokeAndThrowIfNonZero("plutil", new[] { "-replace", "BundleIsRelocatable", "-bool", "NO", pkgPlistPath }, null);

var pkg1Path = Path.Combine(tmpPayload2, "1.pkg");
string[] args1 = {
"--root", tmpPayload1,
"--component-plist", pkgPlistPath,
"--install-location", "/Applications",
pkg1Path,
};

InvokeAndThrowIfNonZero("pkgbuild", args1, null);

// create product package that installs to home dir
var distributionPath = Path.Combine(tmp, "distribution.xml");
InvokeAndThrowIfNonZero("productbuild", new[] { "--synthesize", "--package", pkg1Path, distributionPath }, null);

// disable local system installation and build final package
var distXml = File.ReadAllLines(distributionPath).ToList();
distXml.Insert(2, "<domains enable_anywhere=\"false\" enable_currentUserHome=\"true\" enable_localSystem=\"false\" />");
File.WriteAllLines(distributionPath, distXml);

List<string> args2 = new () {
"--distribution", distributionPath,
"--package-path", tmpPayload2,
pkgOutputPath
};

if (!String.IsNullOrEmpty(signIdentity)) {
args.Add("--sign");
args.Add(signIdentity);
args2.Add("--sign");
args2.Add(signIdentity);
} else {
Log.Warn("No Installer signing identity provided. The '.pkg' will not be signed.");
}

args.Add(pkgOutputPath);

InvokeAndThrowIfNonZero("pkgbuild", args, null);


InvokeAndThrowIfNonZero("productbuild", args2, null);

Log.Info("Installer created successfully");
}

Expand Down
15 changes: 15 additions & 0 deletions src/Squirrel/Internal/Utility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -781,5 +781,20 @@ public static NuspecManifest ReadManifestFromVersionDir(string appVersionDir)

return null;
}

public static void CopyFiles(DirectoryInfo source, DirectoryInfo target)
{
Directory.CreateDirectory(target.FullName);

foreach (var fileInfo in source.GetFiles()) {
var path = Path.Combine(target.FullName, fileInfo.Name);
fileInfo.CopyTo(path, true);
}

foreach (var sourceSubDir in source.GetDirectories()) {
var targetSubDir = target.CreateSubdirectory(sourceSubDir.Name);
CopyFiles(sourceSubDir, targetSubDir);
}
}
}
}

0 comments on commit e148207

Please sign in to comment.