sdk
sdk copied to clipboard
Add `dotnet tool update --all` option
Request
When multiple tools are installed, either globally or locally, it becomes hard to keep track of which tools are outdated and which are not, and updating all outdated tools is time-consuming and boring copy-paste work, since the package id of each installed package needs to be provided to the dotnet tool update command.
I propose to add the --all (alias: -a) option to the dotnet tool update command. This option would simply run dotnet tool list internally and use the results obtained from that command to get the package ids that are installed. Then the dotnet tool update command could be called with each of these package ids.
Background
Updating all installed programs is very usual operation for package maintance application to do. apt upgrade on Debian/Ubuntu, npm upgrade for NPM, etc.
I have encountered the same problem in Python, however, there one can (semi-)easily write a Windows CMD FOR command that uses the pip list --outdated --format=freeze command.
Currently, the only way to update all packages installed with dotnet tool is to parse the output of dotnet tool list. That means I now have to write a PowerShell script that ignores the first two lines (the header and header-splitter) and parses the package id from the start of the line to the first whitespace. Yes, it's doable, but it would be much more convenient to have a command that just does all that for you. Also, adding an option in the actual executable means that dotnet can use it's own data representation of the information on the installed packages, and thus does not have to be subject to changes in the output format, invalid characters when printed to the console, and all that stuff.
Environment data
dotnet --info output:
.NET Core SDK (reflecting any global.json):
Version: 3.0.100-preview-009812
Commit: e3abf6e935
Runtime Environment:
OS Name: Windows
OS Version: 10.0.17763
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.0.100-preview-009812\
Host (useful for support):
Version: 3.0.0-preview-27122-01
Commit: 00c5c8bc40
.NET Core SDKs installed:
1.1.0 [C:\Program Files\dotnet\sdk]
2.0.0 [C:\Program Files\dotnet\sdk]
2.0.2 [C:\Program Files\dotnet\sdk]
2.0.3 [C:\Program Files\dotnet\sdk]
2.1.1 [C:\Program Files\dotnet\sdk]
2.1.4 [C:\Program Files\dotnet\sdk]
2.1.100 [C:\Program Files\dotnet\sdk]
2.1.101 [C:\Program Files\dotnet\sdk]
2.1.102 [C:\Program Files\dotnet\sdk]
2.1.103 [C:\Program Files\dotnet\sdk]
2.1.104 [C:\Program Files\dotnet\sdk]
2.1.200 [C:\Program Files\dotnet\sdk]
2.1.201 [C:\Program Files\dotnet\sdk]
2.1.202 [C:\Program Files\dotnet\sdk]
2.1.400 [C:\Program Files\dotnet\sdk]
2.1.401 [C:\Program Files\dotnet\sdk]
2.1.402 [C:\Program Files\dotnet\sdk]
2.1.500-preview-009335 [C:\Program Files\dotnet\sdk]
2.1.500 [C:\Program Files\dotnet\sdk]
2.1.502 [C:\Program Files\dotnet\sdk]
2.1.503 [C:\Program Files\dotnet\sdk]
2.1.504 [C:\Program Files\dotnet\sdk]
2.1.600-preview-009426 [C:\Program Files\dotnet\sdk]
2.1.600-preview-009497 [C:\Program Files\dotnet\sdk]
2.2.100-preview1-009349 [C:\Program Files\dotnet\sdk]
2.2.102 [C:\Program Files\dotnet\sdk]
3.0.100-preview-009812 [C:\Program Files\dotnet\sdk]
.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.0-preview1-35029 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.0-preview1-35029 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0-preview-18579-0056 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 1.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.3-servicing-26724-03 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.0-preview-26820-02 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0-preview-27122-01 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.0.0-alpha-27128-4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
If you want a horror show of a quick work around you can use
dotnet tool list -g | ForEach-Object {$index = 0} { $index++; if($index -gt 2) { dotnet tool update -g $_.split(" ")[0] } }
@Themodem yeah, I personally prefer the one below, but I agree that it is still horribly ugly...
foreach ($package in $(dotnet tool list --global | Select-Object -Skip 2)) {
Write-Host "dotnet tool update --global $($package.Split(" ", 2)[0])"
dotnet tool update --global $($package.Split(" ", 2)[0])
}
Love this feature. Wish to see it in dotnet in the future.
hello @wli3 and everyone else
Any idea about updating all local tools at once ?
dotnet tool update --local --all
that would be super helpful
as a pwsh alternative would be a workaround.
I just wonder if it's possible to avoid adding script to update tool to work on code ;)
I also wonder if the equivalent of nuget version range and wildcard would work ?
it would fix a part of the update :
foo : 5.* would not be breaking if semver is respected right ?
i mean as wildcard is an opt-in, no one is forced to use it ;)
that could also be [*, 9999.0) (nuget does resolves the latest stable versio with this one)
it's a bit more "dangerous" but for example on dotnet format i'm fine with possible breaking change.
having all these choice would be user driven so that's fine letting each rep owner decide over the strategy to use ;) ?
- manual update of each one by one (only current way today)
- add a
ps1to parse json + uninstall / reinstall / update tools (double source of info) - update all global tool
- update all local tool
- wildcard for patch/minor
- version range
@tebeco thank you for your comment.
Any idea about updating all local tools at once ?
@KathleenDollard and I do like this feature. It is currently in backlog.
equivalent of nuget version range and wildcard would work ?
Currently individual update supports --version with wildcard. But I don't think it can translate to --all easily.
Or are you considering put wild card in the manifest file? Currently only a "precise" number is allowed. In this case, it is under debate. An important feature for local tool is to pin a version number, having a wild card may make it more confusing.
I write a tool that can update all dotnet tool
Installation
dotnet tool install --global dotnetCampus.UpdateAllDotNetTools
Usage
dotnet updatealltools
dotnet-campus/dotnetCampus.UpdateAllDotNetTools: The dotnet tool that can update all dotnet tools
the same as F# script: https://github.com/vilinski/fsharp-scripts/blob/master/toolupdate.fsx
dotnet fsi toolupdate.fsx
no installations needed
You can also do this on linux and Mac by piping the <PACKAGE_ID> list from the output of dotnet tool list --global to dotnet tool update --global
#!/bin/sh
# list global tools installed
# select tool <PACKAGE_ID>
# execute `dotnet tool update --global <PACKAGE_ID>`
dotnet tool list --global | awk 'NR > 2 {print $1}' | xargs -L1 dotnet tool update --global
Here's a PowerShell script that I added to my app repos. It updates local tools to a specific framework version.
# upgradeTools.ps1
$json = Get-Content ../.config/dotnet-tools.json |
ConvertFrom-Json
$json.tools.psobject.Properties.Name |
ForEach-Object { dotnet tool update $_ --framework netcoreapp3.1 }
I am considering to write myself a tool that uses the techniques shown above, but also uses Nuget to determine whether a tool actually is out of date. You might have noticed that dotnet tool update always re-installs (even if the the tool in question is up-to-date)
But I still feel that this functionality should be built-in! Including a --outdated option.
well the idea of this issue i 0 custom scripts ;) it should be first built in to be useable on CI / DevBox
- It should be part of
dotnet toolit self - no third part script/tool to request a tool (dotnet) to update a tool (that should hurt people just to read this sentence ^^)
I mean i love contributions/ open source / etc .... but this is not suitable for CI / Team project to add that kind of layer complexity. I wonder what it would take to bring contribution to the CLI itself so that literally everyone benefits of it from the very moment you have
dotnet - works for global tool if
--global - works for local tool (manifest) if
--local - install should be seem less if already installed and just update
- it should support something like
--allif no name provided
i would also like to see an optional parameter that, before doing the update, would close any tool that is currently running
I'd like to just know which tools are outdated first, before deciding to take any action. Is that possible?
i would also like to see an optional parameter that, before doing the update, would close any tool that is currently running
I'd like to just know which tools are outdated first, before deciding to take any action. Is that possible?
@adamralph @simoncropp
Look like you should create another issue, these are two other features which would be unrelated to the fact that today we just can't udpate -all tool at once
i use this on my linux boxes
dotnet tool list -g | awk '{ print $1 }' | tail +3 | xargs -I % sh -c 'dotnet tool update -g %;'
It looks more and more obvious that native support is very much welcomed with all custom script over and over :D https://github.com/dotnet/sdk/issues/10130#issuecomment-645593134
Would love to see movement on this. Without it, any documentation for how to use dotnet has to include OS-specific (and even distro-specific) steps around upgrading.
I am totally puzzled why this haven't been implemented yet...
Great feature! Does this issue accepts PRs, or is it not approved yet?
I’m tempted to think that it will not be implemented if it’s not submitted from the community
hello @KathleenDollard I just happen to see that @wli3 will likely not work on this feature anymore.
#3115 clearly state DotNetCliToolReference is dead, which is fine for me.
But we'd love to have a way to get a user experience similary to that, especially when it comes to updating the tooling version.
As we can see from the thread, no one really want a manual Json Parsing + a Loop over tool to force the update.
On top of that, it would be shell specific and not XPlat, which make more sense to get that from the CLI itself
#3115 clearly state DotNetCliToolReference is dead
Hmm... thinking about that, maybe someone can ask the dependabot nuget-integration to also do automatic updates for dotnet tools listed in a Dotnet local tool manifest file...?
yes, but that's good only from github user point of view, which is not what the full dotnet echo system uses.
you probably still want dotnet tool update --all anyway to run that locally for example
Any news here?
I was just looking for this exact same thing too ...
Alright, of course the dotnetCampus.UpdateAllDotNetTools tool and those self-written scripts can do the job too indeed, but simply having it by default by a built-in way, which also gets updated when dotnet gets updated would be better.
Or maybe even an automatic update solution. Although the Windows implementation of that will be different from a Linux one and probably the user has to decide whether he wants to enable this or not. But it's just an idea.
I am considering to write myself a tool that uses the techniques shown above, but also uses Nuget to determine whether a tool actually is out of date. You might have noticed that
dotnet tool updatealways re-installs (even if the the tool in question is up-to-date)But I still feel that this functionality should be built-in! Including a
--outdatedoption.
@fredrikhr I've created a script, that checks NuGet before it tries to update anything:
foreach ($toolInfoRow in $(dotnet tool list -g | Select-Object -Skip 2))
{
$toolInfo = $toolInfoRow.Split(" ", [StringSplitOptions]::RemoveEmptyEntries)
$toolName = $toolInfo[0]
$toolVersion = $toolInfo[1].Trim()
# Fetch version from NuGet
$nugetInfo = (dotnet tool search --take 1 $toolName | Select-Object -Skip 2)
$nugetVersion = $nugetInfo.Split(" ", [StringSplitOptions]::RemoveEmptyEntries)[1].Trim()
if ($nugetVersion -ne $toolVersion)
{
Write-Host "dotnet tool update -g $toolName"
dotnet tool update -g $toolName
}
else
{
Write-Host "Skip $toolName (no updates available)"
}
}
But yes, I'd prefer a built-in solution too!
going on year 4 of this request for something pretty fundamental...PS scripts won't work for linux and Mac users, this needs a built in solution.
Any updates on this?
@vilinski your "update all tools" F# script seems to have gone, or moved. The wayback machine doesn't have a copy. Do you happen to still have the fsx script somewhere? Would be awesome to keep it around ;).
See: https://github.com/dotnet/sdk/issues/10130#issuecomment-645021700
@wli3 or @KathleenDollard what's the status? Still in the backlog? Can it be prioritized?
Re your comment: https://github.com/dotnet/sdk/issues/10130#issuecomment-569566206, quote:
@KathleenDollard and I do like this feature. It is currently in backlog.