实现一个更新所有 dotnet tool 的 dotnet tool

实现一个更新所有 dotnet tool 的 dotnet tool

Intro

dotnet tool 是从 .NET Core 2.1 开始支持的命令行工具,在使用 dotnet tool 比较多了的时候,想要更新所有的 dotnet tool 就比较麻烦,而目前 .NET SDK 还不支持,也有一些人希望能够支持一次更新所有的 dotnet tool 这样我们就不需要一个一个地去更新了

Implement

实现思路比较简单,获取所有的 dotnet tool 并逐个进行更新

我们可以通过 dotnet tool list -g command 来获取我们安装的所有的 dotnet global tool,输出结果如下:

1a659e702097011d7d1cb194ab7165e2.png

dotnet tool list sample

第一行是一个标题,第二行是分隔线,从第三行开始是 dotnet tool 数据

第一列是 NuGet package id, 第二列是 package version, 第三列是 dotnet tool 对应的命令,我们可以获取 dotnet tool list -g  输出并从第三行开始读取数据,只需要读取第一列数据的 package id 即可

获取所有 dotnet tool list 的代码如下:

// get dotnet path
var dotnetPath = ApplicationHelper.GetDotnetPath();
// execute `dotnet tool list -g` to get all dotnet tool
var dotnetToolListOutput = await CommandExecutor.ExecuteAndCaptureAsync(dotnetPath, "tool list -g");
// output
Console.WriteLine("`dotnet tool list -g` output:");
Console.WriteLine(dotnetToolListOutput.StandardOut);

拿到输出结果之后,我们就可以得到 dotnet tool list 并开始逐个更新了,实现如下:

var dotnetToolList = dotnetToolListOutput.StandardOut.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries);
if (dotnetToolList.Length > 2)
{foreach (var tool in dotnetToolList[2..]){var toolId = tool.Split(' ', StringSplitOptions.RemoveEmptyEntries)[0].Trim();if (fullToolName.Equals(toolId)){continue;}Console.WriteLine($"update tool {toolId}...");try{await CommandExecutor.ExecuteAsync(dotnetPath, $"tool update -g {toolId}");Console.WriteLine($"update tool {toolId} completed");}catch (Exception ex){Console.WriteLine($"update tool {toolId} failed: {ex}");}}
}

至此我们的核心逻辑就基本完成了,实现效果如下:

6685c78ce7fd0784fb1827174e6db439.png

dotnet-update-all-tools

如果要发布还要准备一下 nuget package 的一些信息

<PropertyGroup><IsPackable>true</IsPackable><PackAsTool>true</PackAsTool><ToolCommandName>dotnet-update-all-tools</ToolCommandName><PackageId>dotnet-update-all-tools</PackageId><Version>1.0.0</Version>
</PropertyGroup>

PackAsTool 意味着我们要打包一个 dotnet tool

ToolCommandName是我们 tool 安装后对应的执行命令

More

上面的 ApplicationHelper.GetDotnetPath() 实现是通过扫描 PATH 找到可执行的dotne path,有些 platform 上需要 full path 才能工作,实现可以参考:https://github.com/WeihanLi/WeihanLi.Common/blob/86b6acc10f50df5867c590ca10039c1e7a8bb740/src/WeihanLi.Common/Helpers/ApplicationHelper.cs#L61

CommandExecutor 实现是起了一个进程并捕获进程输出,可以参考:https://github.com/WeihanLi/WeihanLi.Common/blob/86b6acc10f50df5867c590ca10039c1e7a8bb740/src/WeihanLi.Common/Helpers/CommandExecutor.cs#L45

最终的 dotnet tool  在 System.CommandLine的基础上包装了一下,以为了更好的体验和扩展的方便

var command = new Command(toolName);
command.SetHandler(async () =>
{// 前面的逻辑在这里
});
await command.InvokeAsync(args);

自此我们的 dotnet tool 就完成了

可以通过下面的命令来进行安装

dotnet tool install --global dotnet-update-all-tools

安装好之后执行 dotnet-update-all-tools 即可更新所有的 dotnet tool 了

