天天看点

Cake Frosting:更具可维护性的C#DevOps什么是Frosting?入门适应Frosting别名目录/文件插件和工具概括

目录

什么是Frosting?

入门

适应Frosting

别名

目录/文件

插件和工具

概括

Frosting中的代码更加冗长,别名和目录不那么方便。但是,您将得到的强类型的、可维护的代码可能是值得的,特别是在大型项目中。

Cake Frosting:更具可维护性的C#DevOps什么是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任务。

Cake Frosting:更具可维护性的C#DevOps什么是Frosting?入门适应Frosting别名目录/文件插件和工具概括

如果调查生成的文件,将看到两个引导程序,以及一个带有.csproj和Program.cs文件的/ build文件夹。

Cake Frosting:更具可维护性的C#DevOps什么是Frosting?入门适应Frosting别名目录/文件插件和工具概括

Program.cs相当于Cake的传统的build.cake文件,除了添加了用于设置BuildContext对象的额外代码之外。

Cake Frosting:更具可维护性的C#DevOps什么是Frosting?入门适应Frosting别名目录/文件插件和工具概括

适应Frosting

如果您来自Cake DSL世界,那么您需要做好一些调整代码的准备。

别名

DSL世界中的所有别名实际上都是上下文对象的扩展方法。因此,在Frosting中,您将需要知道名称空间并有权访问上下文对象。

例如,如果您尝试访问该CleanDirectories命令,例如CleanDirectories(".bin"),递归地删除所有bin目录中的所有内容,则需要执行以下操作:

  1. 导入Cake.Common.IO名称空间,如文档页面所示
  2. 从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

继续阅读