Skip to content

Commit 86af6b6

Browse files
authored
Add fuget.org links to packages (#8364)
* Add fuget.org links to packages
1 parent aeb04b5 commit 86af6b6

10 files changed

Lines changed: 74 additions & 2 deletions

File tree

src/NuGetGallery.Services/Configuration/FeatureFlagService.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public class FeatureFlagService : IFeatureFlagService
2626
private const string ManageDeprecationForManyVersionsFeatureName = GalleryPrefix + "ManageDeprecationMany";
2727
private const string ManageDeprecationApiFeatureName = GalleryPrefix + "ManageDeprecationApi";
2828
private const string DisplayVulnerabilitiesFeatureName = GalleryPrefix + "DisplayVulnerabilities";
29+
private const string DisplayFuGetLinksFeatureName = GalleryPrefix + "DisplayFuGetLinks";
2930
private const string ODataReadOnlyDatabaseFeatureName = GalleryPrefix + "ODataReadOnlyDatabase";
3031
private const string PackagesAtomFeedFeatureName = GalleryPrefix + "PackagesAtomFeed";
3132
private const string SearchSideBySideFlightName = GalleryPrefix + "SearchSideBySide";
@@ -133,6 +134,11 @@ public bool IsDisplayVulnerabilitiesEnabled()
133134
return _client.IsEnabled(DisplayVulnerabilitiesFeatureName, defaultValue: false);
134135
}
135136

