winget-cli icon indicating copy to clipboard operation
winget-cli copied to clipboard

Support for package dependencies

Open denelon opened this issue 4 years ago • 50 comments

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 avatar May 15 '20 03:05 denelon

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

denelon avatar May 15 '20 03:05 denelon

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.

Conan-Kudo avatar May 19 '20 21:05 Conan-Kudo

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.

adelcast avatar May 19 '20 21:05 adelcast

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

adamroach avatar May 19 '20 22:05 adamroach

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.

dodgepong avatar May 19 '20 23:05 dodgepong

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.

denelon avatar May 23 '20 04:05 denelon

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.

dustojnikhummer avatar May 26 '20 09:05 dustojnikhummer

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

aetos382 avatar May 26 '20 16:05 aetos382

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:

  • it duplicates libraries
  • it duplicates entire applications and application ecosystems
  • there is no way to keep bundled dependencies up to date

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.

phoerious avatar May 28 '20 09:05 phoerious

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.

aetos382 avatar May 28 '20 12:05 aetos382

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.

riverar avatar May 29 '20 18:05 riverar

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.

Witchilich avatar Jun 15 '20 17:06 Witchilich

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

Kein avatar Jan 06 '21 18:01 Kein

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.

denelon avatar Feb 04 '21 00:02 denelon

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

Kein avatar Feb 04 '21 06:02 Kein

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

riverar avatar Feb 04 '21 06:02 riverar

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?

Kein avatar Feb 04 '21 07:02 Kein

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.

tomsik-radek avatar Feb 04 '21 08:02 tomsik-radek

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

chausner avatar May 04 '21 17:05 chausner

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.

derkrasseleo avatar May 23 '21 09:05 derkrasseleo

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.

lee-b avatar Jun 03 '21 11:06 lee-b

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

Kein avatar Jun 03 '21 12:06 Kein

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

KaranKad avatar Jun 03 '21 17:06 KaranKad

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.

Kein avatar Jun 03 '21 17:06 Kein

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.

amaank404 avatar Jun 27 '21 04:06 amaank404

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"

dustojnikhummer avatar Jun 30 '21 21:06 dustojnikhummer

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

amaank404 avatar Jul 01 '21 07:07 amaank404

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

lee-b avatar Jul 01 '21 08:07 lee-b

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

amaank404 avatar Jul 01 '21 10:07 amaank404

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

dustojnikhummer avatar Jul 01 '21 12:07 dustojnikhummer