Sdk: Add `dotnet tool update --all` option

Created on 21 Feb 2019  路  16Comments  路  Source: dotnet/sdk

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]
For consideration

Most helpful comment

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 tool it 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 --all if no name provided

All 16 comments

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 ps1 to 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 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 tool it 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 --all if 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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

joffreykern picture joffreykern  路  3Comments

moozzyk picture moozzyk  路  3Comments

thomaslevesque picture thomaslevesque  路  3Comments

darrensimio picture darrensimio  路  3Comments

srayuws picture srayuws  路  3Comments