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

Commit

Permalink
Remove System.IO.Packaging dependency, add some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
caesay committed Jan 1, 2022
1 parent a1bcfaf commit 377fac4
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 85 deletions.
28 changes: 0 additions & 28 deletions src/Squirrel/NuGet/PackageHelper.cs

This file was deleted.

10 changes: 0 additions & 10 deletions src/Squirrel/NuGet/Utility.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Packaging;
using System.Linq;
using System.Text;
using System.Xml;
Expand All @@ -26,15 +25,6 @@ internal static string GetPath(Uri uri)
return Uri.UnescapeDataString(path.Replace('/', Path.DirectorySeparatorChar));
}

internal static Uri CreatePartUri(string path)
{
// Only the segments between the path separators should be escaped
var segments = path.Split(new[] { '/', Path.DirectorySeparatorChar }, StringSplitOptions.None)
.Select(Uri.EscapeDataString);
var escapedPath = String.Join("/", segments);
return PackUriHelper.CreatePartUri(new Uri(escapedPath, UriKind.Relative));
}

// Bug 2379: SettingsCredentialProvider does not work
private static Uri CreateODataAgnosticUri(string uri)
{
Expand Down
74 changes: 34 additions & 40 deletions src/Squirrel/NuGet/ZipPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.IO.Packaging;
using System.Linq;
using System.Runtime.Versioning;
using System.Xml.Linq;
using SharpCompress.Archives.Zip;

namespace Squirrel.NuGet
{
Expand Down Expand Up @@ -61,16 +60,14 @@ public ZipPackage(string filePath)

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

using (Stream stream = _streamFactory()) {
var package = Package.Open(stream);

string effectivePath;
fileFrameworks = from part in package.GetParts()
where IsPackageFile(part)
select VersionUtility.ParseFrameworkNameFromFilePath(UriUtility.GetPath(part.Uri), out effectivePath);
}
var fileFrameworks = from entries in zip.Entries
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)
Expand All @@ -96,13 +93,16 @@ public IEnumerable<IPackageFile> GetFiles(string directory)

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

return (from part in package.GetParts()
where IsPackageFile(part)
select (IPackageFile) new ZipPackageFile(part)).ToList();
}
var files = from entries in zip.Entries
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();
}

public string GetFullName()
Expand All @@ -112,25 +112,17 @@ public string GetFullName()

private void EnsureManifest()
{
using (Stream stream = _streamFactory()) {
Package package = Package.Open(stream);

PackageRelationship relationshipType = package.GetRelationshipsByType(Constants.PackageRelationshipNamespace + ManifestRelationType).SingleOrDefault();
using var stream = _streamFactory();
using var zip = ZipArchive.Open(stream);

if (relationshipType == null) {
throw new InvalidOperationException("PackageDoesNotContainManifest");
}
var manifest = zip.Entries
.FirstOrDefault(f => f.Key.EndsWith(Constants.ManifestExtension, StringComparison.OrdinalIgnoreCase));

PackagePart manifestPart = package.GetPart(relationshipType.TargetUri);
if (manifest == null)
throw new InvalidOperationException("PackageDoesNotContainManifest");

if (manifestPart == null) {
throw new InvalidOperationException("PackageDoesNotContainManifest");
}

using (Stream manifestStream = manifestPart.GetStream()) {
ReadManifest(manifestStream);
}
}
using var manifestStream = manifest.OpenEntryStream();
ReadManifest(manifestStream);
}

void ReadManifest(Stream manifestStream)
Expand Down Expand Up @@ -172,7 +164,7 @@ private void ReadMetadataValue(XElement element, HashSet<string> allElements)
Version = new SemanticVersion(value);
break;
case "authors":
Authors = value?.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) ?? Enumerable.Empty<string>();
Authors = value?.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()) ?? Enumerable.Empty<string>();
break;
//case "owners":
// Owners = value;
Expand Down Expand Up @@ -290,14 +282,16 @@ private IEnumerable<string> ParseFrameworkNames(string frameworkNames)
.Select(VersionUtility.ParseFrameworkName);
}

