sdk icon indicating copy to clipboard operation
sdk copied to clipboard

Add `dotnet tool update --all` option

Open fredrikhr opened this issue 6 years ago • 26 comments
trafficstars

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]

fredrikhr avatar Feb 21 '19 10:02 fredrikhr

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 avatar Jun 27 '19 07:06 Themodem

@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])
}

fredrikhr avatar Jun 27 '19 08:06 fredrikhr

Love this feature. Wish to see it in dotnet in the future.

ChihweiLHBird avatar Dec 12 '19 00:12 ChihweiLHBird

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 avatar Dec 24 '19 13:12 tebeco

@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.

wli3 avatar Dec 30 '19 02:12 wli3

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

lindexi avatar Feb 18 '20 14:02 lindexi

the same as F# script: https://github.com/vilinski/fsharp-scripts/blob/master/toolupdate.fsx

dotnet fsi toolupdate.fsx

no installations needed

vilinski avatar Jun 16 '20 21:06 vilinski

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

breiter avatar Jun 17 '20 19:06 breiter

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 }

void-type avatar Jun 17 '20 19:06 void-type

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.

fredrikhr avatar Jun 17 '20 19:06 fredrikhr

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

tebeco avatar Jun 17 '20 20:06 tebeco

i would also like to see an optional parameter that, before doing the update, would close any tool that is currently running

SimonCropp avatar Sep 06 '20 22:09 SimonCropp

I'd like to just know which tools are outdated first, before deciding to take any action. Is that possible?

adamralph avatar Sep 20 '20 10:09 adamralph

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

tebeco avatar Sep 23 '20 14:09 tebeco

i use this on my linux boxes

dotnet tool list -g | awk '{ print $1 }' | tail +3 | xargs -I % sh -c 'dotnet tool update -g %;'

onesteveo avatar Nov 10 '20 23:11 onesteveo

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

tebeco avatar Nov 10 '20 23:11 tebeco

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.

alexanderkyte avatar Jan 07 '21 23:01 alexanderkyte

I am totally puzzled why this haven't been implemented yet...

petersladek avatar May 21 '21 15:05 petersladek

Great feature! Does this issue accepts PRs, or is it not approved yet?

maxkoshevoi avatar Jul 19 '21 10:07 maxkoshevoi

I’m tempted to think that it will not be implemented if it’s not submitted from the community

tebeco avatar Jul 19 '21 10:07 tebeco

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

tebeco avatar Dec 07 '21 08:12 tebeco

#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...?

fredrikhr avatar Dec 07 '21 09:12 fredrikhr

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

tebeco avatar Dec 07 '21 09:12 tebeco

Any news here?

psimsa avatar Jun 08 '22 07:06 psimsa

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.

eduarddejong avatar Jun 14 '22 09:06 eduarddejong

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.

@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!

kapsiR avatar Sep 28 '22 06:09 kapsiR

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.

silverf1re avatar Dec 13 '22 21:12 silverf1re

Any updates on this?

PhilParisot avatar Jan 09 '23 15:01 PhilParisot

@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

abelbraaksma avatar Sep 22 '23 00:09 abelbraaksma

@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.

abelbraaksma avatar Sep 22 '23 00:09 abelbraaksma