microsoft / winget-cli

WinGet is the Windows Package Manager. This project includes a CLI (Command Line Interface), PowerShell modules, and a COM (Component Object Model) API (Application Programming Interface).
https://learn.microsoft.com/windows/package-manager/
MIT License
23.13k stars 1.44k forks source link

Support for package dependencies #163

Closed denelon closed 1 year ago

denelon commented 4 years ago

Description of the new feature/enhancement

Some packages like IDEs require the language to be installed separately. Most installers take care of their own dependencies, but there should be a way to support this situation. Maybe it's just a package collection, but we would still need to figure out the right order to install packages like this

Proposed technical implementation details (optional)

https://github.com/microsoft/winget-cli/blob/master/doc/specs/%23163%20-%20Dependencies.md


Edited: Added link to specification document.

denelon commented 4 years ago

https://github.com/microsoft/winget-pkgs/pull/131 is an example of a package that has an external dependency.

Conan-Kudo commented 4 years ago

You should consider using openSUSE/libsolv for this. It's a battle-tested dependency resolver library, used by DNF, Zypper, opkg, mamba, and other package managers.

adelcast commented 4 years ago

Couldn't agree more with @Conan-Kudo. I currently maintain opkg, a tiny package manager used for embedded devices. It used to rely on its own dependency engine, which was the most complicated/buggy code in the project. We added support for libsolv, which smoothed things out a lot (speed them up too, since libsolv is a really fast SAT solver). Now dependency bugs are a tiny fraction of the overall bug backlog.

Another benefit is that by sharing the same dependency model as rpm/dpkg (Recommends, Depends, Suggest, Conflicts, etc) you get a model that has been successful for 20+ years, so there is no need to reinvent the wheel. It will also bring winget closer to other package managers that already have large tooling around them. Some of that tooling could then be leveraged by winget. Certainly an option worth giving some serious thought.

adamroach commented 4 years ago