bool IsPackageFile(PackagePart part)
bool IsPackageFile(string partPath)
{
string path = UriUtility.GetPath(part.Uri);
string directory = Path.GetDirectoryName(path);
if (Path.GetFileName(partPath).Equals(ContentType.ContentTypeFileName, StringComparison.OrdinalIgnoreCase))
return false;

if (Path.GetExtension(partPath).Equals(Constants.ManifestExtension, StringComparison.OrdinalIgnoreCase))
return false;

// We exclude any opc files and the manifest file (.nuspec)
return !ExcludePaths.Any(p => directory.StartsWith(p, StringComparison.OrdinalIgnoreCase)) &&
!PackageHelper.IsManifest(path);
string directory = Path.GetDirectoryName(partPath);
return !ExcludePaths.Any(p => directory.StartsWith(p, StringComparison.OrdinalIgnoreCase));
}
}
}
38 changes: 32 additions & 6 deletions src/Squirrel/NuGet/ZipPackageFile.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Packaging;
using System.Runtime.Versioning;
using SharpCompress.Archives.Zip;

namespace Squirrel.NuGet
{
Expand All @@ -14,13 +13,13 @@ internal interface IPackageFile : IFrameworkTargetable
Stream GetStream();
}

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

public ZipPackageFile(PackagePart part)
: this(UriUtility.GetPath(part.Uri), part.GetStream().ToStreamFactory())
public ZipPackageFile(string localPath, ZipArchiveEntry entry)
: this(localPath, entry.OpenEntryStream().ToStreamFactory())
{
}

Expand All @@ -29,7 +28,7 @@ public ZipPackageFile(IPackageFile file)
{
}

protected ZipPackageFile(string path, Func<Stream> streamFactory)
internal ZipPackageFile(string path, Func<Stream> streamFactory)
{
Path = path;
_streamFactory = streamFactory;
Expand Down Expand Up @@ -73,5 +72,32 @@ public override string ToString()
{
return Path;
}

public override int GetHashCode()
{
unchecked {
int hash = 17;
hash = hash * 23 + Path.GetHashCode();
hash = hash * 23 + EffectivePath.GetHashCode();
hash = hash * 23 + TargetFramework.GetHashCode();
return hash;
}
}

public override bool Equals(object obj)
{
if (obj is ZipPackageFile zpf)
return Equals(zpf);
return false;
}

public bool Equals(ZipPackageFile other)
{
if (other == null) return false;
return
Path.Equals(other.Path) &&
EffectivePath.Equals(other.EffectivePath) &&
TargetFramework.Equals(other.TargetFramework);
}
}
}
1 change: 0 additions & 1 deletion src/Squirrel/Squirrel.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
<ItemGroup>
<PackageReference Include="SharpCompress" Version="0.30.1" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageReference Include="System.IO.Packaging" Version="5.0.0" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('net461')) ">
Expand Down
2 changes: 2 additions & 0 deletions test/Squirrel.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<Description>Squirrel.Tests</Description>
<Title>Squirrel.Tests</Title>
<IsPackable>false</IsPackable>
<LangVersion>9</LangVersion>
<IsTest>true</IsTest>
<NoWarn>CS1998,xUnit2015,xUnit2017,xUnit2005,xUnit2009,xUnit2013,xUnit2004</NoWarn>
<SignAssembly>True</SignAssembly>
Expand All @@ -17,6 +18,7 @@
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" PrivateAssets="All" />
<PackageReference Include="System.IO.Packaging" Version="5.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
120 changes: 120 additions & 0 deletions test/ZipPackageTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Packaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Squirrel.NuGet;
using Squirrel.Tests.TestHelpers;
using Xunit;
using ZipPackage = Squirrel.NuGet.ZipPackage;

namespace Squirrel.Tests
{
public class ZipPackageTests
{
[Fact]
public void HasSameFilesAndDependenciesAsPackaging()
{
var inputPackage = IntegrationTestHelper.GetPath("fixtures", "slack-1.1.8-full.nupkg");

var zp = new ZipPackage(inputPackage);
var zipfw = zp.GetSupportedFrameworks();
var zipf = zp.GetFiles().OrderBy(f => f.Path).ToArray();
var zipfLib = zp.GetLibFiles().OrderBy(f => f.Path).ToArray();

using Package package = Package.Open(inputPackage);
var packagingfw = GetSupportedFrameworks(zp, package);
var packaging = GetFiles(package).OrderBy(f => f.Path).ToArray();
var packagingLib = GetLibFiles(package).OrderBy(f => f.Path).ToArray();

//for (int i = 0; i < zipf.Length; i++) {
// if (zipf[i] != packagingLib[i])
// throw new Exception();
//}

Assert.Equal(packaging, zipf);
Assert.Equal(packagingLib, zipfLib);
}

[Fact]
public void ParsesNuspecCorrectly()
{
var inputPackage = IntegrationTestHelper.GetPath("fixtures", "FullNuspec.1.0.0.nupkg");
var zp = new ZipPackage(inputPackage);

Assert.Equal("FullNuspec", zp.Id);
Assert.Equal(new SemanticVersion("1.0"), zp.Version);
Assert.Equal(new [] { "Anaïs Betts", "Caelan Sayler" }, zp.Authors);
Assert.Equal(new Uri("https://github.com/clowd/Clowd.Squirrel"), zp.ProjectUrl);
Assert.Equal(new Uri("https://user-images.githubusercontent.com/1287295/131249078-9e131e51-0b66-4dc7-8c0a-99cbea6bcf80.png"), zp.IconUrl);
Assert.Equal("A test description", zp.Description);
Assert.Equal("A summary", zp.Summary);
Assert.Equal("release notes\nwith multiple lines", zp.ReleaseNotes);
Assert.Equal("Copyright ©", zp.Copyright);
Assert.Equal("en-US", zp.Language);
Assert.Equal("Squirrel for Windows", zp.Title);

Assert.NotEmpty(zp.DependencySets);
var net461 = zp.DependencySets.First();
Assert.Equal(new[] { ".NETFramework4.6.1" }, net461.SupportedFrameworks);
Assert.Equal(".NETFramework4.6.1", net461.TargetFramework);

Assert.NotEmpty(net461.Dependencies);
var dvt = net461.Dependencies.First();
Assert.Equal("System.ValueTuple", dvt.Id);
Assert.Equal("4.5.0", dvt.VersionSpec);

Assert.Equal(new[] { "net5.0" }, zp.DependencySets.Last().SupportedFrameworks);

Assert.NotEmpty(zp.FrameworkAssemblies);
var fw = zp.FrameworkAssemblies.First();
Assert.Equal("System.Net.Http", fw.AssemblyName);
Assert.Equal(new [] { ".NETFramework4.6.1" }, fw.SupportedFrameworks);
}

IEnumerable<string> GetSupportedFrameworks(ZipPackage zp, Package package)
{
var fileFrameworks = from part in package.GetParts()
where IsPackageFile(part)
select VersionUtility.ParseFrameworkNameFromFilePath(UriUtility.GetPath(part.Uri), out var effectivePath);

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

IEnumerable<IPackageFile> GetLibFiles(Package package)
{
return GetFiles(package, Constants.LibDirectory);
}

IEnumerable<IPackageFile> GetFiles(Package package, string directory)
{
string folderPrefix = directory + Path.DirectorySeparatorChar;
return GetFiles(package).Where(file => file.Path.StartsWith(folderPrefix, StringComparison.OrdinalIgnoreCase));
}

List<IPackageFile> GetFiles(Package package)
{
return (from part in package.GetParts()
where IsPackageFile(part)
select (IPackageFile) new ZipPackageFile(UriUtility.GetPath(part.Uri), part.GetStream().ToStreamFactory())).ToList();
}

bool IsPackageFile(PackagePart part)
{
string path = UriUtility.GetPath(part.Uri);
string directory = Path.GetDirectoryName(path);
string[] ExcludePaths = new[] { "_rels", "package" };
return !ExcludePaths.Any(p => directory.StartsWith(p, StringComparison.OrdinalIgnoreCase)) && !IsManifest(path);
}

bool IsManifest(string p)
{
return Path.GetExtension(p).Equals(Constants.ManifestExtension, StringComparison.OrdinalIgnoreCase);
}
}
}
Loading

0 comments on commit 377fac4

Please sign in to comment.