目錄
什麼是Frosting?
入門
适應Frosting
别名
目錄/檔案
插件和工具
概括
Frosting中的代碼更加冗長,别名和目錄不那麼友善。但是,您将得到的強類型的、可維護的代碼可能是值得的,特别是在大型項目中。
Cake V1.0于本周釋出了,它Frosting的更新版,這是一種用整個團隊都能了解的語言編寫DevOps的更健壯的技術。時機太棒了,因為上周,我剛剛釋出了“我希望在使用Cake之前知道的一件事”,其中我警告說更傳統的build.cake檔案的增長不受控制。我在那裡提供的解決方案仍然存在,但是Cake Frosting為子產品化、封裝性和可維護性提供了更好的解決方案。如果您準備接受一些折衷方案,那麼工具也将更好。
什麼是Frosting?
Cake Frosting是Cake的四個“運作器”之一,它們是運作Cake并獲得其龐大的插件生态系統和“依賴關系管理”模式的通路方式,在此模式中,您可以定義任務及其依賴關系,而不是線性運作C#代碼。四個選項是:
- .NET工具
- .NET Framework
- .NET Core,以及
- Frosting
前三個需要使用Cake團隊建立的DSL(一種域特定語言)進行建構,以删除不必要的C#Chrome,并使您的C#DevOps代碼簡潔明了。
最後一個允許您放棄傳統的Cake DSL,而是在.NET控制台應用程式内添加Cake上下文和一些自定義屬性來編寫DevOps 。
本質上,我們不需要像這樣編寫DSL:
projDir = Directory("./src");
Task("Build")
.IsDependentOn("Clean")
.Does(() =>
{
DotNetCoreBuild(projDir)
});
使用Frosting,您可以這樣編寫:
// Cake DSL aliases like DotNetCoreBuild are extension methods off ICakeContext
using Cake.Common.Tools.DotNetCore;
[TaskName("Build")]
[IsDependentOn(typeof(CleanTask))]
public sealed class BuildTask : AsyncFrostingTask<BuildContext> {
public override Task RunAsync(BuildContext context) {
var projDir = context.Directory("./src");
context.DotNetCoreBuild(projDir);
return Task.FromResult(true);
}
}
當然,我抛出了一些不必要的異步來表示對它的支援,但是相比之下,它看起來仍然冗長得多。那是很大的缺點。
但是,以這種冗長的交換,您将獲得具有推斷的所有子產品化、封裝性和可維護性的C#類。此外,它是強類型的,是以與DSL不同,如果您鍵入錯誤的變量、方法或别名,該工具可以可靠地告訴您編譯之前的資訊,更不用說運作之前了。而且Intellisense的工作可靠。甚至更好的是,您可以進行重構和靜态分析,如果您喜歡這種方法,還可以使用ReSharper。
最後:檢視第5行中具有強類型依賴管理的地方。是以,Cake運作期不僅會確定當您運作BuildTask時,CleanTask及其任何依賴都會運作(并且隻運作一次),而且如果會CleanTask被重新命名,它會給出一個編譯器錯誤。
入門
Frosting設定文檔相當簡單,但是快速回顧一下:
先決條件:
- .NET Core 3.1.301或更高版本
- Mac、Windows或Linux
1、安裝Cake.Frosting.Template,這是一個.NET工具模闆包,可讓您快速建立新的Frosting項目。這是全局的,您隻需要執行一次。
dotnet new --install Cake.Frosting.Template
2、轉到一個空檔案夾,然後根據上方的Frosting模闆建立一個項目:
dotnet new cakefrosting
3、使用PowerShell或Bash引導程式運作它:
.\build.ps1 --target=Default
./build.sh --target=Default
就這樣,Cake剛剛執行了一個“Default”任務,其相關的World任務和其相關的Hello任務。
如果調查生成的檔案,将看到兩個引導程式,以及一個帶有.csproj和Program.cs檔案的/ build檔案夾。
Program.cs相當于Cake的傳統的build.cake檔案,除了添加了用于設定BuildContext對象的額外代碼之外。
适應Frosting
如果您來自Cake DSL世界,那麼您需要做好一些調整代碼的準備。
别名
DSL世界中的所有别名實際上都是上下文對象的擴充方法。是以,在Frosting中,您将需要知道名稱空間并有權通路上下文對象。
例如,如果您嘗試通路該CleanDirectories指令,例如CleanDirectories(".bin"),遞歸地删除所有bin目錄中的所有内容,則需要執行以下操作:
- 導入Cake.Common.IO名稱空間,如文檔頁面所示
- 從ICakeContext對象調用指令(例如context.CleanDirectories(".bin");)
目錄/檔案
如果您習慣了Cake的便利,ConvertableDirectories和ConvertableFiles可以在其中将檔案和目錄連接配接在一起,例如:
var projectDir = Directory("./project/");
var subProjectDir = projectDir + Directory("subproject");
var subProjectCsProj = subProjectDir + File("subproj.csproj")
然後可悲的是,您會發現“Frosting”更為冗長。它需要将那些對象儲存在Context對象的構造函數中。
public class BuildContext : FrostingContext
{
public ConvertableDirectoryPath ProjDir { get; set; }
public ConvertableDirectoryPath SubProjDir { get; set; }
public ConvertableFilePath SubProjCsProj { get; set; }
public BuildContext(ICakeContext context)
: base(context)
{
ProjDir = context.Directory("./project");
SubProjDir = ProjDir + context.Directory("subproj");
SubProjCsProj = SubProjDir + context.File("subproject.csproj");
}
}
這種便利可能值得,也可能不值得。
插件和工具
幸運的是,有些事情幾乎一樣簡單。使用DSL通路插件是一個指令在檔案的頂部:
#addin "nuget:?package=Cake.AzureCli&version=1.2.0"
(噓,那是我正在悄悄插入的開源AzureCli Cake插件。)
Frosting的替代方法是僅通過NuGet引用項目。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Cake.AzureCli" Version="1.2.0" />
<PackageReference Include="Cake.Frosting" Version="1.0.0" />
</ItemGroup>
</Project>
工具隻是稍微複雜一點,需要調用Main()中的InstallTool:
public static class Program
{
public static int Main(string[] args)
{
return new CakeHost()
.UseContext<BuildContext>()
.InstallTool(new Uri("nuget:?package=ReportGenerator&version=4.8.1"))
.Run(args);
}
}
概括
我是Frosting的忠實擁護者,但目前應該權衡利弊。代碼更加冗長,别名和目錄之類的許多便利都不那麼友善。但是您會得到的強類型、可維護的代碼可能是值得的,尤其是在較大的項目上。更重要的是,進入項目兩年後,您肯定不會意外地得到2000行的build.cake檔案。
https://www.codeproject.com/Articles/5295180/Cake-Frosting-More-Maintainable-Csharp-DevOps