Skip to content

Commit edf99c9

Browse files
committed
Add support for namespaced packages
1 parent fee56a4 commit edf99c9

File tree

8 files changed

+109
-19
lines changed

8 files changed

+109
-19
lines changed

Add.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ private static async Task<UnpkgJsonEntry> AddPackage(string package)
4444
return null;
4545
}
4646

47+
var distDirectory = distFile.Files.FirstOrDefault(f =>
48+
f.Type.Equals("directory", StringComparison.OrdinalIgnoreCase) && f.Path.Equals("/dist", StringComparison.OrdinalIgnoreCase));
49+
50+
if (distDirectory != null)
51+
{
52+
distDirectory.BaseUrl = distFile.BaseUrl;
53+
distFile = distDirectory;
54+
}
55+
4756
await DownloadPackage(package, distFile.BaseUrl, distFile.Files);
4857
return UnpkgJsonEntry.Create(package, distFile);
4958
}
@@ -69,7 +78,9 @@ private static Task DownloadPackage(string package, string basePath, IEnumerable
6978

7079
private static async Task DownloadFile(string package, string basePath, DistFile file)
7180
{
72-
file.LocalPath = await Download.DistFile(package, $"{basePath}{file.Path}");
81+
var (cdn, localPath) = await Download.DistFile(package, $"{basePath.TrimSlashes()}/{file.Path.TrimSlashes()}");
82+
file.Url = cdn;
83+
file.LocalPath = localPath.Replace(Path.DirectorySeparatorChar, '/');
7384
}
7485
}
7586
}

DistFile.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ public class DistFile
1414
public string Type { get; set; }
1515
public string Integrity { get; set; }
1616
public List<DistFile> Files { get; set; }
17+
public string Url { get; set; }
1718
}
1819
}

Download.cs

Lines changed: 72 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,16 @@ namespace dotnet_unpkg
88
{
99
public static class Download
1010
{
11+
private static readonly char[] SplitChar = {'/'};
1112
private static readonly HttpClient Client = new HttpClient
1213
{
1314
BaseAddress = new Uri("https://unpkg.com")
1415
};
1516
private static readonly string BaseDirectory = Path.Combine("wwwroot", "lib");
1617

17-
public static async Task<string> DistFile(string package, string path)
18+
public static async Task<(string, string)> DistFile(string package, string path)
1819
{
19-
var target = TargetFile(path);
20+
var target = TargetFile(package, path);
2021
using (var response = await Client.GetAsync(path))
2122
{
2223
if (response.IsSuccessStatusCode)
@@ -36,23 +37,82 @@ public static async Task<string> DistFile(string package, string path)
3637
}
3738

3839
Console.WriteLine($"{response.RequestMessage.RequestUri}... OK");
39-
return localPath;
40+
return (response.RequestMessage.RequestUri.ToString(), localPath);
4041
}
4142
else
4243
{
4344
Console.WriteLine($"{response.RequestMessage.RequestUri}... failed ({(int)response.StatusCode})");
44-
return null;
45+
return default;
4546
}
4647
}
4748
}
4849

49-
private static string TargetFile(string path) => path.Contains("/dist/")
50-
? string.Join(Path.DirectorySeparatorChar,
51-
path.Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries)
52-
.SkipWhile(s => !s.Equals("dist", StringComparison.OrdinalIgnoreCase))
53-
.Skip(1))
54-
: string.Join(Path.DirectorySeparatorChar,
55-
path.Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries)
56-
.Skip(1));
50+
public static async Task RestoreDistFile(string url, string path)
51+
{
52+
using (var response = await Client.GetAsync(url))
53+
{
54+
if (response.IsSuccessStatusCode)
55+
{
56+
path = path.Replace('/', Path.DirectorySeparatorChar);
57+
var directory = Path.GetDirectoryName(path);
58+
if (!Directory.Exists(directory))
59+
{
60+
Directory.CreateDirectory(directory);
61+
}
62+
63+
using (var fileStream = File.Create(path))
64+
{
65+
await response.Content.CopyToAsync(fileStream);
66+
}
67+
68+
Console.WriteLine($"{response.RequestMessage.RequestUri}... OK");
69+
}
70+
else
71+
{
72+
Console.WriteLine($"{response.RequestMessage.RequestUri}... failed ({(int)response.StatusCode})");
73+
}
74+
}
75+
}
76+
77+
private static string TargetFile(string package, string path)
78+
{
79+
var packageEnd = package.Split(SplitChar, StringSplitOptions.RemoveEmptyEntries).Last();
80+
var pathParts = path.Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries).ToArray();
81+
82+
if (pathParts.Contains("dist"))
83+
{
84+
pathParts = pathParts
85+
.SkipWhile(s => !s.Equals("dist", StringComparison.OrdinalIgnoreCase))
86+
.Skip(1).ToArray();
87+
88+
switch (pathParts.Length)
89+
{
90+
case 0:
91+
return path;
92+
case 1:
93+
return pathParts[0];
94+
default:
95+
if (pathParts[0].Equals(packageEnd, StringComparison.OrdinalIgnoreCase))
96+
{
97+
pathParts = pathParts.Skip(1).ToArray();
98+
}
99+
100+
break;
101+
}
102+
// return string.Join(Path.DirectorySeparatorChar,
103+
// pathParts
104+
// .SkipWhile(s => !s.Equals("dist", StringComparison.OrdinalIgnoreCase))
105+
// .Skip(1));
106+
}
107+
else
108+
{
109+
pathParts = pathParts.Skip(1).ToArray();
110+
// return string.Join(Path.DirectorySeparatorChar,
111+
// pathParts
112+
// .Skip(1));
113+
}
114+
115+
return string.Join(Path.DirectorySeparatorChar, pathParts);
116+
}
57117
}
58118
}

