Skip to content

Commit a1602af

Browse files
authored
Merge pull request #7257 from NuGet/mogah-prototype
[GiHub Usage] Add Gallery UI
2 parents 78e88f9 + 832ff49 commit a1602af

23 files changed

Lines changed: 584 additions & 2 deletions

src/Bootstrap/dist/css/bootstrap-theme.css

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Bootstrap/less/theme/page-display-package.less

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,24 @@
117117
}
118118
}
119119

120+
.btn-gh-repo {
121+
display: inline-block;
122+
width: 100%;
123+
background-color: white;
124+
}
125+
126+
.btn-gh-repo:hover {
127+
background-color: @state-info-bg;
128+
}
129+
130+
.badge-gh-repo {
131+
background-color: @navbar-inverse-bg;
132+
}
133+
134+
.star-gh-repo {
135+
color: #ffac0e;
136+
}
137+
120138
.install-tabs {
121139
font-size: 0.8em;
122140

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
8+
namespace NuGetGallery
9+
{
10+
public class GitHubUsageConfiguration : IGitHubUsageConfiguration
11+
{
12+
private readonly IReadOnlyDictionary<string, NuGetPackageGitHubInformation> _nuGetPackagesGitHubDependencies;
13+
14+
public GitHubUsageConfiguration(IReadOnlyCollection<RepositoryInformation> repositories)
15+
{
16+
if (repositories == null)
17+
{
18+
throw new ArgumentNullException(nameof(repositories));
19+
}
20+
21+
_nuGetPackagesGitHubDependencies = GetNuGetPackagesDependents(repositories);
22+
}
23+
24+
public NuGetPackageGitHubInformation GetPackageInformation(string packageId)
25+
{
26+
if (packageId == null)
27+
{
28+
throw new ArgumentNullException(nameof(packageId));
29+
}
30+
31+
if (_nuGetPackagesGitHubDependencies.TryGetValue(packageId, out var value))
32+
{
33+
return value;
34+
}
35+
36+
return NuGetPackageGitHubInformation.Empty;
37+
}
38+
39+
private static IReadOnlyDictionary<string, NuGetPackageGitHubInformation> GetNuGetPackagesDependents(IReadOnlyCollection<RepositoryInformation> repositories)
40+
{
41+
var dependentsPerPackage = new Dictionary<string, List<RepositoryInformation>>(StringComparer.OrdinalIgnoreCase);
42+
foreach (var repo in repositories)
43+
{
44+
foreach (var dependency in repo.Dependencies)
45+
{
46+
if (!dependentsPerPackage.TryGetValue(dependency, out var packageDependents))
47+
{
48+
packageDependents = new List<RepositoryInformation>();
49+
dependentsPerPackage[dependency] = packageDependents;
50+
}
51+
52+
packageDependents.Add(repo);
53+
}
54+
}
55+
56+
return dependentsPerPackage
57+
.ToDictionary(
58+
entry => entry.Key,
59+
entry => new NuGetPackageGitHubInformation(entry.Value),
60+
StringComparer.OrdinalIgnoreCase);
61+
}
62+
}
63+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
namespace NuGetGallery
5+
{
6+
public interface IGitHubUsageConfiguration
7+
{
8+
/// <summary>
9+
/// Returns the GitHub dependants information about a NuGet package.
10+
///
11+
/// If a packageId has no information, the NuGetPackageGitHubInformation's TotalRepos will be 0
12+
/// and the Repos list will be empty
13+
///
14+
/// </summary>
15+
/// <exception cref="System.ArgumentNullException">Thrown when packageId is null</exception>
16+
/// <param name="packageId">NuGet package id, cannot be null</param>
17+
/// <returns>NuGetPackageGitHubInformation that contains the information about a NuGet package.</returns>
18+
NuGetPackageGitHubInformation GetPackageInformation(string packageId);
19+
}
20+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
8+
namespace NuGetGallery
9+
{
10+
public class NuGetPackageGitHubInformation
11+
{
12+
public const int ReposPerPackage = 10;
13+
14+
public readonly static NuGetPackageGitHubInformation Empty = new NuGetPackageGitHubInformation(new List<RepositoryInformation>());
15+
16+
public NuGetPackageGitHubInformation(IReadOnlyCollection<RepositoryInformation> repos)
17+
{
18+
if( repos == null)
19+
{
20+
throw new ArgumentNullException(nameof(repos));
21+
}
22+
23+
TotalRepos = repos.Count;
24+
Repos = repos
25+
.OrderByDescending(x => x.Stars)
26+
.ThenBy(x => x.Id, StringComparer.OrdinalIgnoreCase)
27+
.Take(ReposPerPackage)
28+
.ToList();
29+
}
30+
31+
public int TotalRepos { get; }
32+
public IReadOnlyCollection<RepositoryInformation> Repos { get; }
33+
}
34+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using Newtonsoft.Json;
5+
using System;
6+
using System.Collections.Generic;
7+
8+
namespace NuGetGallery
9+
{
10+
public class RepositoryInformation
11+
{
12+
public RepositoryInformation(
13+
string id,
14+
string url,
15+
int stars,
16+
IReadOnlyList<string> dependencies)
17+
{
18+
if (stars < 0)
19+
{
20+
throw new IndexOutOfRangeException(string.Format("{0} cannot have a negative value!", nameof(stars)));
21+
}
22+
23+
Id = id ?? throw new ArgumentNullException(nameof(id));
24+
var idSplit = Id.Split('/');
25+
if (idSplit.Length == 2)
26+
{
27+
Owner = idSplit[0];
28+
Name = idSplit[1];
29+
}
30+
else
31+
{
32+
throw new ArgumentException(string.Format("{0} has an invalid format! It should be \"owner/repositoryName\"!", nameof(Id)));
33+
}
34+
35+
Url = url ?? throw new ArgumentNullException(nameof(url));
36+
Stars = stars;
37+
Dependencies = dependencies ?? throw new ArgumentNullException(nameof(dependencies));
38+
}
39+
40+
[JsonIgnore]
41+
public string Name { get; }
42+
[JsonIgnore]
43+
public string Owner { get; }
44+
public string Url { get; }
45+
public int Stars { get; }
46+
public string Id { get; }
47+
public IReadOnlyList<string> Dependencies { get; }
48+
}
49+
}

src/NuGetGallery.Core/NuGetGallery.Core.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@
147147
<Compile Include="Features\FeatureFlagReference.cs" />
148148
<Compile Include="Features\FeatureFlagSaveResult.cs" />
149149
<Compile Include="Features\IEditableFeatureFlagStorageService.cs" />
150+
<Compile Include="GitHub\GitHubUsageConfiguration.cs" />
151+
<Compile Include="GitHub\IGitHubUsageConfiguration.cs" />
152+
<Compile Include="GitHub\NuGetPackageGitHubInformation.cs" />
153+
<Compile Include="GitHub\RepositoryInformation.cs" />
150154
<Compile Include="ICloudStorageStatusDependency.cs" />
151155
<Compile Include="Infrastructure\AzureEntityList.cs" />
152156
<Compile Include="Infrastructure\ElmahException.cs" />

src/NuGetGallery.Services/ServicesConstants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public static class ContentNames
3939
public static readonly string CertificatesConfiguration = "Certificates-Configuration";
4040
public static readonly string SymbolsConfiguration = "Symbols-Configuration";
4141
public static readonly string TyposquattingConfiguration = "Typosquatting-Configuration";
42+
public static readonly string NuGetPackagesGitHubDependencies = "GitHubUsage.v1";
4243
}
4344
}
4445
}

src/NuGetGallery.Services/Storage/ContentObjectService.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5+
using System.Collections.Generic;
56
using System.Threading.Tasks;
67
using Newtonsoft.Json;
78
using NuGetGallery.Services;
@@ -28,6 +29,7 @@ public ContentObjectService(IContentService contentService)
2829
public ICertificatesConfiguration CertificatesConfiguration { get; set; }
2930
public ISymbolsConfiguration SymbolsConfiguration { get; set; }
3031
public ITyposquattingConfiguration TyposquattingConfiguration { get; set; }
32+
public IGitHubUsageConfiguration GitHubUsageConfiguration { get; set; }
3133

3234
public async Task Refresh()
3335
{
@@ -46,9 +48,15 @@ await Refresh<SymbolsConfiguration>(ServicesConstants.ContentNames.SymbolsConfig
4648
TyposquattingConfiguration =
4749
await Refresh<TyposquattingConfiguration>(ServicesConstants.ContentNames.TyposquattingConfiguration) ??
4850
new TyposquattingConfiguration();
51+
52+
var reposCache =
53+
await Refresh<IReadOnlyCollection<RepositoryInformation>>(ServicesConstants.ContentNames.NuGetPackagesGitHubDependencies) ??
54+
Array.Empty<RepositoryInformation>();
55+
56+
GitHubUsageConfiguration = new GitHubUsageConfiguration(reposCache);
4957
}
5058

51-
private async Task<T> Refresh<T>(string contentName)
59+
private async Task<T> Refresh<T>(string contentName)
5260
where T : class
5361
{
5462
var configString = (await _contentService.GetContentItemAsync(contentName, RefreshInterval))?.ToString();

src/NuGetGallery.Services/Storage/IContentObjectService.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4+
using System.Collections.Generic;
45
using System.Threading.Tasks;
56
using NuGetGallery.Services;
67

@@ -12,6 +13,8 @@ public interface IContentObjectService
1213
ICertificatesConfiguration CertificatesConfiguration { get; }
1314
ISymbolsConfiguration SymbolsConfiguration { get; }
1415
ITyposquattingConfiguration TyposquattingConfiguration { get; }
16+
IGitHubUsageConfiguration GitHubUsageConfiguration { get; }
17+
1518
Task Refresh();
1619
}
1720
}

0 commit comments

Comments
 (0)