Spectre.Console-实现自己的CLI

Spectre,CLI,Console · 浏览次数 : 266

小编点评

## GTD 项目 CLI 实现指南 **引言:** 由于每个人的习惯和工作流都不一样,创建个性化的 GTD 项目管理工具可以提升效率。本文介绍使用 C# 创建 CLI,记录和分析项目执行时间,并按照 GTD 工作流程进行管理的方案。 **技术选择:** 由于前端技术选型Ainda,但希望实现类似 dotnet、git 之类的 CLI,所以选择以下技术: * Spectre.Console:美化 Console 输出 * CommandLineArguments:处理命令行参数 * Spectre.Console.Cli:支持层级命令 **核心功能:** * 记录项目执行时间 * 按时间分组执行时间 * 按任务分组执行时间 * 提供统计信息 **核心结构:** ```csharp using Spectre.Console.Cli; namespace MyApp { public static class Program { public static int Main(string[] args) { // Configure Spectre.Console var app = new CommandApp(); // Configure command settings var settings = new AddSettings() { Project = "MyProject", Package = "MyPackage.dll" }; // Run the command return app.Run(args, settings); } } } ``` **使用说明:** 1. 创建一个新项目,并添加以下代码: ```csharp using Spectre.Console.Cli; namespace MyApp { public static class Program { public static int Main(string[] args) { // Configure Spectre.Console var app = new CommandApp(); // Configure command settings var settings = new AddPackageSettings() { Project = "MyProject", Package = "MyPackage.dll" }; // Run the command return app.Run(args, settings); } } } ``` 2. 运行程序,可以看到以下输出: ``` Total file size for MyPackage.dll files in MyProject: 12345 bytes Package successfully added! ``` **总结:** 本文展示了如何使用 C# 创建 CLI,记录和分析项目执行时间,并按照 GTD 工作流程进行管理的方案。该方案适用于各种项目,可帮助您提升项目管理效率。

正文

引言

最近发现自己喜欢用的 Todo 软件总是差点意思,毕竟每个人的习惯和工作流不太一样,我就想着自己写一个小的Todo 项目,核心的功能是自动记录 Todo 执行过程中消耗的时间(尤其面向程序员),按照自己的想法实现一套 GTD 工作流。

不想写 WinformWPF 也写腻了,就想着学学 MAUIAvaloniaUno Platformblazor 之类的。由于前端技术选型纠结,迟迟动不了手,想想还是暂时先不弄了。但为了测试,没有个界面总是不太行,先搞一个 CLI 吧。

更新:由于想让程序持续执行,所以后面还是替换了 CLI 。

Spectre. Console

Spectre.Console(spectreconsole.net) 是一个美化 Console 输出的类库,通过它可以实现丰富多样的 Console 输出。核心的特性有这些:

  • 格式化输出文本(支持斜体等)
  • 支持对文字着色
  • 渲染复杂的组件(表格、结构树、ASCII 图片)
  • 显示进度条与状态
  • 强类型输入验证
  • 对 exception 输出着色

除此以外,它还提供了一个 Spectre.Console.Cli 类库,可以帮助我们实现类似 dotnetgit 之类的 CLI(Command Line Interface)。

基本用法

这里使用官方的示例:

var app = new CommandApp<FileSizeCommand>();
return app.Run(args);

internal sealed class FileSizeCommand : Command<FileSizeCommand.Settings>
{
    public sealed class Settings : CommandSettings
    {
        [Description("Path to search. Defaults to current directory.")]
        [CommandArgument(0, "[searchPath]")]
        public string? SearchPath { get; init; }

        [CommandOption("-p|--pattern")]
        public string? SearchPattern { get; init; }

        [CommandOption("--hidden")]
        [DefaultValue(true)]
        public bool IncludeHidden { get; init; }
    }

    public override int Execute([NotNull] CommandContext context, [NotNull] Settings settings)
    {
        var searchOptions = new EnumerationOptions
        {
            AttributesToSkip = settings.IncludeHidden
                ? FileAttributes.Hidden | FileAttributes.System
                : FileAttributes.System
        };

        var searchPattern = settings.SearchPattern ?? "*.*";
        var searchPath = settings.SearchPath ?? Directory.GetCurrentDirectory();
        var files = new DirectoryInfo(searchPath)
            .GetFiles(searchPattern, searchOptions);

        var totalFileSize = files
            .Sum(fileInfo => fileInfo.Length);

        AnsiConsole.MarkupLine($"Total file size for [green]{searchPattern}[/] files in [green]{searchPath}[/]: [blue]{totalFileSize:N0}[/] bytes");

        return 0;
    }
}

结构非常简单,标有 [CommandOption("xxx")] 会自动将参数归类,通过下列命令进行调用。

app.exe
app.exe c:\windows
app.exe c:\windows --pattern *.dll
app.exe c:\windows --hidden --pattern *.dll

多命令

上面这个示例只支持一个默认的命令,但是一般的 CLI 都有很多支持的命令,需要调整一下实现:

var app = new CommandApp();
app.Configure(config =>
{
    config.AddCommand<AddCommand>("add");
    config.AddCommand<CommitCommand>("commit");
    config.AddCommand<RebaseCommand>("rebase");
});

层级命令

更复杂一点的,比如 dotnet add packagedotnet add reference 这种,add 后面还有 package 这个子命令,上面的方法还得继续拓展,首先定义 add 基类和 package 与 reference 继承类。

public class AddSettings : CommandSettings
{
    [CommandArgument(0, "[PROJECT]")]
    public string Project { get; set; }
}

public class AddPackageSettings : AddSettings
{
    [CommandArgument(0, "<PACKAGE_NAME>")]
    public string PackageName { get; set; }

    [CommandOption("-v|--version <VERSION>")]
    public string Version { get; set; }
}

public class AddReferenceSettings : AddSettings
{
    [CommandArgument(0, "<PROJECT_REFERENCE>")]
    public string ProjectReference { get; set; }
}

然后对不同的命令,指定不同处理函数。

public class AddPackageCommand : Command<AddPackageSettings>
{
    public override int Execute(CommandContext context, AddPackageSettings settings)
    {
        // Omitted
        return 0;
    }
}

public class AddReferenceCommand : Command<AddReferenceSettings>
{
    public override int Execute(CommandContext context, AddReferenceSettings settings)
    {
        // Omitted
        return 0;
    }
}

最后使用 AddBranch 进行组合:

using Spectre.Console.Cli;

namespace MyApp
{
    public static class Program
    {
        public static int Main(string[] args)
        {
            var app = new CommandApp();

            app.Configure(config =>
            {
                config.AddBranch<AddSettings>("add", add =>
                {
                    add.AddCommand<AddPackageCommand>("package");
                    add.AddCommand<AddReferenceCommand>("reference");
                });
            });

            return app.Run(args);
        }
    }
}

参考

与Spectre.Console-实现自己的CLI相似的内容:

Spectre.Console-实现自己的CLI

## 引言 最近发现自己喜欢用的 Todo 软件总是差点意思,毕竟每个人的习惯和工作流不太一样,我就想着自己写一个小的[Todo 项目]( https://github.com/circler3/TodoTrack ),核心的功能是自动记录 Todo 执行过程中消耗的时间(尤其面向程序员),按照自己

Spectre.Console-处理依赖注入

## 引言 之前说的做自动记录 Todo 执行过程中消耗的时间的[Todo 项目]( https://github.com/circler3/TodoTrack ),由于想持续保持程序执行,就放弃了 `Spectre.Console.Cli`,后来随着命令越来越多,自己处理觉得很是麻烦,想了想要不试

使用Terminal.Gui构建功能强大的.NET控制台应用

前言 前段时间分享了一个库帮你轻松的创建漂亮的.NET控制台应用程序 - Spectre.Console的文章教程,然后就有小伙伴提问:.NET控制台应用需要应对强交互性的场景,有什么好的解决方案?,今天大姚给大家分享一款适用于.NET的跨平台终端 UI 工具包,帮助大家快速构建功能强大的.NET控

[转帖]迟到的Meltdown/Spectre分析

https://zhuanlan.zhihu.com/p/263081764 Meltdown/Spectre在2018年初闹得沸沸扬扬, 可以说是有史以来最有影响的cpu漏洞了. 当时有过简单了解, 但是不够深入, 这两天重新又看了一下. 背景知识 乱序执行 cpu的乱序执行一般都使用Tomasu

[转帖]【文章导读】什么是旁道攻击?Meltdown Redux英特尔漏洞(MDS攻击);KAISER:从用户空间隐藏内核(KAISER);Meltdown/Spectre分析

Table of Contents 黑客词典:什么是旁道攻击? Meltdown Redux:Intel缺陷使黑客窃取了数百万台PC的秘密 三重熔毁:有多少研究人员同时发现了20年的芯片缺陷 KAISER:从用户空间隐藏内核 迟到的Meltdown/Spectre分析 黑客词典:什么是旁道攻击? h

一个库帮你轻松的创建漂亮的.NET控制台应用程序

前言 做过.NET控制台应用程序的同学应该都知道原生的.NET控制台应用程序输出的内容都比较的单调,假如要编写漂亮且美观的控制台输出内容或者样式可能需要花费不少的时间去编写代码和调试。今天大姚给大家分享一个.NET开源且免费的类库帮你轻松的创建漂亮、美观的.NET控制台应用程序:Spectre.Co