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

Commit

Permalink
Refactor ZipPackage to expose more relevant simplified data
Browse files Browse the repository at this point in the history
  • Loading branch information
caesay committed Jan 6, 2022
1 parent ecea6e1 commit 4cb937b
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 99 deletions.
11 changes: 5 additions & 6 deletions src/Squirrel/Internal/HelperExe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,17 +130,16 @@ public static async Task SetExeIcon(string exePath, string iconPath)
}
}

public static async Task SetPEVersionBlockFromPackageInfo(string exePath, Squirrel.NuGet.IPackage package, string iconPath = null)
public static async Task SetPEVersionBlockFromPackageInfo(string exePath, NuGet.IPackage package, string iconPath = null)
{
var realExePath = Path.GetFullPath(exePath);
var company = String.Join(",", package.Authors);

List<string> args = new List<string>() {
realExePath,
"--set-version-string", "CompanyName", company,
"--set-version-string", "LegalCopyright", package.Copyright ?? "Copyright © " + DateTime.Now.Year.ToString() + " " + company,
"--set-version-string", "FileDescription", package.Summary ?? package.Description ?? "Installer for " + package.Id,
"--set-version-string", "ProductName", package.Description ?? package.Summary ?? package.Id,
"--set-version-string", "CompanyName", package.ProductCompany,
"--set-version-string", "LegalCopyright", package.ProductCopyright,
"--set-version-string", "FileDescription", package.ProductDescription,
"--set-version-string", "ProductName", package.ProductName,
"--set-file-version", package.Version.ToString(),
"--set-product-version", package.Version.ToString(),
};
Expand Down
2 changes: 1 addition & 1 deletion src/Squirrel/Internal/ReleasePackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ internal string CreateReleasePackage(string outputFile, Func<string, string> rel
// we can tell from here what platform(s) the package targets
// but given this is a simple package we only
// ever expect one entry here (crash hard otherwise)
var frameworks = package.GetSupportedFrameworks();
var frameworks = package.GetFrameworks();
if (frameworks.Count() > 1) {
var platforms = frameworks
.Aggregate(new StringBuilder(), (sb, f) => sb.Append(f.ToString() + "; "));
Expand Down
117 changes: 69 additions & 48 deletions src/Squirrel/NuGet/ZipPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,46 @@ namespace Squirrel.NuGet
internal interface IPackage
{
string Id { get; }
string Description { get; }
IEnumerable<string> Authors { get; }
string Title { get; }
string Summary { get; }
string ProductName { get; }
string ProductDescription { get; }
string ProductCompany { get; }
string ProductCopyright { get; }
string Language { get; }
string Copyright { get; }
SemanticVersion Version { get; }
IEnumerable<FrameworkAssemblyReference> FrameworkAssemblies { get; }
IEnumerable<PackageDependencySet> DependencySets { get; }
Uri ProjectUrl { get; }
string ReleaseNotes { get; }
Uri IconUrl { get; }
IEnumerable<FrameworkAssemblyReference> FrameworkAssemblies { get; }
IEnumerable<PackageDependencySet> DependencySets { get; }
SemanticVersion Version { get; }
IEnumerable<string> GetSupportedFrameworks();
IEnumerable<IPackageFile> GetLibFiles();
string GetFullName();
string[] GetFrameworks();
Stream ReadLibFileStream(string fileName);
}

internal class ZipPackage : IPackage
{
public string ProductName => Title ?? Id;
public string ProductDescription => Description ?? Summary ?? Title ?? Id;
public string ProductCompany => (Authors.Any() ? String.Join(", ", Authors) : Owners) ?? ProductName;
public string ProductCopyright => Copyright ?? "Copyright © " + DateTime.Now.Year.ToString() + " " + ProductCompany;

public string Id { get; private set; }
public string Description { get; private set; }
public IEnumerable<string> Authors { get; private set; } = Enumerable.Empty<string>();
public string Title { get; private set; }
public string Summary { get; private set; }
public string Language { get; private set; }
public string Copyright { get; private set; }
public SemanticVersion Version { get; private set; }
public IEnumerable<FrameworkAssemblyReference> FrameworkAssemblies { get; private set; } = Enumerable.Empty<FrameworkAssemblyReference>();
public IEnumerable<PackageDependencySet> DependencySets { get; private set; } = Enumerable.Empty<PackageDependencySet>();
public Uri ProjectUrl { get; private set; }
public string ReleaseNotes { get; private set; }
public Uri IconUrl { get; private set; }
public string Language { get; private set; }

protected string Description { get; private set; }
protected IEnumerable<string> Authors { get; private set; } = Enumerable.Empty<string>();
protected string Owners { get; private set; }
protected string Title { get; private set; }
protected string Summary { get; private set; }
protected string Copyright { get; private set; }

private readonly Func<Stream> _streamFactory;
private static readonly string[] ExcludePaths = new[] { "_rels", "package" };
private const string ManifestRelationType = "manifest";

public ZipPackage(string filePath)
{
Expand All @@ -58,23 +62,41 @@ public ZipPackage(string filePath)
EnsureManifest();
}

public IEnumerable<string> GetSupportedFrameworks()
public string[] GetFrameworks()
{
using var stream = _streamFactory();
using var zip = ZipArchive.Open(stream);

var fileFrameworks = GetPackageFiles(zip)
.Select(z => VersionUtility.ParseFrameworkNameFromFilePath(z.Path, out var _));

return FrameworkAssemblies
.SelectMany(f => f.SupportedFrameworks)
.Concat(fileFrameworks)
.Where(f => f != null)
.Distinct()
.ToArray();
}

public Stream ReadLibFileStream(string fileName)
{
using var stream = _streamFactory();
using var zip = ZipArchive.Open(stream);

var fileFrameworks = from entries in zip.Entries
where !entries.IsDirectory
let uri = new Uri(entries.Key, UriKind.Relative)
let path = UriUtility.GetPath(uri)
where IsPackageFile(path)
select VersionUtility.ParseFrameworkNameFromFilePath(path, out var effectivePath);

return FrameworkAssemblies.SelectMany(f => f.SupportedFrameworks)
.Concat(fileFrameworks)
.Where(f => f != null)
.Distinct()
.ToArray();
string folderPrefix = Constants.LibDirectory + Path.DirectorySeparatorChar;
var files = GetPackageFiles(zip)
.Where(z => z.Path.StartsWith(folderPrefix, StringComparison.OrdinalIgnoreCase))
.Where(z => Path.GetFileName(z.Path).Equals(fileName, StringComparison.OrdinalIgnoreCase));

if (!files.Any()) {
return null;
}

var f = files.First();
using var fstream = f.Entry.OpenEntryStream();
var ms = new MemoryStream();
fstream.CopyTo(ms);
return ms;
}

public IEnumerable<IPackageFile> GetLibFiles()
Expand All @@ -93,24 +115,23 @@ public IEnumerable<IPackageFile> GetFiles(string directory)
return GetFiles().Where(file => file.Path.StartsWith(folderPrefix, StringComparison.OrdinalIgnoreCase));
}

public List<IPackageFile> GetFiles()
public IEnumerable<IPackageFile> GetFiles()
{
using var stream = _streamFactory();
using var zip = ZipArchive.Open(stream);

var files = from entries in zip.Entries
where !entries.IsDirectory
let uri = new Uri(entries.Key, UriKind.Relative)
let path = UriUtility.GetPath(uri)
where IsPackageFile(path)
select (IPackageFile) new ZipPackageFile(path, entries);

return files.ToList();
return GetPackageFiles(zip)
.Select(z => (IPackageFile) new ZipPackageFile(z.Path))
.ToArray();
}

public string GetFullName()
private IEnumerable<(string Path, ZipArchiveEntry Entry)> GetPackageFiles(ZipArchive zip)
{
return Id + " " + Version;
return from entry in zip.Entries
where !entry.IsDirectory
let uri = new Uri(entry.Key, UriKind.Relative)
let path = UriUtility.GetPath(uri)
where IsPackageFile(path)
select (path, entry);
}

private void EnsureManifest()
Expand All @@ -128,7 +149,7 @@ private void EnsureManifest()
ReadManifest(manifestStream);
}

void ReadManifest(Stream manifestStream)
private void ReadManifest(Stream manifestStream)
{
var document = XmlUtility.LoadSafe(manifestStream, ignoreWhiteSpace: true);

Expand Down Expand Up @@ -169,9 +190,9 @@ private void ReadMetadataValue(XElement element, HashSet<string> allElements)
case "authors":
Authors = value?.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()) ?? Enumerable.Empty<string>();
break;
//case "owners":
// Owners = value;
// break;
case "owners":
Owners = value;
break;
//case "licenseUrl":
// LicenseUrl = value;
// break;
Expand Down Expand Up @@ -285,7 +306,7 @@ private IEnumerable<string> ParseFrameworkNames(string frameworkNames)
.Select(VersionUtility.ParseFrameworkName);
}

bool IsPackageFile(string partPath)
private bool IsPackageFile(string partPath)
{
if (Path.GetFileName(partPath).Equals(ContentType.ContentTypeFileName, StringComparison.OrdinalIgnoreCase))
return false;
Expand Down
21 changes: 1 addition & 20 deletions src/Squirrel/NuGet/ZipPackageFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,15 @@ internal interface IPackageFile : IFrameworkTargetable
string Path { get; }
string EffectivePath { get; }
string TargetFramework { get; }
Stream GetStream();
}

internal class ZipPackageFile : IPackageFile, IEquatable<ZipPackageFile>
{
private readonly Func<Stream> _streamFactory;
private readonly string _targetFramework;

public ZipPackageFile(string localPath, ZipArchiveEntry entry)
: this(localPath, entry.OpenEntryStream().ToStreamFactory())
{
}

public ZipPackageFile(IPackageFile file)
: this(file.Path, file.GetStream().ToStreamFactory())
{
}

internal ZipPackageFile(string path, Func<Stream> streamFactory)
public ZipPackageFile(string path)
{
Path = path;
_streamFactory = streamFactory;

string effectivePath;
_targetFramework = VersionUtility.ParseFrameworkNameFromFilePath(path, out effectivePath);
EffectivePath = effectivePath;
Expand Down Expand Up @@ -63,11 +49,6 @@ IEnumerable<string> IFrameworkTargetable.SupportedFrameworks {
}
}

public Stream GetStream()
{
return _streamFactory();
}

public override string ToString()
{
return Path;
Expand Down
1 change: 0 additions & 1 deletion src/Squirrel/ReleaseEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ public string PackageName {
public string GetReleaseNotes(string packageDirectory)
{
var zp = new ZipPackage(Path.Combine(packageDirectory, Filename));
var t = zp.Id;

if (String.IsNullOrWhiteSpace(zp.ReleaseNotes)) {
throw new Exception(String.Format("Invalid 'ReleaseNotes' value in nuspec file at '{0}'", Path.Combine(packageDirectory, Filename)));
Expand Down
8 changes: 4 additions & 4 deletions src/Squirrel/UpdateManager.ApplyReleases.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ public Dictionary<ShortcutLocation, ShellLink> GetShortcutsForExecutable(string
IconPath = target,
IconIndex = 0,
WorkingDirectory = Path.GetDirectoryName(exePath),
Description = zf.Description,
Description = zf.ProductDescription,
};

if (!String.IsNullOrWhiteSpace(programArguments)) {
Expand Down Expand Up @@ -240,7 +240,7 @@ public void CreateShortcutsForExecutable(string exeName, ShortcutLocation locati
IconPath = icon ?? target,
IconIndex = 0,
WorkingDirectory = Path.GetDirectoryName(exePath),
Description = zf.Description,
Description = zf.ProductDescription,
};
if (!String.IsNullOrWhiteSpace(programArguments)) {
Expand Down Expand Up @@ -693,14 +693,14 @@ string linkTargetForVersionInfo(ShortcutLocation location, IPackage package, Fil
{
var possibleProductNames = new[] {
versionInfo.ProductName,
package.Title,
package.ProductName,
versionInfo.FileDescription,
Path.GetFileNameWithoutExtension(versionInfo.FileName)
};

var possibleCompanyNames = new[] {
versionInfo.CompanyName,
package.Authors.FirstOrDefault() ?? package.Id,
package.ProductCompany,
};

var prodName = possibleCompanyNames.First(x => !String.IsNullOrWhiteSpace(x));
Expand Down
11 changes: 5 additions & 6 deletions src/Squirrel/UpdateManager.InstallHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,12 @@ public async Task<RegistryKey> CreateUninstallerRegistryEntry(string uninstallCm

// we will try to find an "app.ico" from the package, write it to the local app dir, and then
// use it for the uninstaller icon. If an app.ico does not exist, it will use a SquirrelAwareApp exe icon instead.
var iconFile = zp.GetLibFiles().FirstOrDefault(f => f.Path.EndsWith("app.ico", StringComparison.InvariantCultureIgnoreCase));
if (iconFile != null) {
using var iconFileStream = zp.ReadLibFileStream("app.ico");
if (iconFileStream != null) {
try {
var targetIco = Path.Combine(rootAppDirectory, "app.ico");
using (var iconStream = iconFile.GetStream())
using (var targetStream = File.Open(targetIco, FileMode.Create, FileAccess.Write))
await iconStream.CopyToAsync(targetStream).ConfigureAwait(false);
await iconFileStream.CopyToAsync(targetStream).ConfigureAwait(false);
this.Log().Info($"File '{targetIco}' is being used for uninstall icon.");
key.SetValue("DisplayIcon", targetIco, RegistryValueKind.String);
} catch (Exception ex) {
Expand All @@ -68,11 +67,11 @@ public async Task<RegistryKey> CreateUninstallerRegistryEntry(string uninstallCm
}

var stringsToWrite = new[] {
new { Key = "DisplayName", Value = zp.Title ?? zp.Description ?? zp.Summary },
new { Key = "DisplayName", Value = zp.ProductName },
new { Key = "DisplayVersion", Value = zp.Version.ToString() },
new { Key = "InstallDate", Value = DateTime.Now.ToString("yyyyMMdd") },
new { Key = "InstallLocation", Value = rootAppDirectory },
new { Key = "Publisher", Value = String.Join(",", zp.Authors) },
new { Key = "Publisher", Value = zp.ProductCompany },
new { Key = "QuietUninstallString", Value = String.Format("{0} {1}", uninstallCmd, quietSwitch) },
new { Key = "UninstallString", Value = uninstallCmd },
new { Key = "URLUpdateInfo", Value = zp.ProjectUrl != null ? zp.ProjectUrl.ToString() : "", }
Expand Down
11 changes: 5 additions & 6 deletions src/SquirrelCli/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
Expand Down Expand Up @@ -276,7 +276,7 @@ static void Releasify(ReleasifyOptions options)
Log.Info($"Creating Setup bundle");
var infosave = new BundledSetupInfo() {
AppId = bundledzp.Id,
AppFriendlyName = bundledzp.Title ?? bundledzp.Id,
AppFriendlyName = bundledzp.ProductName,
BundledPackageBytes = File.ReadAllBytes(newestReleasePath),
BundledPackageName = Path.GetFileName(newestReleasePath),
RequiredFrameworks = requiredFrameworks.ToArray(),
Expand Down Expand Up @@ -304,16 +304,15 @@ static async Task createMsiPackage(string setupExe, IPackage package, bool packa

var setupExeDir = Path.GetDirectoryName(setupExe);
var setupName = Path.GetFileNameWithoutExtension(setupExe);
var company = String.Join(",", package.Authors);
var culture = CultureInfo.GetCultureInfo(package.Language ?? "").TextInfo.ANSICodePage;

var templateText = File.ReadAllText(HelperExe.WixTemplatePath);
var templateData = new Dictionary<string, string> {
{ "Id", package.Id },
{ "Title", package.Title },
{ "Author", company },
{ "Title", package.ProductName },
{ "Author", package.ProductCompany },
{ "Version", Regex.Replace(package.Version.ToString(), @"-.*$", "") },
{ "Summary", package.Summary ?? package.Description ?? package.Id },
{ "Summary", package.ProductDescription },
{ "Codepage", $"{culture}" },
{ "Platform", packageAs64Bit ? "x64" : "x86" },
{ "ProgramFilesFolder", packageAs64Bit ? "ProgramFiles64Folder" : "ProgramFilesFolder" },
Expand Down
Loading

0 comments on commit 4cb937b

Please sign in to comment.