Skip to content
This repository was archived by the owner on Jan 27, 2025. It is now read-only.

Commit 7b40f6c

Browse files
author
InedoJohn
committed
Fix #27
1 parent 5ea3aba commit 7b40f6c

7 files changed

+135
-4
lines changed

upack/Command.cs

+11
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Linq;
1010
using System.Net;
1111
using System.Reflection;
12+
using System.Security.Cryptography;
1213
using System.Text;
1314
using System.Threading;
1415
using System.Threading.Tasks;
@@ -440,5 +441,15 @@ internal static UniversalFeedClient CreateClient(string source, NetworkCredentia
440441
throw new UpackException("Invalid UPack feed URL: " + ex.Message, ex);
441442
}
442443
}
444+
445+
internal static HexString GetSHA1(string filePath)
446+
{
447+
using (var file = File.OpenRead(filePath))
448+
using (var hash = HashAlgorithm.Create("SHA1"))
449+
{
450+
var bytes = hash.ComputeHash(file);
451+
return new HexString(bytes);
452+
}
453+
}
443454
}
444455
}

upack/CommandDispatcher.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Inedo.ProGet.UPack
1010
{
1111
public sealed class CommandDispatcher
1212
{
13-
public static CommandDispatcher Default => new CommandDispatcher(typeof(Pack), typeof(Push), typeof(Unpack), typeof(Install), typeof(List), typeof(Repack));
13+
public static CommandDispatcher Default => new CommandDispatcher(typeof(Pack), typeof(Push), typeof(Unpack), typeof(Install), typeof(List), typeof(Repack), typeof(Verify), typeof(Hash));
1414

1515
private readonly IEnumerable<Type> commands;
1616

upack/Hash.cs

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using System;
2+
using System.ComponentModel;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
using Inedo.UPack;
6+
using Inedo.UPack.Packaging;
7+
8+
namespace Inedo.ProGet.UPack
9+
{
10+
[DisplayName("hash")]
11+
[Description("Calculates the SHA1 hash of a local package and writes it to standard output.")]
12+
public sealed class Hash : Command
13+
{
14+
[DisplayName("package")]
15+
[Description("Path of a valid .upack file.")]
16+
[PositionalArgument(0)]
17+
[ExpandPath]
18+
public string PackagePath { get; set; }
19+
20+
public override Task<int> RunAsync(CancellationToken cancellationToken)
21+
{
22+
var metadata = GetPackageMetadata();
23+
var packageId = new UniversalPackageId(metadata.Group, metadata.Name);
24+
25+
var sha1 = GetSHA1(this.PackagePath);
26+
27+
Console.WriteLine(sha1);
28+
29+
return Task.FromResult(0);
30+
}
31+
32+
private UniversalPackageMetadata GetPackageMetadata()
33+
{
34+
try
35+
{
36+
using (var package = new UniversalPackage(this.PackagePath))
37+
{
38+
return package.GetFullMetadata().Clone();
39+
}
40+
}
41+
catch (Exception ex)
42+
{
43+
throw new UpackException($"The source package file '{this.PackagePath}' does not exist or could not be opened.", ex);
44+
}
45+
}
46+
}
47+
}

upack/Pack.cs

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public sealed class Pack : Command
1616
[AlternateName("metadata")]
1717
[Description("Path of a valid upack.json metadata file.")]
1818
[ExtraArgument]
19+
[ExpandPath]
1920
public string Manifest { get; set; }
2021

2122
[DisplayName("source")]

upack/Repack.cs

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
using Inedo.UPack;
2-
using Inedo.UPack.Packaging;
3-
using System;
1+
using System;
42
using System.ComponentModel;
53
using System.IO;
64
using System.Linq;
75
using System.Threading;
86
using System.Threading.Tasks;
7+
using Inedo.UPack;
8+
using Inedo.UPack.Packaging;
99

1010
namespace Inedo.ProGet.UPack
1111
{
@@ -17,6 +17,7 @@ public sealed class Repack : Command
1717
[AlternateName("metadata")]
1818
[Description("Path of upack.json file to merge.")]
1919
[ExtraArgument]
20+
[ExpandPath]
2021
public string Manifest { get; set; }
2122

2223
[DisplayName("source")]
@@ -101,6 +102,8 @@ public override async Task<int> RunAsync(CancellationToken cancellationToken)
101102

102103
foreach (var entry in entries)
103104
{
105+
cancellationToken.ThrowIfCancellationRequested();
106+
104107
if (entry.IsDirectory)
105108
{
106109
builder.AddEmptyDirectoryRaw(entry.RawPath);

upack/Verify.cs

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.ComponentModel;
4+
using System.Net;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
using Inedo.UPack;
8+
using Inedo.UPack.Packaging;
9+
10+
namespace Inedo.ProGet.UPack
11+
{
12+
[DisplayName("verify")]
13+
[Description("Verifies that a specified package hash matches the hash stored in a ProGet Universal feed.")]
14+
public sealed class Verify : Command
15+
{
16+
[DisplayName("package")]
17+
[Description("Path of a valid .upack file.")]
18+
[PositionalArgument(0)]
19+
[ExpandPath]
20+
public string PackagePath { get; set; }
21+
22+
[DisplayName("source")]
23+
[Description("URL of a upack API endpoint.")]
24+
[PositionalArgument(1)]
25+
public string SourceEndpoint { get; set; }
26+
27+
[DisplayName("user")]
28+
[Description("User name and password to use for servers that require authentication. Example: username:password")]
29+
[ExtraArgument]
30+
public NetworkCredential Authentication { get; set; }
31+
32+
public override async Task<int> RunAsync(CancellationToken cancellationToken)
33+
{
34+
var metadata = GetPackageMetadata();
35+
var packageId = new UniversalPackageId(metadata.Group, metadata.Name);
36+
var client = CreateClient(this.SourceEndpoint, this.Authentication);
37+
var remoteVersion = await client.GetPackageVersionAsync(packageId, metadata.Version, false, cancellationToken);
38+
39+
if (remoteVersion == null)
40+
throw new UpackException($"Package {packageId} was not found in feed.");
41+
42+
var sha1 = GetSHA1(this.PackagePath);
43+
44+
if (sha1 != remoteVersion.SHA1)
45+
throw new UpackException($"Package SHA1 value {sha1} did not match remote SHA1 value {remoteVersion.SHA1}");
46+
47+
Console.WriteLine("Hashes for local and remote package match: " + sha1);
48+
49+
return 0;
50+
}
51+
52+
private UniversalPackageMetadata GetPackageMetadata()
53+
{
54+
try
55+
{
56+
using (var package = new UniversalPackage(this.PackagePath))
57+
{
58+
return package.GetFullMetadata().Clone();
59+
}
60+
}
61+
catch (Exception ex)
62+
{
63+
throw new UpackException($"The source package file '{this.PackagePath}' does not exist or could not be opened.", ex);
64+
}
65+
}
66+
}
67+
}

upack/upack.csproj

+2
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@
6666
<Compile Include="Command.cs" />
6767
<Compile Include="CommandDispatcher.cs" />
6868
<Compile Include="Install.cs" />
69+
<Compile Include="Hash.cs" />
70+
<Compile Include="Verify.cs" />
6971
<Compile Include="List.cs" />
7072
<Compile Include="Repack.cs" />
7173
<Compile Include="Pack.cs" />

0 commit comments

Comments
 (0)