Skip to content
This repository has been archived by the owner on Feb 19, 2019. It is now read-only.

Cache clean #253

Closed
Iristyle opened this issue Feb 26, 2013 · 12 comments
Closed

Cache clean #253

Iristyle opened this issue Feb 26, 2013 · 12 comments

Comments

@Iristyle
Copy link
Contributor

NPM (cache clean), Bower (cache-clean) and others have a facility for cleaning their local cache, either by package name, or for all packages.

I think this is an important feature to have in Chocolatey as well, because we're running into some scenarios where a package with a bunch of dependencies can fail halfway through. This usually involves me telling people to manually find their chocolately lib folder and start deleting stuff.

It would be useful to issue a simple clean command to delete the package and all it's listed dependencies, so that a reinstall can be attempted without resorting to manually sifting through the package list. In our experience, --force doesn't really address this.

@ferventcoder
Copy link
Contributor

Force doesn't address this, YET. ;)

@ferventcoder
Copy link
Contributor

Agreed though, this is a little different than clean

@rismoney
Copy link
Contributor

the uninstall should be deleting the lib... assuming there is an uninstall

@Iristyle
Copy link
Contributor Author

Not sure if your comment is directed to me @rismoney ? The thing is, this isn't for an uninstall, I want to carry on with the install that got borked.

Here's a real example of what happened this AM.. I told another dev to install EPSDevTools.Web. I wasn't there for all of this, so I'm kind of paraphrasing what happened:

  • He already has Sublime installed, and accidentally left it open. So the Sublime installer died, killing the install of the main EPSDevTools.Web package.
  • OK, so now we're in this half installed state. So try reinstalling with -force
  • NodeJS package was goofed up, so that kills us the next time.

So sometimes you get into this state of .. hmm... did all my dependencies properly install? Maybe I should just start trashing the new folders out of /lib to kick Choc to reinstall missing bits because -force, AFAIK, won't execute the installer for dependent packages.. and there can be situations where the install of a dependency started, but couldn't proceed, so now it's in lib and Choc thinks its installed.

So then you say as a package maintainer... maybe I'm just better off calling cinst a bunch of times in my chocolateyInstall.ps1 to work around this, instead of using the dependencies in the nuspec, because these unexpected things can happen. But of course that kind of defeats the purpose.

IMHO, this is one of the bigger pain points I've run into choc. And don't get me wrong, I love Chocolatey, I just think that the user experience here could use some polishing -- principal of least surprise and all that ;0

So -- maybe to improve on this situation:

  • Ensure that calling -force on a parent package, calls it down the hierarchy. (I don't think this is the current behavior, but obviously correct me if I've drawn the wrong conclusion)
  • When there are dependencies for a package, provide a summary at the end that lists success / fail status.

Just as a quick'n'dirty sample of what this could look like:

Installed
[✔] - nodejs.install
[✔] - SourceCodePro

Failed
[✖] - SublimeText2.app

The characters are taken from the Mocha reporter -- unicode 2714 for succes and 2716 for fail,. (These can have problems displaying based on the shell you're in under Windows unfortunately IIRC)

  • If a parent package has failed dependencies, maybe it's also best to do a delete of that package, so you don't need to do any sort of -force. Same for any dependent packages. If the heuristic for determining if something is installed, is the presence of the package on disk, then if something doesn't succeed, trash the folder.
  • A lot of times if there's a script attached to a package that has a bunch of dependencies, the script is dependent on those things being properly installed / available in PATH. If they aren't, abort running chocolateyInstall.ps1 for the parent package.

Thoughts?

@ferventcoder
Copy link
Contributor

+1000. Yeah, this current area is a pain point for all of us.

@rismoney
Copy link
Contributor

I guess I wasn't clear. I wasn't really directing comments 😇

I think a fail install should call cuninst, and we should stop on the last successful dependency. Don't leave the unwinding to the end user. A cuninst will actually perform a delete of chocolatey.lib. In this scenario I might silent all stdout/stderr unless debug, and report a failed install has been unwound on package foo. Further investigation may be necessary.

I am comparing it to an msi, that fails midway, and then the progress bar goes in reverse, and usually leaves 💩 in far worse places than my lib. love the emoji's btw.

@Iristyle
Copy link
Contributor Author

Yeah, the cuninst approach sounds like it could be good as long as it:

  • Handles being called on only the last failed dependency
  • Handles being called up the chain / nested dependency hierarchy

I'm thinking of situations where it's undesirable to run an uninstaller. In the most extreme, consider Visual Studio was a dependency and took an hour to install. You definitely don't want to uninstall it as part of a rollback if it was a later dependency in the list that exploded.

Also -- the docs should probably stress the scope of both chocolateyInstall.ps1 / chocolateyUninstall.ps1 and how it's important for them to be iidempotent.

@ferventcoder
Copy link
Contributor

cuninst would need an explicit item to be called on.

The failed installs will move to a directory so someone can go inspect why they failed later.

@Iristyle
Copy link
Contributor Author

Ok, so yeah.. thinking on this some more -- I don't think that cuninst is the right way to go.

I think the best approach is to delete the last failed thing from \chocolatey\lib -- do not pass go, do not collect 💰 If the package was a dependency of a parent package, also delete the parent from lib, and so on up the hierarchy.

Also, there's another contributing factor that is causing a bunch of confusion here. A co-worker got through like 18 of 20 packages in the mentioned EPSDevTools.Web. There was a temporary network hiccup grabbing Ruby, which killed the Ruby install and everything after that.

From that experience, examining his console output and the lib directory, I noticed 3 major problems.

  • Chocolatey downloads all the nested dependencies up front. This should be changed to downloading each on demand IMHO. With all the packages downloaded to disk, even with a -force, chocolatey skips the failed dependencies (in this case Ruby, Vagrant and VirtualBox), because they're on disk. So a real simple solution is not download until they're ready to be used.
  • So we deleted those 3 folders, and re-ran with a -force. I thought this was supposed to cause the chocolateyInstall.ps1 for EPSDevTools.Web to execute again. It didn't. So Ruby, Vagrant and VirtualBox installed, but the extra NPM packages and Gems from the install script did not. The only way to work around this, was to delete the EPSDevTools.Web package from lib, then re-run the install. It skipped all the dependencies as expected, but ran the script it was supposed to.
  • We're still having issues with not recapturing environment variables after cinst wraps up. So clearly my previous work here wasn't enough to fix this. So of course you end up in the shell dance... close, re-open, re-run, etc. because the current shell can't use the things that were just installed.

@ferventcoder
Copy link
Contributor

Be sure to look at #595 for perspective.

@ferventcoder
Copy link
Contributor

--force --force-dependencies (or -fx)

@ferventcoder
Copy link
Contributor

This is now linked up with chocolatey/choco#1124 so please follow from there.

@chocolatey-archive chocolatey-archive locked and limited conversation to collaborators Jan 7, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants