Skip to content

Expand --version option to allow range #800

Open

Description

@dtgm

Summary

Currently, issuing upgrades of packages restricted to a major version requires a unique id. This is typically done by appending the version to the id such as with community dotnet packages, e.g. dotnet3, dotnet4, etc.

Proposal

Use nuspec versioning (as already used in nuspec files to determine valid dependency version) to select version with choco. This could be for install/upgrade/pin etc.

Current

--version=VALUE
Version - A specific version to install.

Proposed

--version=2.0, --version=[2.0]
Version - Select exact version.

--version=[1.0,2.0)
Version - Select most recent version from a range >=1.0 && <2.0

--version=(,2.0)
Version - Select most recent version from a range >0.0 && <2.0.

For example, if you wanted to restrict install of a package to version 9.0
Just like when declaring a dependency in *.nuspec:

<dependencies>
  <dependency id="example" version="[9.0,10.0)" />
</dependencies>

one time use: choco install example --version=[9.0,10.0)
stored use (pin): choco pin add -n=example --version [9.0,10.0)

Adding #798 would be a very nice complement to this.

Related

Clickup task.

┆Issue is synchronized with this Clickup task by Unito

Activity

  1. added
    0 - BacklogIssue is accepted, but is not ready to be worked on or not in current sprint.
    0 - TriagingIssue is accepted, but a milestone has yet to be added for the issue.
    on Jun 15, 2016
  2. ferventcoder commented on Jun 15, 2016

    @ferventcoder
    Member

    I think this has already been logged. If not 👍

  3. ferventcoder commented on Jun 15, 2016

    @ferventcoder
    Member

    Similar - #688

  4. ferventcoder commented on Jun 15, 2016

    @ferventcoder
    Member

    @dtgm Summary/proposal - do you think this is something we could enhance the template with?

  5. added and removed
    0 - TriagingIssue is accepted, but a milestone has yet to be added for the issue.
    on Jun 15, 2016
  6. added this to the 1.x milestone on Jun 15, 2016
  7. ferventcoder commented on Jun 15, 2016

    @ferventcoder
    Member

    Pushing this out a bit - it's a good feature, but requires a lot of working parts to change.

  8. dtgm commented on Jun 15, 2016

    @dtgm
    ContributorAuthor

    @ferventcoder I figured it had to been logged too, but couldn't find with search. Probably still on the old chocolatey repo issue tracker.

    Adding to template? On one hand, it clarifies the situation, on the other, it may encourage people to a bunch of packages that should be deprecated when the feature gets implemented. I mean right now we have teamviewer, teamviewer7, teamviewer8, teamviewer9, teamviewer10.... I would see a lot of packages needing to the same. Also, it can be hard to declare a dependency sometimes as sometimes packages get created with also minor versions, dotnet4.6 and dotnet4.6.1. So a package declaring dotnet4.6 as a dependency will not get upgraded since 4.6.1 is a different package (saw that when I was looking at paint.net). But I can easily see this affecting businesses just as well that want a easily maintainable upgrade channel for supporting different versions among their different environments.

    How does nuget handle interpreting the dependency xml element? Can we leverage what they are doing there? We would probably want to separate out interpreting the version and call on that as required to retrieve the latest version within the provided parameters(?)

  9. ferventcoder commented on Jun 15, 2016

    @ferventcoder
    Member

    Bigger discussion - .NET 4.6 and 4.6.1 may be side by side installs.

  10. dtgm commented on Jun 15, 2016

    @dtgm
    ContributorAuthor

    ^^^ Widens scope for sure if needing to handle multiple versions of same id, which dotnet would. That should probably get logged as a new feature enhancement that would build upon this one.

    • Requiring upgrade to specific major version is relatively easy
    • Requiring upgrade to specific versions AND allowing multiple versions may be more difficult depending on how -m is implemented
    -m, --sxs, --sidebyside, --side-by-side, --allowmultiple, --allow-multiple, --allowmultipleversions, --allow-multiple-v
    rsions
        AllowMultipleVersions - Should multiple versions of a package be
          installed? Defaults to false.
    

    -m doesn't work for dependency packages, right?

    For example,
    a dependent on c version ==1.0
    b dependent on c version ==2.0

    I think the behavior is if b is installed, a will still install, but c will remain as 2.0

    There would have to be a way to follow the dependencies strict with -m recursive option, which would work for dotnet which installs the versions to different registry keys. But would be bad if not used correctly by packages as allowing side-by-side packages to install is meaningless if the package just reinstalls to the same registry key.

  11. ferventcoder commented on Jun 16, 2016

    @ferventcoder
    Member

    Our recommendation is that for when the natively installed app can have two versions of it installed, that is two different packages. So .NET Framework 3.5 versus .NET Framework 4.5. Those are different installs, thus different packages.

  12. dtgm commented on Jun 17, 2016

    @dtgm
    ContributorAuthor

    I agree and it should continue like that for now, but also ... stop and dream a little, man!

    Imagine a world where all the dotnetX maintainers worked together....
    Imagine a world where packages depended on dotnet and specified version required....

    Most programs just need at least a certain version of installed, say dotnet >=4.0
    So if dotnet4.6 is installed, well, gonna need to install dotnet 4.0 too because it is a separate package, and that builds a needlessly bloated system.

    But many programs also do require a specific version so it's not a solution to merge them all until there is some mechanism to say, "Hey, dependency X, I know we already have a version of you installed, but we need you too, bruh."

    Requiring side-by-side install of latest release in 4.5.x.x

    <dependencies>
      <dependency id="dotnet" version="[4.5,4.6)" force="yes" />
    </dependencies>

    So by adding an attribute force (or whatever) to dependency element, that dependent package would be forced to be installed side-by-side (-m), rather than prompting an upgrade per usual....BUT that would still introduce bloat, only more slowly, if even one package misused this property since it would be way more difficult to determine no longer relevant dependent packages. But that is a job for a dependency cleaner that I am just going to very conveniently assume that is already well developed and will magically handle all of that.

  13. jberezanski commented on Jun 17, 2016

    @jberezanski

    I've been thinking about converging the .NET packages for quite a while now (as hinted here). There are exactly two packages needed, one for each .NET "family": 2.x/3.x (2.0, 3.0, 3.5, 3.5.1) and 4.x (4.0, 4.0.1, 4.0.2, 4.0.3, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2). Both families are independent of each other and install side-by-side. Within each family, each new release completely overwrites/supersedes the older ones, while remaining backward-compatible.

    Back on topic: I fully support this feature suggestion. It would help greatly in cases where subsequent versions of a commercial package have different licensing, for example a license is valid only for a specific major version (e.g. Resharper - there is currently no way to tell choco "I have a license for 9.x, so please install the latest release before 10.0").

  14. 22 remaining items

  15. aaronsteers commented on Jan 4, 2021

    @aaronsteers

    I was directed here to this feature request by some comments regarding python version freezing - and I see that many of the comments here are actually related to python as well. I've logged a new ticket in chocolatey-community/chocolatey-packages#1602 to discuss a reevaluation of granularity for publishing python packages.

    This new ticket proposes that we think of "minor" Python version releases as if they were each major releases - adopting a strategy of publishing a new public meta-package for each in the chocolatey package directory starting with python38. This wouldn't cancel out any capabilities of the existing python and python3 packages, but it would simplify version pinning within new major (read: "non-backwards compatible") python release.

    Would greatly appreciate this group's ideas and combined brain power there in that thread:

    RE: chocolatey-community/chocolatey-packages#1602

  16. removed this from the 1.x milestone on Apr 19, 2023
  17. joel-schaal commented on Sep 6, 2023

    @joel-schaal

    Is there any news around that issue?
    I tried it on my side and it still does not work indeed:

    $ choco upgrade -y notepadplusplus --version="(,8.2)"
    Chocolatey v2.1.0
    Upgrading the following packages:
    notepadplusplus
    By upgrading, you accept licenses for the packages.
    
    Chocolatey upgraded 0/0 packages.
     See the log for details (C:\ProgramData\chocolatey\logs\chocolatey.log).
    '(,8.2)' is not a valid version string.
    Parameter name: value
    

    In the log file, I was presented with that stack trace:

    2023-09-06 13:52:36,350 20748 [ERROR] - More Details: System.ArgumentException: '(,8.2)' is not a valid version string.
    Parameter name: value
       at NuGet.Versioning.NuGetVersion.Parse(String value)
       at chocolatey.infrastructure.app.services.NugetService.Upgrade(ChocolateyConfiguration config, Action`2 continueAction, Boolean performAction, Action`2 beforeUpgradeAction)
       at chocolatey.infrastructure.app.services.NugetService.Upgrade(ChocolateyConfiguration config, Action`2 continueAction, Action`2 beforeUpgradeAction)
       at chocolatey.infrastructure.app.services.ChocolateyPackageService.Upgrade(ChocolateyConfiguration config)
       at chocolatey.infrastructure.app.runners.GenericRunner.Run(ChocolateyConfiguration config, Container container, Boolean isConsole, Action`1 parseArgs)
       at chocolatey.infrastructure.app.runners.ConsoleApplication.Run(String[] args, ChocolateyConfiguration config, Container container)
       at chocolatey.console.Program.Main(String[] args)
    

    I looked a bit in NugetService.Upgrade and I believe NuGetVersion version should either be converted to a VersionRange, or the appropriate NuGetVersion should be looked up (through a find with the appropriate call to the nuget backend), to minimize code change.

    I just scratched the surface (I'm quite new to the codebase, and not that familiar with C#).
    Can someone more versed investigate more thoroughly?

  18. pauby commented on Sep 6, 2023

    @pauby
    Member

    This hasn't been assigned to a milestone and isn't something we're working on.

    Nuspec versioning doesn't work with the --version option (as you discovered).

  19. mvorisek commented on Nov 22, 2024

    @mvorisek

    Dear developers, this feature request have 40 upvotes, please share the hapiness with us all! 🙏

  20. vbjay commented on Mar 15, 2025

    @vbjay

    Problem

    I don't want dotnet-windowshosting >8 since 8 is current LTS. If I just choco upgrade dotnet-windowshosting -y, I would get latest of 9.*

    Workaround

    function Get-LatestChocoPackageVersion {
      param (
        [string]$PackageName,
        [int]$MajorVersion
      )
    
      $versions = choco find -e -r -a $PackageName | Select-String -Pattern "$PackageName"
      $latestVersion = $null
    
      foreach ($version in $versions) {
        $versionNumber = [version]($version -split '\|' | Select-Object -Last 1)
        if ($versionNumber.Major -eq $MajorVersion) {
          if ($null -eq $latestVersion -or $versionNumber -gt $latestVersion) {
            $latestVersion = $versionNumber
          }
        }
      }
    
      return $latestVersion
    }
    
    

    Can be expanded on to support minor, and build version numbers. Then in your scripting to upgrade do something like below since we can't do range versions like choco upgrade dotnet-windowshosting --version 8.* -y

    $hostingVer = Get-LatestChocoPackageVersion "dotnet-windowshosting" 8
    $hostingChocoVersion = "$($hostingVer.Major).$($hostingVer.Minor).$($hostingVer.Build)"
    choco upgrade dotnet-windowshosting --version $hostingChocoVersion -y

    OR

    function Upgrade-ChocoPackage {
        param (
          [string]$PackageName,
          [int]$MajorVersion
        )
      
        $latestVersion = Get-LatestChocoPackageVersion -PackageName $PackageName -MajorVersion $MajorVersion
        $chocoVersion = "$($latestVersion.Major).$($latestVersion.Minor).$($latestVersion.Build)"
        choco upgrade $PackageName --version $chocoVersion -y
      }
    Upgrade-ChocoPackage -PackageName "dotnet-windowshosting" -MajorVersion 8

    The problem with this workaround is it makes it harder for us to pass in other arguments to choco. I really want something like choco upgrade/install --version and version accepting

    • .* to mean other values to accept whatever
      • 8.* Major must be 8 and minor/build accept latest
      • 8.0.* Major must be 8 and minor must be 0 but build can be whatever
    • [ ... ] syntax per version segment with .* support. Since chocolatey is based on nuget supporting one to one nuget range spec would help a lot.
      • 8.[0,1].* must be 8 major and minor can be 0 or 1 but not >=2. Technically the 0 could be omitted in this example.
  21. GuillaumeHullin commented on Jul 12, 2025

    @GuillaumeHullin

    Inspired by @vbjay but slightly different approach in case that help someone.

    # Finds the latest Chocolatey package version starting with a specific version prefix.
    # Useful to restrict updates or installs to a specific major/minor version branch.
    function Find-ChocoPackageLatestVersionPrefix {
        param (
            [Parameter(Mandatory)]
            [string]$PackageName,
    
            [Parameter(Mandatory)]
            [string]$VersionPrefix  # Example: '6.0.' to match all 6.0.x versions
        )
    
        $allVersions = choco search $PackageName --exact --all-versions --limit-output | ForEach-Object {
            ($_ -split '\|')[1]
        }
    
        $filtered = $allVersions | Where-Object { $_.StartsWith($VersionPrefix) }
    
        if ($filtered) {
            $latest = $filtered | Select-Object -First 1
            Write-Host "Latest version of '$PackageName' matching prefix '$VersionPrefix': $latest" -ForegroundColor DarkCyan
            return $latest
        } else {
            Write-Host "Package '$PackageName' not found with version starting with '$VersionPrefix'." -ForegroundColor DarkRed
            return $null
        }
    }

    Also I agree it would be awesome to have some kind of function to "pin" to major version.

  22. added this to the Future milestone on Aug 17, 2025
  23. aproposts commented on Oct 20, 2025

    @aproposts

    I'm in a similar spot to @GuillaumeHullin and @vbjay. But I'm not sure if the problem would be solved by the proposed solutions, either at the package level as described in the OP for this issue, or the 'pin' level--though they'd both be welcome additions.

    What I actually want:

    choco upgrade all # with perhaps an option like, --version-safe or --check-dependencies ?

    ...to upgrade packages as per the dependencies of the installed packages (namely metapackages) on the system.

    For instance, faced with the same problem as @vbjay, I've uninstalled the dotnet-windowshosting package, instead riding on dotnet-8.0-windowshosting, which solves the top-level 8 vs. 9 problem. Still, the 8.0 metapackage would appear to want to use the previous major version of dotnet-aspnetcoremodule-v2, and choco update all would push it to the next major version.

    As it is, I'll probably write a wrapper which builds the dependency graph by scraping .nuspec files as demonstrated in #1276 to appropriately decide which packages should actually be updated.

    Short of having an automagic command switch which 'does the thing', a canonical way to get package dependency metadata would probably be better than reading from disk myself. If I've missed something in the docs, I'm happy to be corrected.

  24. added
    EnhancementIssues that introduce new functionality to the project, or enhances/updates existing functionality.
    and removed on Nov 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    0 - BacklogIssue is accepted, but is not ready to be worked on or not in current sprint.ClickUp - BacklogUsed when syncing issues between GitHub and Clickup.CustomerBug reported or feature requested by a licensed customer of Chocolatey.EnhancementIssues that introduce new functionality to the project, or enhances/updates existing functionality.

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions