chocolatey / choco

Chocolatey - the package manager for Windows
https://chocolatey.org
Other
10.24k stars 897 forks source link

Chocolatey should fail a package if its dependency packages fail to install #1521

Open ajklotz opened 6 years ago

ajklotz commented 6 years ago

Chocolatey should not attempt to install a package if a dependency package (listed in .nuspec) failed to install properly. But this should not stop progress on any other independent chocolatey packages. The scenario here would be custom chocolatey packages with embedded .msi files with dependency packages listed in the nuspec file.

For example, say I have 3 chocolatey packages to install: packageA, packageB and packageC. packageB has 2 dependency packages. choco install packageA packageB packageC (I'm assuming chocolatey will install in the order from left to right) packageA installs successfully. packageB fails to install one of its dependency packages - packageB should not attempt install packageC installs successfully.

ferventcoder commented 6 years ago

As mentioned on Gitter (I believe that was you :) ), you can set this behavior with the feature flip if that is what you desire.

If you want it to be the default, that is going to require concensus and a likely a major version (v1.0.0) because folks may depending on the current default behavior.

Then there are other questions like:

How would you handle a meta package - one like dev-tools that has a bunch of dependencies on unrelated packages?

jberezanski commented 6 years ago

This has been a thorn in my side for quite a long time now.

If packageB depends on depX and depX fails to install, there are three scenarios for packageB: 1) packageB installs successfully, but the application fails at runtime (example: when KB2533623 fails to install, dotnetcore-runtime.install gets installed but running dotnet -h fails); 2) packageB installation fails (possibly causing a cascade of failures, if other packages depend on it), presenting the user with an (usually unhelpful) error message (example: when KB2919355 fails to install on 2012 R2, dotnet4.6.1 will fail with exit code 5100 - which translates to "the system does not meet the requirements", but the user probably won't know that) 3) packageB seems to install successfully, but the application or one of its components does not actually get installed (because, for example, the native installer is implemented in such a way that it silently skips some install steps when it does not detect certain prerequisites - case in point: dotnetcore-windowshosting, whose sole reason for existence is to install the IIS ASP.NET Core module, but the native installer will silently skip installing the module if IIS is not present) and the user is misled into thinking the application was fully installed.

In each scenario the user experience would be much better if Chocolatey displayed a warning: "Aborting installation of packageB because one of its dependencies (depX) failed to install. Please retry the installation after fixing the problem."

How would you handle a meta package - one like dev-tools that has a bunch of dependencies on unrelated packages?

The same as with "normal" packages. A dependency fails -> metapackage does not get installed. Otherwise, it would give the impression that all tools are present.

jberezanski commented 6 years ago

"Aborting installation of packageB because one of its dependencies (depX) failed to install. Please retry the installation after fixing the problem."

"...or use --ignore-dependencies if you know what you are doing."

bmd0031 commented 6 years ago

+1

I'm also having a similar issue. Meta package installs successfully even if one or more, or even all, dependencies fail. I think that should be expected behavior when installing with --force but as a default it should probably roll back the meta package and any of it's successful dependencies when one or more fail.

This is for the simple reason that anyone would misinterpret a successful meta package installation as a sign that all dependencies are also installed, which is simply not always going to be the case.

bcurran3 commented 6 years ago

I'm working on a temporary kludge to this issue that package maintainers can build in using an extension. First round is just a basic check to see if the dependency folder exists in lib and returns true/false. If false, the package could intentionally abort/abend/throw/cancel/stop/exit/return/break/etc. Hopefully it's useful to those that maintain packages. It's the Test-Dependency function in: https://chocolatey.org/packages/chocolatey-misc-helpers.extension/0.0.3-pre I'll probably add dependency version checking in the future via a 2nd similar function and a complete Test-Dependencies that checks the dependency(ies) and version(s) from parsing the package .nuspec when I have time.

EDIT: in 0.0.3+ https://chocolatey.org/packages/chocolatey-misc-helpers.extension

thendarion commented 5 years ago

I just ran into this issue and it's rather unsettling to be honest.

vexx32 commented 5 years ago

A package manager should not attempt to install something where prerequisites are not met. That's kind of the point of having a package manager. If one wanted to install something in an unsupported configuration, one wouldn't be using a package manager in my opinion. 😄

Alejo99 commented 4 years ago

I agree this should be the default behaviour: if a dependency fails then the package shouldn't be installed/updated. Are there any updates regarding this open issue? It is rather annoying finding out that even when a dependency failed, the package was still "installed successfully" (although its unusable or will fail at runtime).

vexx32 commented 4 years ago

To come back to this, and noting Rob's point about meta-packages - I think we may need some kind of feature where a package can specify which dependencies are critical, and which are not. So, for example, if we have a meta-package where all of its "dependencies" actually depend on one specific package that the meta-package installs first, we can have choco determine that the critical dependency fails and stop trying to install everything.

On the other hand, if the critical dependency works fine, and the other dependencies are a bit hit-or-miss, you still get as many of the "optional" ones as it can find and install successfully.

chudkins commented 4 years ago

I've run into this issue while setting up a new system. Some VC runtime failed (because it's no longer available, which is a separate issue) yet packages that depend on it happily installed anyway.

I agree with vexx32 and others: If a run-time dependency is not met, a package that depends on it should not be installed unless the user forces it. To my knowledge, package managers on other platforms (portage, yum, apt...) default to this behavior because it is the sane way to do things.

If something else depends on the current behavior... well, I'm gonna withhold my opinion of that. 🙄

bcurran3 commented 4 years ago

... you can set this behavior with the feature flip if that is what you desire.

REF: https://chocolatey.org/docs/chocolatey-configuration#other-1

@ferventcoder - request for some clarity (specifics) here. Are you referring to?:

Exit Codes [x] usePackageExitCodes - Use Package Exit Codes - Package scripts can provide exit codes. With this on, package exit codes will be what choco uses for exit when non-zero (this value can come from a dependency package). Chocolatey defines valid exit codes as 0, 1605, 1614, 1641, 3010. With this feature off, choco will exit with 0, 1, or -1 (matching previous behavior). Available in 0.9.10+.

aaronsmith1203 commented 4 years ago

Chocolatey should not attempt to install a package if a dependency package (listed in .nuspec) failed to install properly. But this should not stop progress on any other independent chocolatey packages.

I strongly agree with this behaviour. As most posters have already commented, this makes absolute sense.

... you can set this behavior with the feature flip if that is what you desire.

@ferventcoder - as @bcurran3 has asked, can you clarify what you mean by this?

I have run tests by flipping the following features, independently:

[ ] usePackageExitCodes - Use Package Exit Codes

This didn't change the behaviour for me. I still see parent packages attempting to install even though a dependency has failed.

[ ] stopOnFirstPackageFailure - Stop On First Package Failure

This is somewhat useful, but doesn't allow for the scenario that @ajklotz describes, because package C will not be invoked.

packageA installs successfully. packageB fails to install one of its dependency packages - packageB should not attempt install packageC installs successfully.

Destroy666x commented 1 year ago

Just bumping as IMO this should be a top priority issue that causes a lot of confusion. E.g. OBS Studio package has frequent issues of not installing/upgrading because of some launched apps (https://github.com/AeliusSaionji/chocopkgs/issues/36) but the meta package always succeeds. And then, because the version is bumped, you basically have to force install anyways if you don't want to uninstall bunch of other dependencies. Potentially ignoring other more serious errors.

The default behavior should be failing the meta package and there's no doubt about it as several people have stated. --force is what's needed by the user to tell choco "yes, I know it fails and could have unpredictable consquences".