Skip to content

Commit 65907b4

Browse files
Implementation of Cake tab with instructions for NuGet packages (#8434)
* Add installation instructions for Cake for Addin, Module, Recipe Co-authored-by: Nils Andresen <[email protected]> Related to #8381
1 parent 6080e08 commit 65907b4

8 files changed

Lines changed: 277 additions & 2 deletions

File tree

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

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

src/Bootstrap/dist/js/bootstrap.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*!
22
* Bootstrap v3.4.1 (https://getbootstrap.com/)
3-
* Copyright 2011-2020 Twitter, Inc.
3+
* Copyright 2011-2021 Twitter, Inc.
44
* Licensed under the MIT license
55
*/
66

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@
303303
border-width: 1px 0 1px 1px;
304304
user-select: all;
305305
vertical-align: middle;
306+
word-break: break-word;
306307
}
307308

308309
.copy-button {
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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.Linq;
6+
7+
namespace NuGetGallery
8+
{
9+
public static class CakeBuildManagerExtensions
10+
{
11+
public static bool IsCakeExtension(this DisplayPackageViewModel model)
12+
{
13+
return IsCakeAddin(model) || IsCakeModule(model) || IsCakeRecipe(model);
14+
}
15+
16+
public static string GetCakeInstallPackageCommand(this DisplayPackageViewModel model)
17+
{
18+
var reference = $"nuget:?package={model.Id}&version={model.Version}";
19+
20+
if (model.Prerelease)
21+
{
22+
reference += "&prerelease";
23+
}
24+
25+
if (IsCakeAddin(model))
26+
{
27+
return $"#addin {reference}";
28+
}
29+
30+
if (IsCakeModule(model))
31+
{
32+
return $"#module {reference}";
33+
}
34+
35+
if (IsCakeRecipe(model))
36+
{
37+
return $"#load {reference}";
38+
}
39+
40+
return string.Join(Environment.NewLine,
41+
$"// Install {model.Id} as a Cake Addin",
42+
$"#addin {reference}",
43+
"",
44+
$"// Install {model.Id} as a Cake Tool",
45+
$"#tool {reference}"
46+
);
47+
}
48+
49+
private static bool IsCakeAddin(ListPackageItemViewModel model) =>
50+
model.Tags?.Contains("cake-addin", StringComparer.OrdinalIgnoreCase) ?? false;
51+
52+
private static bool IsCakeModule(ListPackageItemViewModel model) =>
53+
model.Tags?.Contains("cake-module", StringComparer.OrdinalIgnoreCase) ?? false;
54+
55+
private static bool IsCakeRecipe(ListPackageItemViewModel model) =>
56+
model.Tags?.Contains("cake-recipe", StringComparer.OrdinalIgnoreCase) ?? false;
57+
}
58+
}

src/NuGetGallery/NuGetGallery.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@
212212
<Compile Include="Controllers\ExperimentsController.cs" />
213213
<Compile Include="Controllers\ManageDeprecationJsonApiController.cs" />
214214
<Compile Include="ExtensionMethods.cs" />
215+
<Compile Include="Extensions\CakeBuildManagerExtensions.cs" />
215216
<Compile Include="Extensions\ImageExtensions.cs" />
216217
<Compile Include="Helpers\ValidationHelper.cs" />
217218
<Compile Include="Helpers\ViewModelExtensions\DeleteAccountListPackageItemViewModelFactory.cs" />

src/NuGetGallery/Views/Packages/DisplayPackage.cshtml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
InstallPackageCommand = string.Format("dotnet tool install --global {0} --version {1}", Model.Id, Model.Version),
3636
AlertLevel = AlertLevel.Info,
3737
AlertMessage = "This package contains a <a href='https://aka.ms/global-tools'>.NET Core Global Tool</a> you can call from the shell/command line.",
38-
}
38+
},
3939
};
4040
}
4141
else if (Model.IsDotnetNewTemplatePackageType)
@@ -103,6 +103,12 @@
103103
"For F# scripts that support <a href=\"{0}\">#r syntax</a>, copy this into the source code to reference the package.",
104104
"https://docs.microsoft.com/en-us/dotnet/fsharp/tools/fsharp-interactive/#referencing-packages-in-f-interactive")
105105
},
106+
107+
new ThirdPartyPackageManagerViewModel("Cake", "https://cakebuild.net/support/nuget")
108+
{
109+
Id = Model.IsCakeExtension() ? "cake-extension" : "cake",
110+
InstallPackageCommand = Model.GetCakeInstallPackageCommand()
111+
},
106112
};
107113
}
108114
}
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
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.Collections.Generic;
5+
using System.Linq;
6+
using Xunit;
7+
8+
namespace NuGetGallery.Extensions
9+
{
10+
public class CakeBuildManagerExtensionsFacts
11+
{
12+
public class TheMethodIsCakeExtension
13+
{
14+
public class GivenAPackageWithKnownCakeTags
15+
{
16+
[Theory]
17+
[MemberData(nameof(PackageTagsKnownToBeCakeExtensions), MemberType = typeof(CakeBuildManagerExtensionsFacts))]
18+
public void ReturnsTrue(string[] tags)
19+
{
20+
var model = new DisplayPackageViewModel
21+
{
22+
Tags = tags,
23+
};
24+
25+
var actual = model.IsCakeExtension();
26+
27+
Assert.True(actual);
28+
}
29+
}
30+
31+
public class GivenAPackageWithoutAnyKnownCakeTags
32+
{
33+
[Theory]
34+
[MemberData(nameof(PackageTagsNotKnownToBeCakeExtensions), MemberType = typeof(CakeBuildManagerExtensionsFacts))]
35+
public void ReturnsFalse(string[] tags)
36+
{
37+
var model = new DisplayPackageViewModel
38+
{
39+
Tags = tags,
40+
};
41+
42+
var actual = model.IsCakeExtension();
43+
44+
Assert.False(actual);
45+
}
46+
}
47+
}
48+
49+
public class TheMethodGetCakeInstallPackageCommand
50+
{
51+
public class GivenAPackageWithTheCakeAddinTag
52+
{
53+
[Fact]
54+
public void ReturnsAnAddinDirective()
55+
{
56+
var model = new DisplayPackageViewModel
57+
{
58+
Id = "Cake.7zip",
59+
Version = "1.0.0",
60+
Tags = new[] { "cake-addin" },
61+
};
62+
63+
var actual = model.GetCakeInstallPackageCommand();
64+
65+
Assert.Equal("#addin nuget:?package=Cake.7zip&version=1.0.0", actual);
66+
}
67+
68+
[Fact]
69+
public void ReturnsAnAddinDirectiveWithPrerelease()
70+
{
71+
var model = new DisplayPackageViewModel
72+
{
73+
Id = "Cake.7zip",
74+
Version = "1.0.0",
75+
Tags = new[] { "cake-addin" },
76+
Prerelease = true,
77+
};
78+
79+
var actual = model.GetCakeInstallPackageCommand();
80+
81+
Assert.Equal("#addin nuget:?package=Cake.7zip&version=1.0.0&prerelease", actual);
82+
}
83+
}
84+
85+
public class GivenAPackageWithTheCakeModuleTag
86+
{
87+
[Fact]
88+
public void ReturnsAModuleDirective()
89+
{
90+
var model = new DisplayPackageViewModel
91+
{
92+
Id = "Cake.BuildSystems.Module",
93+
Version = "1.0.0",
94+
Tags = new[] {"cake-module"},
95+
};
96+
97+
var actual = model.GetCakeInstallPackageCommand();
98+
99+
Assert.Equal("#module nuget:?package=Cake.BuildSystems.Module&version=1.0.0", actual);
100+
}
101+
102+
[Fact]
103+
public void ReturnsAModuleDirectiveWithPrerelease()
104+
{
105+
var model = new DisplayPackageViewModel
106+
{
107+
Id = "Cake.BuildSystems.Module",
108+
Version = "1.0.0",
109+
Tags = new[] { "cake-module" },
110+
Prerelease = true,
111+
};
112+
113+
var actual = model.GetCakeInstallPackageCommand();
114+
115+
Assert.Equal("#module nuget:?package=Cake.BuildSystems.Module&version=1.0.0&prerelease", actual);
116+
}
117+
}
118+
119+
public class GivenAPackageWithTheCakeRecipeTag
120+
{
121+
[Fact]
122+
public void ReturnsALoadDirective()
123+
{
124+
var model = new DisplayPackageViewModel
125+
{
126+
Id = "Cake.Recipe",
127+
Version = "1.0.0",
128+
Tags = new[] { "cake-recipe" },
129+
};
130+
131+
var actual = model.GetCakeInstallPackageCommand();
132+
133+
Assert.Equal("#load nuget:?package=Cake.Recipe&version=1.0.0", actual);
134+
}
135+
136+
[Fact]
137+
public void ReturnsALoadDirectiveWithPrerelease()
138+
{
139+
var model = new DisplayPackageViewModel
140+
{
141+
Id = "Cake.Recipe",
142+
Version = "1.0.0",
143+
Tags = new[] { "cake-recipe" },
144+
Prerelease = true,
145+
};
146+
147+
var actual = model.GetCakeInstallPackageCommand();
148+
149+
Assert.Equal("#load nuget:?package=Cake.Recipe&version=1.0.0&prerelease", actual);
150+
}
151+
}
152+
153+
public class GivenAPackageWithoutAnyKnownCakeTags
154+
{
155+
[Theory]
156+
[MemberData(nameof(PackageTagsNotKnownToBeCakeExtensions), MemberType = typeof(CakeBuildManagerExtensionsFacts))]
157+
public void ReturnsMultipleDirectives(string[] tags)
158+
{
159+
var model = new DisplayPackageViewModel
160+
{
161+
Id = "Polly",
162+
Version = "1.0.0",
163+
Tags = tags,
164+
};
165+
166+
var actual = model.GetCakeInstallPackageCommand();
167+
168+
Assert.Contains("#addin nuget:?package=Polly&version=1.0.0", actual);
169+
Assert.Contains("#tool nuget:?package=Polly&version=1.0.0", actual);
170+
}
171+
172+
[Theory]
173+
[MemberData(nameof(PackageTagsNotKnownToBeCakeExtensions), MemberType = typeof(CakeBuildManagerExtensionsFacts))]
174+
public void ReturnsMultipleDirectivesWithPrerelease(string[] tags)
175+
{
176+
var model = new DisplayPackageViewModel
177+
{
178+
Id = "Polly",
179+
Version = "1.0.0",
180+
Tags = tags,
181+
Prerelease = true,
182+
};
183+
184+
var actual = model.GetCakeInstallPackageCommand();
185+
186+
Assert.Contains("#addin nuget:?package=Polly&version=1.0.0&prerelease", actual);
187+
Assert.Contains("#tool nuget:?package=Polly&version=1.0.0&prerelease", actual);
188+
}
189+
}
190+
}
191+
192+
public static IEnumerable<object[]> PackageTagsKnownToBeCakeExtensions => new[]
193+
{
194+
new[] { "cake-addin" },
195+
new[] { "cake-module" },
196+
new[] { "cake-recipe" },
197+
}.Select(tags => new object[] { tags });
198+
199+
public static IEnumerable<object[]> PackageTagsNotKnownToBeCakeExtensions => new[]
200+
{
201+
null,
202+
new string[0],
203+
new string[] { null },
204+
new[] { "json" },
205+
}.Select(tags => new object[] { tags });
206+
}
207+
}

tests/NuGetGallery.Facts/NuGetGallery.Facts.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
<Compile Include="Authentication\AuthenticationServiceFacts.cs" />
8080
<Compile Include="Authentication\Providers\CommonAuth\AzureActiveDirectoryV2AuthenticatorFacts.cs" />
8181
<Compile Include="Authentication\TestCredentialHelper.cs" />
82+
<Compile Include="Extensions\CakeBuildManagerExtensionsFacts.cs" />
8283
<Compile Include="Helpers\ValidationHelperFacts.cs" />
8384
<Compile Include="Infrastructure\ODataCacheOutputAttributeFacts.cs" />
8485
<Compile Include="Queries\AutocompleteDatabasePackageIdsQueryFacts.cs" />

0 commit comments

Comments
 (0)