137+
public bool IsDisplayFuGetLinksEnabled()
138+
{
139+
return _client.IsEnabled(DisplayFuGetLinksFeatureName, defaultValue: false);
140+
}
141+
136142
public bool AreEmbeddedIconsEnabled(User user)
137143
{
138144
return _client.IsEnabled(EmbeddedIconFlightName, user, defaultValue: false);

src/NuGetGallery.Services/Configuration/IFeatureFlagService.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ public interface IFeatureFlagService
6161
/// </summary>
6262
bool IsDisplayVulnerabilitiesEnabled();
6363

64+
/// <summary>
65+
/// Whether or not a fuget.org link is visible on a package's details page.
66+
/// </summary>
67+
bool IsDisplayFuGetLinksEnabled();
68+
6469
/// <summary>
6570
/// Whether the user is allowed to publish packages with an embedded icon.
6671
/// </summary>

src/NuGetGallery/App_Data/Files/Content/flags.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"NuGetGallery.ODataV2FindPackagesByIdCountNonHijacked": "Enabled",
2424
"NuGetGallery.ODataV2SearchNonHijacked": "Enabled",
2525
"NuGetGallery.ODataV2SearchCountNonHijacked": "Enabled",
26-
"NuGetGallery.DisplayVulnerabilities": "Enabled"
26+
"NuGetGallery.DisplayVulnerabilities": "Enabled",
27+
"NuGetGallery.DisplayFuGetLinks": "Enabled"
2728
},
2829
"Flights": {
2930
"NuGetGallery.TyposquattingFlight": {
7.61 KB
Loading
Lines changed: 13 additions & 0 deletions
Loading

src/NuGetGallery/Controllers/PackagesController.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,7 @@ public virtual async Task<ActionResult> DisplayPackage(string id, string version
902902
model.IsAtomFeedEnabled = _featureFlagService.IsPackagesAtomFeedEnabled();
903903
model.IsPackageDeprecationEnabled = _featureFlagService.IsManageDeprecationEnabled(currentUser, allVersions);
904904
model.IsPackageVulnerabilitiesEnabled = _featureFlagService.IsDisplayVulnerabilitiesEnabled();
905+
model.IsFuGetLinksEnabled = _featureFlagService.IsDisplayFuGetLinksEnabled();
905906
model.IsPackageRenamesEnabled = _featureFlagService.IsPackageRenamesEnabled(currentUser);
906907
model.IsPackageDependentsEnabled = _featureFlagService.IsPackageDependentsEnabled(currentUser);
907908

src/NuGetGallery/Helpers/ViewModelExtensions/DisplayPackageViewModelFactory.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,12 @@ private DisplayPackageViewModel SetupCommon(
163163
viewModel.ProjectUrl = projectUrl;
164164
}
165165

166+
var fugetUrl = $"https://www.fuget.org/packages/{package.Id}/{package.NormalizedVersion}";
167+
if (PackageHelper.TryPrepareUrlForRendering(fugetUrl, out string fugetReadyUrl))
168+
{
169+
viewModel.FuGetUrl = fugetReadyUrl;
170+
}
171+
166172
viewModel.EmbeddedLicenseType = package.EmbeddedLicenseType;
167173
viewModel.LicenseExpression = package.LicenseExpression;
168174

src/NuGetGallery/ViewModels/DisplayPackageViewModel.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public class DisplayPackageViewModel : ListPackageItemViewModel
3434
public bool IsAtomFeedEnabled { get; set; }
3535
public bool IsPackageDeprecationEnabled { get; set; }
3636
public bool IsPackageVulnerabilitiesEnabled { get; set; }
37+
public bool IsFuGetLinksEnabled { get; set; }
3738
public bool IsPackageRenamesEnabled { get; set; }
3839
public bool IsGitHubUsageEnabled { get; set; }
3940
public bool IsPackageDependentsEnabled { get; set; }
@@ -77,6 +78,7 @@ public bool HasNewerRelease
7778
public RepositoryKind RepositoryType { get; private set; }
7879
public string ProjectUrl { get; set; }
7980
public string LicenseUrl { get; set; }
81+
public string FuGetUrl { get; set; }
8082
public IReadOnlyCollection<string> LicenseNames { get; set; }
8183
public string LicenseExpression { get; set; }
8284
public IReadOnlyCollection<CompositeLicenseExpressionSegment> LicenseExpressionSegments { get; set; }

src/NuGetGallery/Views/Packages/DisplayPackage.cshtml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1029,7 +1029,24 @@
10291029
<a href="@Url.ViewValidations(Model)">View validations</a>
10301030
</li>
10311031
}
1032-
</ul>
1032+
1033+
@if (Model.IsFuGetLinksEnabled && !string.IsNullOrEmpty(Model.FuGetUrl))
1034+
{
1035+
var disclaimer = "fuget.org is a 3rd party website, not controlled by Microsoft. This link is made available to you per the NuGet Terms of Use.";
1036+
1037+
<li>
1038+
<img class="icon"
1039+
aria-label="@disclaimer" title="@disclaimer"
1040+
src="@Url.Absolute("~/Content/gallery/img/fuget.svg")"
1041+
@ViewHelpers.ImageFallback(Url.Absolute("~/Content/gallery/img/fuget-32x32.png")) />
1042+
<a href="@Model.FuGetUrl" data-track="outbound-repository-url"
1043+
aria-label="open in fuget.org explorer"
1044+
title="Explore additional package info on fuget.org" rel="nofollow" target="_blank">
1045+
Open in FuGet Package Explorer
1046+
</a>
1047+
</li>
1048+
}
1049+
</ul>
10331050
@if (Model.LicenseNames.AnySafe())
10341051
{
10351052
<p>License info provided by <a href="http://sonatype.com/">Sonatype</a>.</p>

tests/NuGetGallery.Facts/ViewModels/DisplayPackageViewModelFacts.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,27 @@ public void ItInitializesProjectUrl(string projectUrl, string expected)
104104
Assert.Equal(expected, model.ProjectUrl);
105105
}
106106

107+
[Theory]
108+
[InlineData("foo", "1.0.0", "https://www.fuget.org/packages/foo/1.0.0")]
109+
[InlineData("foo", "1.1.0", "https://www.fuget.org/packages/foo/1.1.0")]
110+
[InlineData("Foo.Bar", "1.1.0-bETa", "https://www.fuget.org/packages/Foo.Bar/1.1.0-bETa")]
111+
public void ItInitializesFuGetUrl(string packageId, string packageVersion, string expected)
112+
{
113+
var package = new Package
114+
{
115+
Version = packageVersion,
116+
NormalizedVersion = packageVersion,
117+
PackageRegistration = new PackageRegistration
118+
{
119+
Id = packageId,
120+
Owners = Enumerable.Empty<User>().ToList(),
121+
Packages = Enumerable.Empty<Package>().ToList()
122+
}
123+
};
124+
125+
var model = CreateDisplayPackageViewModel(package, currentUser: null, packageKeyToDeprecation: null, readmeHtml: null);
126+
Assert.Equal(expected, model.FuGetUrl);
127+
}
107128

108129
[Theory]
109130
[InlineData(null, null)]

0 commit comments

Comments
 (0)