Restore.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,14 @@ private static Task DownloadFiles(string package, JObject entry)
5959

6060
private static Task DownloadFile(string package, string version, JObject file)
6161
{
62-
var local = file["local"].Value<string>();
62+
var local = file["local"]?.Value<string>()?.Replace('/', Path.DirectorySeparatorChar);
63+
var cdn = file["cdn"]?.Value<string>();
64+
65+
if (string.IsNullOrWhiteSpace(local) || string.IsNullOrWhiteSpace(cdn))
66+
{
67+
Console.Error.WriteLine($"Could not restore: {file}");
68+
return Task.CompletedTask;
69+
}
6370
if (File.Exists(local))
6471
{
6572
var integrity = file["integrity"].Value<string>();
@@ -82,7 +89,7 @@ private static Task DownloadFile(string package, string version, JObject file)
8289
}
8390
}
8491

85-
return Download.DistFile(package, $"{version}/{file["file"].Value<string>()}");
92+
return Download.RestoreDistFile(cdn, local);
8693
}
8794

8895
private static HashAlgorithm GetAlgorithm(string name)

TrimExtensions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace dotnet_unpkg
2+
{
3+
public static class TrimExtensions
4+
{
5+
public static string TrimSlashes(this string path) => path?.Trim().Trim('/');
6+
}
7+
}

UnpkgJson.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ public static async Task Save(IEnumerable<UnpkgJsonEntry> entries)
4343
}
4444
}
4545

46-
public static string CleanPackageName(string full) => full.Split('@').FirstOrDefault();
46+
private static string CleanPackageName(string full)
47+
{
48+
var last = full.LastIndexOf('@');
49+
return last > 0 ? full.Substring(0, last) : full;
50+
}
4751

4852
public static string CleanVersion(string full) => full.Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
4953
}

UnpkgJsonEntry.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ private static void AddFiles(List<UnpkgJsonFile> files, string version, IEnumera
3030
{
3131
Path = distFile.Path,
3232
LocalPath = distFile.LocalPath,
33-
CdnUrl = $"https://unpkg.com/{version}{distFile.Path}",
33+
CdnUrl = distFile.Url,
3434
Integrity = distFile.Integrity
3535
});
3636
}

dotnet-unpkg.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3-
<Version>1.0.0</Version>
3+
<Version>1.1.0</Version>
44
<OutputType>Exe</OutputType>
55
<TargetFramework>netcoreapp2.0</TargetFramework>
66
<LangVersion>latest</LangVersion>
77
<AssemblyName>dotnet-unpkg</AssemblyName>
88
<PackageId>RendleLabs.UnpkgCli</PackageId>
99
<Description>dotnet cli extension for installing front-end packages from unpkg.com</Description>
1010
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
11-
<PackageReleaseNotes>Preview 1</PackageReleaseNotes>
11+
<PackageReleaseNotes>Supports namespaces packages</PackageReleaseNotes>
1212
<Copyright>Copyright (C) 2018 RendleLabs</Copyright>
1313
<PackageTags>frontend package-management</PackageTags>
1414
<PackageProjectUrl>https://github.com/rendlelabs/dotnet-unpkg</PackageProjectUrl>

0 commit comments

Comments
 (0)