Another example of a dependency I would expect winget to understand is: powertoys depends on .NET Core being installed, but winget will happily install powertoys in what is effectively an unusable state (since it doesn't install .NET Core automatically).

dodgepong commented 4 years ago

Another example would be any GPL application that depends on VC++ runtimes, such as OBS Studio. The GUI installer for OBS prompts the user to go download the VC++ redists if they are not detected on the machine, but when installed via winget, since the installer is run with the /S flag, that prompt is never shown to the user.

GPL applications are allowed to link against VC++ runtimes via the System Library Exception, but are forbidden from distributing those libraries, or else the exception does not apply.

denelon commented 4 years ago

What are thoughts on a short-term UI display/prompt for dependencies?

Assume package foo needs Java to be installed on the machine. Assume the key in the manifest would be "DependsOn". If the foo manifest had "DependsOn: Java", executing `winget install foo' would fail, but the output could include "Foo depends on Java".

This is far from dependency support, but it might be a helpful step in the right direction.

dustojnikhummer commented 4 years ago

What are thoughts on a short-term UI display/prompt for dependencies?

Assume package foo needs Java to be installed on the machine. Assume the key in the manifest would be "DependsOn". If the foo manifest had "DependsOn: Java", executing `winget install foo' would fail, but the output could include "Foo depends on Java".

This is far from dependency support, but it might be a helpful step in the right direction.

I would prefer what Chocolatey does (I can only speak for Choco as that is what I'm using). Chocolatey asks you if you want to install those dependencies and you can say no. Origin is a good example, It relies on a lot of KB updates so

choco install origin -y

will install Origin and its dependencies automatically.

choco install origin

would ask you for every additional package required.

aetos382 commented 4 years ago

If the dependent packages are installed automatically, they must support side-by-side installation. Manifest repositories also need to provide multiple versions.

phoerious commented 4 years ago

I think dependencies are a crucial part of a successful package manager ecosystem. Currently, most Windows applications are entirely self-contained and package managers are nothing but a more convenient interface for downloading and unpacking the installer EXE or MSI. Though that is generally fine, it is not desirable for several reasons:

The first issue may not always be solvable, but at least in some cases, standard libraries may be provided through a separate package of which multiple versions can be installed in parallel. For instance, there could be a Qt 5.12, 5.14, 5.15 package, which can reduce the size of dependent applications by a lot. Guaranteeing binary compatibility across various devices, tool chains (MSVC, GCC, Clang), and versions of Windows is not always easy, but should be doable at least in some cases.

The second issue is particularly annoying in the case of many Unix tools, where each tool ships its own entire GNU ecosystem. I wish I could install Git without yet another version of OpenSSH, GnuPG, a full host of basic /bin utilities, and yet another shitty terminal emulator.

The third issue is a consequence of the first two.

I get it that simply wrapping the standard installer is the easiest and most straight-forward way of implementing a package manager on Windows, but now that we have an official Microsoft package manager, I hope it will find some first-class adoption by application maintainers, so that we can finally start cleaning up the package dependency mess.

aetos382 commented 4 years ago

As I commented in #340, to support package dependencies, the repository needs to keep all past versions and not let them be deleted. And we also need a central repository to host the installer packages along with the manifest. I think it's difficult to support package dependencies when installer packages are spread out across several servers and not managed under a uniform policy.

riverar commented 4 years ago

EarTrumpet requires the VCLibs framework package (i.e. <PackageDependency Name="Microsoft.VCLibs.140.00" MinVersion="14.0.24123.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />).

Winget cannot install EarTrumpet on clean machines at this time. To mitigate this issue, we'd have to manually plumb in vclibs like it's 1999 and/or make serious changes to our Store/AppInstaller CI. Frankly, it's not worth the effort at this time.

Witchilich commented 4 years ago

Another example is https://github.com/microsoft/winget-pkgs/pull/1467 It requires DirectX 9.29.1974 https://github.com/microsoft/winget-pkgs/blob/master/manifests/Microsoft/DirectX/9.29.1974.yaml It should support specific version as dependencies too.

Kein commented 3 years ago

Judging by the changelogs here you are adding dependencies literally and unironically manually for each case? ???

denelon commented 3 years ago

MSIX packages can be parsed for dependencies, but many other installers can't. We will automate what we can, and otherwise, yes dependencies will need to be explicitly added to manifests.

Kein commented 3 years ago

What do you mean, I'm not sure I understand. What relevance have MSIX packages? We are talking about Windows Store items. For example, how is that AdGuard store parser can do this and you can't?

  1. https://store.rg-adguard.net
  2. Select Friendly Name
  3. Type Microsoft.WindowsCalculator_8wekyb3d8bbwe
  4. Have all dependencies for store package listed
riverar commented 3 years ago

@Kein Remember, winget supports installation of apps via this repository (loose executables, msis, etc.) and the Store (msix). Store dependencies are easy to discover, as you point out. But discovery of dependencies for the others is not always possible. Those will require dependencies to be explicitly listed in the manifest.

Kein commented 3 years ago

Store dependencies are easy to discover,

Well if it is easy why wgcli still cant do it? Why do you have too add them manually (sic) to the list. What you gonna do when they are updated and new added/removed? Update manually?

tomsik-radek commented 3 years ago

Store dependencies are easy to discover,

Well if it is easy why wgcli still cant do it? Why do you have too add them manually (sic) to the list. What you gonna do when they are updated and new added/removed? Update manually?

Other package managers (my only experience is with Choco) also have to include dependencies. Something I think Microsoft can't do due to licensing.

chausner commented 3 years ago

WiXToolset requires the .NET Framework 3.5 Windows feature to be enabled. It is yet another type of external dependency.

derkrasseleo commented 3 years ago

Netbeans also needs the JDK to install (AdoptOpenJDK for example). The problem is, I can install it locally (because I installed the JDK), but can't test it with the Sandbox script.

lee-b commented 3 years ago

Without dependency management, winget has completely missed the point (of a well established, 1995-era technology).

Tools like apt-get are not about just "installing" packages: they're about encoding the dependency and compatibility knowledge of the package maintainers, so that users can manage entire systems' packages and dependencies, upgrade packages, and install security updates to specific components without getting themselves into DDL hell or creating subtle conflicts between packages, or having to reboot your entire system three times during an OS version upgrade, when only the MOST you should ever need to reboot for is a kernel change.

Kein commented 3 years ago

@lee-b I dont believe winget will get close to functionality of apt-get in next 10 years, but I also dont think it is a big deal. Being able to use it to interact with WinStore in 100% compatible way via CLI without their default massive store integration nonsense that comes with Windows 10 (so you can uninstall it) - is a MASSIVE advantage and QoL thing already.

KaranKad commented 3 years ago

default massive store integration nonsense that comes with Windows 10 (so you can uninstall it) - is a MASSIVE advantage and QoL thing already.

If you are talking about uninstalling windows store and just using winget to get store apps, I don't think it will work as winget just gets the application from store for you, but just without actually interacting with store's gui.

Edit - I forgot about Add-AppxPackage

Kein commented 3 years ago

But It does work exactly that right now? Except paid apps and subscriptions but it is coming. Even if you remove Windows Store, the service that provides its functionality still there, winget can use it if needed for account-related functionality and access.

amaank404 commented 3 years ago

Let me give an idea. For example if a package foo depends on package bar and package bar depends on foo2 and bar2 then winget could do this behind the scenes:

command run: winget install foo

winget finds that foo requires bar to be installed first, so winget runs internally in some way winget install bar. Now in the same way as above through recursion winget installs all required packages.

Or what I would suggest is using libsolv for this but the above can be a temporary solution to that.

dustojnikhummer commented 3 years ago

Let me give an idea. For example if a package foo depends on package bar and package bar depends on foo2 and bar2 then winget could do this behind the scenes:

command run: winget install foo

winget finds that foo requires bar to be installed first, so winget runs internally in some way winget install bar. Now in the same way as above through recursion winget installs all required packages.

Or what I would suggest is using libsolv for this but the above can be a temporary solution to that.

I think it should let the owner know first

"Package foo requires package bar. Do you want to also install bar? y/n"

amaank404 commented 3 years ago

@dustojnikhummer I would also suggest adding a option a which means all. Something like this:

Package foo requires package bar. Do you want to install bar (Yes, no, all):

where first letter of the given input can be checked if no character is given then the default is used which in this case is Yes the capital letter at start suggests user what is the default option. Feel free to suggest different name for all because that look weird to me.

lee-b commented 3 years ago

That's SORT OF how it's normally done, @xcodz-dot , but not quite, because it doesn't scale when real dependency management is done involving potentially hundreds of packages and their version resolution, etc. Normally the prompt (after a command to install a given package) is more like: "The following additional packages are required: ... Continue? [y/N] ". It's really worth firing up a Debian or Ubuntu VM and exploring what apt-get does for you, or just checking out packages.debian.org

amaank404 commented 3 years ago

It's really worth firing up a Debian or Ubuntu VM and exploring what apt-get does for you, or just checking out packages.debian.org

I do not use Windows at all and I have never used winget in my life. I am a Ubuntu user. and as far as apt-get it will read the local database that it stores which is updated using apt-get update. After reading the data it shows all the additional packages that will be installed (dependencies). Then it lists how many packages will be upgraded, installed, removed. And then it tells exactly what amount of data it will have to download and then tells how much storage space will be consumed and then asks this:

After this operation, 832 MB of additional disk space will be used.
Do you want to continue? [Y/n]

To which yes and no is said. Obviously installers do not provide how much installation storage will be used. And yes and no for every dependency kind of looks not good to me but at the same time its people's opinion. here is the log for you to see all the output when running sudo apt-get install qtcreator

dustojnikhummer commented 3 years ago

It's really worth firing up a Debian or Ubuntu VM and exploring what apt-get does for you, or just checking out packages.debian.org

I do not use Windows at all and I have never used winget in my life. I am a Ubuntu user. and as far as apt-get it will read the local database that it stores which is updated using apt-get update. After reading the data it shows all the additional packages that will be installed (dependencies). Then it lists how many packages will be upgraded, installed, removed. And then it tells exactly what amount of data it will have to download and then tells how much storage space will be consumed and then asks this:

After this operation, 832 MB of additional disk space will be used.
Do you want to continue? [Y/n]

To which yes and no is said. Obviously installers do not provide how much installation storage will be used. And yes and no for every dependency kind of looks not good to me but at the same time its people's opinion. here is the log for you to see all the output when running sudo apt-get install qtcreator

The issue with Windows dependencies is licensing

amaank404 commented 3 years ago

The issue with Windows dependencies is licensing

I think that is upon the package authors or developers to decide what dependencies will they include. For example, most of the dependencies will be upon language such as Python, Ruby which have a nice license to use while most of the other dependencies such as libraries can be provided by the package installer just like traditional windows installers.

Witchilich commented 3 years ago

How does this work? I added dependencies to a local version of Tachidesk-JUI manifest https://github.com/microsoft/winget-pkgs/blob/master/manifests/s/Suwayomi/Tachidesk-JUI/1.1.2/Suwayomi.Tachidesk-JUI.installer.yaml

Dependencies:
  PackageDependencies:
  - PackageIdentifier: Oracle.JavaRuntimeEnvironment
    MinimumVersion: 8.0

And it does not install Java Runtime Environment.

amaank404 commented 3 years ago

@Witchilich Unfortunately, as of now, this has not been implemented yet and will be implemented in the future.

lee-b commented 2 years ago

@Witchilich Unfortunately, as of now, this has not been implemented yet and will be implemented in the future.

Until it properly resolves dependencies of the software that it installs, it needs a big warning that the installation may be incomplete and/or incompatible. Only a system-wide package management system, with system-wide dependency resolution, can provide correctness.

lonkelle commented 2 years ago

This would be supremely useful and necessary in certain cases.

ostrich commented 2 years ago

frankly it's insane that winget was allowed to go to production before this was implemented

Kein commented 2 years ago

I thought 1.3.x supposed to show dependencies?

C:\Programs\Winget>winget.exe show --id 9WZDNCRFHVN5
Found Windows Calculator [9WZDNCRFHVN5]
Version: Unknown
Publisher: Microsoft Corporation
Publisher Url: http://windows.microsoft.com
Publisher Support Url: http://go.microsoft.com/fwlink/p/?LinkId=282454
Description: A simple yet powerful calculator that includes standard, scientific, and programmer modes, as well as a unit converter. It's the perfect tool to add up a bill, convert measurements in a recipe or other project, or complete complex math, algebra, or geometry problems. Calculator history makes it easy to confirm if you've entered numbers correctly.
License: ms-windows-store://pdp/?ProductId=9WZDNCRFHVN5
Privacy Url: http://go.microsoft.com/fwlink/?LinkID=521839
Copyright: (c) Microsoft Corporation
Agreements:
Category: Utilities & tools
Pricing: Free
Free Trial: No
Terms of Transaction: https://aka.ms/microsoft-store-terms-of-transaction
Seizure Warning: https://aka.ms/microsoft-store-seizure-warning
Store License Terms: https://aka.ms/microsoft-store-license

Installer:
  Type: msstore
  Store Product Id: 9WZDNCRFHVN5
denelon commented 2 years ago

It's an experimental feature.

[cid:47b9c1b5-6b9a-487b-9dec-ce7941abf9ef]

Kein commented 2 years ago

Yes, I have it enabled

denelon commented 2 years ago

@Kein, I don't believe any of the Microsoft Store packages have dependencies outside of MSIX dependencies serviced by the Microsoft Store as framework packages. The experimental feature really only would have data for packages coming from either the community repository or REST sources with manifests containing dependencies.

Kein commented 2 years ago

I don't believe any of the Microsoft Store packages have dependencies

??? Wndows.Calculator depends on XAML and VClibs at bare minimum. https://store.rg-adguard.net Select PackageFamilyName, pasteMicrosoft.WindowsCalculator_8wekyb3d8bbwe, search. When you install it via MS Store it install all dependencies automatically. This is expected behavior from any package manager.

(it looks like they added net runtimes for newer versions, these did not present before ~2 years ago)

AppxManifest.xml for 10.2103.8.0/Win10version:

  <Identity Name="Microsoft.WindowsCalculator" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" Version="10.2103.8.0" ProcessorArchitecture="x64"/>
  <Dependencies>
    <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17133.0" MaxVersionTested="10.0.18362.0"/>
    <PackageDependency Name="Microsoft.UI.Xaml.2.4" MinVersion="2.42007.9001.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"/>
    <PackageDependency Name="Microsoft.VCLibs.140.00" MinVersion="14.0.29231.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"/>
  </Dependencies>

PowerShell AppXpackage output

PS C:\> Get-AppxPackage | Where-Object {$_.PackageFamilyName -eq "Microsoft.WindowsCalculator_8wekyb3d8bbwe"}

RunspaceId             : e0ca3915-97cd-45c0-9cb2-06026a8135ea
Name                   : Microsoft.WindowsCalculator
[...]
Dependencies           : {Microsoft.UI.Xaml.2.4_2.42007.9001.0_x64__8wekyb3d8bbwe,
                         Microsoft.VCLibs.140.00_14.0.30704.0_x64__8wekyb3d8bbwe,
                         Microsoft.WindowsCalculator_10.2103.8.0_neutral_split.scale-100_8wekyb3d8bbwe,
                         Microsoft.WindowsCalculator_10.2103.8.0_neutral_split.scale-125_8wekyb3d8bbwe}
denelon commented 2 years ago

Those dependencies are handled directly by the Microsoft Store and are called out in the MSIX manifest. The dependency feature in the Windows Package Manager is not looking at those types of dependencies. It's looking at dependencies declared in a Windows Package Manager Manifest.

Kein commented 2 years ago

This is the only dependencies that had any importance in my opinion and I was expecting that this issue being discussed in said context. If it is not the windows store package dependencies then I'm not sure I understand what the point. What other dependencies are there? For the record you can't install said Windows.Calculator without having dependencies installed or provided to the whatever installer you are using.

I suppose then we have to fallback to https://store.rg-adguard.net/ yet again.

Masamune3210 commented 2 years ago

If you think MSIX dependencies are the only important use for dependency tracking, you are the only one. Besides, aren't MSIX dependencies automatically delivered by the store when you go to download the app?

Edit: I see that was already brought up, other statement still stands though

Kein commented 2 years ago

If you think

I think I'm missing the point of the tool. I've checked the linked example and in its context it appears this issue essentially exist for a self-inflicted problem. I havent used winget much because it wasnt really on par with what I wanted from package manager (as per linux experience, I literally was waiting for it to "be good" and this issue is one of a few that was on my watchlist), however my understanding was it is a essentially a cli-tool for Windows Store. The manifest example provided earlier indicate that instead of being cli-fronted for MSStore backend it uses its [onw?/community?/user]-driver repository index, for whatever reason, instead of just using the store. This makes little sense to me and so is whole ordeal with winget since it ends up not just subpar but kinda useless, because chocolatey does the same but better. Unironically better in every regard if you need a package manager that is separate from MS Store and does its job.

Masamune3210 commented 2 years ago

It's not just store, it's a cli to install any program added to the database. Originally, the store wasn't even supported

ostrich commented 2 years ago

It's an experimental feature. [cid:47b9c1b5-6b9a-487b-9dec-ce7941abf9ef]

so is there a way to install an experimental version with this functionality?

denelon commented 2 years ago

All,

I started a discussion so we can talk about dependency differences between MSIX manifests and Windows Package Manager manifests. I'd like to keep the discussion out of this issue due to the number of individuals who are getting e-mail notifications because they are following this issue.

gab9281 commented 2 years ago

A little proposal here : Could dependencies be resolved inside winget itself ? A manifest could link to another manifest and may specify a version. It may be troublesome at some point due to "contracts" between apps and dependencies, but it could work if the apps mentioned with a specific version is sandboxed and could live beside an upgradable version. There would be a reason to keep manifests alive and make sure that packages are updated.

denelon commented 2 years ago

@gab9218 we are in the process of tracking dependencies in manifests currently.

They have been in the schema since 1.0.

We're building a graph so we can inform PR authors when they add a manifest with dependencies that aren't in the repository. We will also inform PR authors when they try to remove a manifest with other manifests containing dependencies to the manifest they are trying to remove.

There is already an experimental feature (in preview versions) to display dependencies from manifests via winget show <package>. Several manifests already have them.