References

  • https://www.nuget.org/packages/dotnet-update-all-tools

  • https://github.com/WeihanLi/SamplesInPractice/tree/master/CommandLineAppSamples/UpgradeAllTools

  • https://github.com/WeihanLi/WeihanLi.Common/blob/86b6acc10f50df5867c590ca10039c1e7a8bb740/src/WeihanLi.Common/Helpers/ApplicationHelper.cs#L61

  • https://github.com/WeihanLi/WeihanLi.Common/blob/86b6acc10f50df5867c590ca10039c1e7a8bb740/src/WeihanLi.Common/Helpers/CommandExecutor.cs#L45

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/280666.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[AHOI2009]飞行棋 BZOJ1800

题目描述 给出圆周上的若干个点&#xff0c;已知点与点之间的弧长&#xff0c;其值均为正整数&#xff0c;并依圆周顺序排列。 请找出这些点中有没有可以围成矩形的&#xff0c;并希望在最短时间内找出所有不重复矩形。 输入输出格式 输入格式&#xff1a;第一行为正整数N&…

webapi+Quartz.NET解决若干定时程序同时运行的问题

项目现状&#xff1a; 有若干定时程序需要自启动运行&#xff0c;为了简便程序部署等问题&#xff0c;采取这种办法把定时程序集中管理到webapi中跟随api发布 代码架构介绍&#xff1a; 新建一个类库&#xff0c;类库引用Quartz&#xff08;Quartz.2.3.2&#xff09;&#xff0…

mac恢复iphone_免费下载:旧Mac和iPhone壁纸的令人震惊的完整档案

mac恢复iphoneLove or hate Apple, you’ve got to admit: their background images are consistently stunning. Now you can download all of them. 爱或恨苹果&#xff0c;您必须承认&#xff1a;它们的背景图像始终令人赞叹。 现在&#xff0c;您可以下载所有这些文件。 A …

Magicodes.IE 2.7.1发布

2.7.12022.12.01Magicodes.IE.EPPlus默认添加SkiaSharp.NativeAssets.Linux.NoDependencies包&#xff0c;以便于在Linux环境下使用导入验证支持将错误数据通过Stream的方式返回&#xff0c;感谢sampsonye &#xff08;见pr#466&#xff09;2.7.02022.11.07添加SkiaSharp移除Si…

Comcast以纯文本泄露客户Wi-Fi登录信息,立即更改密码

A Comcast Xfinity website was leaking Wi-Fi names and passwords, meaning now is a good time to change your Wi-Fi passcode. Comcast Xfinity网站泄漏了Wi-Fi名称和密码&#xff0c;这意味着现在是更改Wi-Fi密码的好时机。 The site, intended to help new customers se…

龙芯上跑WTM,为国产化做点贡献

点击上方蓝字关注我哦“信创”&#xff0c;是一项国家战略&#xff0c;即信息技术应用创新产业&#xff0c;它是数据安全、网络安全的基础&#xff0c;也是新基建的重要组成部分。信创从名称上来看本意指向创新&#xff0c;但是自从漂亮国亲手撕碎了“科技没有国界”的谎言之后…

PHP安装之configure的配置参数

1、生成环境安装配置如下 要求安装如下库&#xff1a; imagickgdmysqlmysqlimysqlndphalconPharsoapsocketsxwebxsvczipzlib 具体查看 vim php-config 就可以知道是如何配置的 --prefix/home/php --with-config-file-path/home/php/etc --with-mysql --with-pdo-oci --with-ope…

Django05: 请求生命周期流程图/路由层

请求生命周期流程图 扩展知识&#xff1a; 缓存数据库 路由层 路由匹配 url(r^test/, views.test), 1. 第一个参数是正则匹配。 只要第一个匹配了&#xff0c;就不会执行下面。 输入url会默认加斜杠&#xff0c;django会重定向 a. 一次匹配不行 b. url再加斜杠匹配 可以…

facebook 分享页面_Facebook个人资料,页面和组之间有什么区别?

