实现一个更新所有 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,一经查实,立即删除!

相关文章

C# 普通权限运行程序\非管理员运行\降低权限运行

一、目的与实际 1.VS设置管理员权限运行程序后&#xff0c;发现调用powershell命令或程序需要普通权限即可&#xff0c;Administrator权限反而错。 2.网上搜索关键字&#xff0c;大部分都是怎么使用管理员权限运行。 3.bing搜索意外发现有相关资料&#xff0c;记录分享。 二…

am335x PDK3.0 设置为单网口配置记录

原来的配置是双网口的&#xff0c;现在要配置为单网口。一直以为这个配置是在 make menuconfig 里面&#xff0c; 没想到是在设备树里面。修改设备树// vim arch/arm/boot/dts/am335x-sbc7109.dts722 &mac {723 pinctrl-names "default", "sleep"…

[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 …

Django01-1: request 方法

#POST request.method #返回全大写字符穿&#xff0c;<class str> POST/GETrequest.POST #用户提交数据&#xff0c;不包含文件 #<QueryDict>request.POST.get(hobby) #拿列表最后一个 request.POST.getList(hobby) #拿多个&#xff0c;列表全部#GET 获取url &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…

Oracle监听的静态注册和动态注册

静态注册&#xff1a;通过解析listene.ora文件 动态注册&#xff1a;由PMON进程动态注册至监听中 在没有listener.ora配置文件的情况下&#xff0c;如果启动监听&#xff0c;则监听为动态注册。用图形化netca创建的监听&#xff0c;默认也为动态注册 1.静态注册 listener.ora文…

AKOJ-1695-找素数

题意&#xff1a; 给定区间L&#xff0c;R。 计算区间中素数个数。 2 < L,R < 2147483647, R-L < 1000000。 思路&#xff1a; 素数区间筛 先筛(2-sqrt(r))。 再用(2-sqrt(r))中的素数筛(l-r)。 代码: 1.自己写的区间筛&#xff0c;将筛2-sqrt&#xff08;r) 分开了。…

Spring 环境与profile(一)——超简用例

什么是profile,为什么需要profile? 在开发时&#xff0c;不同环境&#xff08;开发、联调、预发、正式等&#xff09;所需的配置不同导致&#xff0c;如果每改变一个环境就更改配置不但麻烦&#xff08;修改代码、重新构建&#xff09;而且容易出错。Spring提供了解决方案。 方…

Django04-1: ORM增删改查

ORM 增删改查 一、字段增加 #终端输入 1.model里添加字段&#xff0c; 2.执行迁移命令。 3.终端里输入默认值&#xff0c;继续执行迁移命令。 #允许为空 再nulltrue&#xff0c;终端不需要输入默认值 #设置默认值 defalult‘xxxx‘ 二、字段修改 1.直接修改代码&…

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…

SpringBoot详解(一)-快速入门

SpringBoot详解系列文章&#xff1a;SpringBoot详解&#xff08;一&#xff09;-快速入门SpringBoot详解&#xff08;二&#xff09;-Spring Boot的核心SpringBoot详解&#xff08;三&#xff09;-Spring Boot的web开发SpringBoot详解&#xff08;四&#xff09;-优雅地处理日志…

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

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

Class与Style绑定

对于数据绑定&#xff0c;一个常见的需求是操作元素的class列表和它的内联样式。因为它们都是attribute&#xff0c;我们可以用v-bind处理它们&#xff1a;只需要计算出表达式最终的字符串。不过&#xff0c;字符串拼接麻烦又易错。因此&#xff0c;在v-bind用于class和style时…

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…

zabbix运行脚本监控ggsci报错

/u01/app/oracle/oracle/ogg/ggsci: error while loading shared libraries: libdb-6.1.so: cannot open shared object file: No such file or directory增加脚本环境变量设置PATH$PATH:$HOME/binexport ORACLE_BASE/u01/app/oracleexport ORACLE_HOME$ORACLE_BASE/11/db_1exp…

一句话设计原则

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