facebook 分享页面Facebook is used by a lot of different people for a lot of different things, so it’s only natural that Facebook would have different sets of features for each of them. There are three main ways you can use Facebook: with a regular Profile…

一句话设计原则

面向对象的可复用设计&#xff08; Object Oriented Design / OOD&#xff09; 1. 开闭原则 (Open Closed Principle) 对扩展开放&#xff0c;对修改关闭 2. 里氏代换原则(LSP) 1.可以使用基类的地方&#xff0c;其子类必然也能使用 2.并且原功能不会受到任何影响 -- 经典案例,…

postman--安装及Interceptor插件

1. 官网安装&#xff08;看网速-我下载的时候一直下载失败&#xff09;打开官网&#xff0c;https://www.getpostman.com选择ios或者win 2. 非官网安装 https://pan.baidu.com/s/1mstsimqO3ZC5m9z8czxVnA 密码&#xff1a;q6yp 安装postman 3.需要安装分享的蓝灯安装包&#xf…

亚马逊标题自动抓取_如何为您的家人提供自动Amazon礼品卡津贴

亚马逊标题自动抓取When your kids move away to go to school, they’ll probably phone home every once in a while to ask for money. If they shop a lot on Amazon (and they probably do), you can expedite that process by setting up an automatically recurring dep…

我 与 TDesignBlazor 的故事

前言作者打拼了 .NET 十多年&#xff0c;属于全栈应用类型的工程师&#xff0c;特别是对于前端的技术情有独钟&#xff0c;从纯js到jquery&#xff0c;从bootstrap到自己写css&#xff0c;从web到winform&#xff0c;还写过一段时间的knockout.js&#xff0c;以至于公司里的前端…

实验数据

1.整段deng音频200多秒 2.加xx(1000:1480)之后 转载于:https://www.cnblogs.com/20179302yzl/p/10270632.html

mysql中查询一个字段属于哪一个数据库中的哪一个表的方式

mysql中查询一个字段具体是属于哪一个数据库的那一张表&#xff1a;用这条语句就能查询出来,其中 table_schema 是所在库, table_name 是所在表 --mysql中查询某一个字段名属于哪一个库中的哪一张表 select table_schema,table_name from information_schema.columns where col…

macos剪切_如何使用macOS的内置“ Kill and Yank”作为替代剪切和粘贴

macos剪切Everyone knows about cutting and pasting by now. But did you know that your Mac sort of has a second clipboard known as kill and yank? 现在&#xff0c;每个人都知道剪切和粘贴。 但是您是否知道Mac上还有第二个剪贴板&#xff0c;称为“ kill and yank”&…

ExtJS 折线图趟过的坑

问题&#xff1a; 1、根据条件检索后绘制折线图&#xff0c;之前的坐标没有清除如图 解决方案&#xff1a; 在绘制之前&#xff0c;清空坐票&#xff1a; leftLine.surface.removeAll(); leftLine.redraw(false); 完整代码如下 storeBar.load({params: { SDate: bTime, EDate: …

Django的第一步(第一节)

写下你的第一个Django应用第一部分让我们通过例子来学习.在本教程中&#xff0c;我们将引导您完成基本投票应用程序的创建.其中包括两部分:一个让人们查看民意调查并投票的公共网站.允许您添加&#xff0c;更改和删除民意调查的管理网站.我们假设你django已经安装好了,你可以通…

ad中电源插座怎么封装_您可以在房屋中安装的各种电源插座

ad中电源插座怎么封装You may already know about smart outlets, or outlets with integrated USB ports. But you might be surprised at how many “normal” outlets you can actually buy for your house. They’re all built for different situations, and you want to …

Django05-2:路由分发/命名空间/伪静态/虚拟环境/django版本区别

路由分发 补充&#xff1a;每一个应用可以有独立的templates模板文件夹&#xff0c;static静态文件加&#xff0c;urls.py 总路由 #方法一from app01 import urls as app01_urls from app02 import urls as app02_urlsurlpatterns [url(r^publisher_list/, views.publisher_…