choco icon indicating copy to clipboard operation
choco copied to clipboard

[Feature Request] Allow post/pre hooks to run on upgrade/install/uninstall

Open AdmiringWorm opened this issue 7 years ago • 11 comments

The idea for this have been taken from pacman (the main package manager for arch linux). One usage example on how it is used in pacman would be running reflector after pacman-mirrorlist package is updated: https://wiki.archlinux.org/index.php/Reflector#Pacman_Hook

What I request is similiar: have a directory (either configurable or hard coded to $env:ChocolateyInstall\hook that stores a bunch of powershell scripts that are meant to be run after/before a package update/install (or after choco have completed the full update/install of all packages).

The way I'm thinking this could work is through a naming convention. ie: (pre|post){pacakge-id}-upgrade/install/uninstall.ps1 or (pre|post)global-upgrade/install/uninstall.ps1.

The reason I would like to see something like this implemented is because quite a few times I have a need/want to automatically configure some extra configuration for the package(s) that I'm installing (usually user specific configurations) (could range from anything as easy as removing a shortcut, to full configuration of git, virtualbox, smartgit, or even choco. as well as others).

AdmiringWorm avatar Mar 05 '17 01:03 AdmiringWorm

Chocolatey does have this concept built-in to it, but it is not consumer based. I think this could be looked at being added as well. Just unsure where this could fall.

Related: https://github.com/chocolatey/chocolatey-licensed-issues/issues/11

ferventcoder avatar Mar 05 '17 20:03 ferventcoder

I know this is very "edge case" but I too would welcome this feature. It would allow some pre and post processing when installing packages.

Some examples:

  • https://chocolatey.org/packages/chocolatey-preinstaller-checks.extension
  • https://chocolatey.org/packages/chocolatey-toast-notifications.extension
  • ability to delete unwanted icons
  • ability to update package install status to some central database or send a status email

I'm sure people will come up with many creative uses for it.

bcurran3 avatar Feb 21 '19 18:02 bcurran3

I am very interested in this feature. It would be very helpful for my workflow, as I like to archive a copy of programs installers.

TheCakeIsNaOH avatar Mar 26 '19 23:03 TheCakeIsNaOH

https://github.com/Badgerati/Fudge provides the ability to have pre and post hooks , but they run before and after the set of packages, not before/after each one. I am using the post-install hook , loading the Fudgefile, and dynamically calling scriptlets called deps.<choco-package-name>-postinstall.ps1 for each package in the Fudgefile.

jayvdb avatar Jun 14 '19 14:06 jayvdb

https://github.com/Badgerati/Picassio and https://github.com/Badgerati/Picassio2 also provide a way for pre/post hooks.

jayvdb avatar Jun 14 '19 15:06 jayvdb

This feature would be very useful to me. I am trying to attach a post-update script to my choco upgrade command whenever it updates my JDK, so that I can update my vscode settings.json to always point to the correct JDK path in the settings. Background: I use chocolatey to manage my JDK as AdoptOpenJDK. I use vscode for coding in Java. vscode needs to know where my JDK lives. To achieve this, I have this in my settings.json:

[snip]
"java.home": "{$env:ProgramFiles}\\AdoptOpenJDK\\jdk-14.0.2.12-hotspot",
"java.configuration.runtimes": [
        {
            "name": "JavaSE-1.8",
            "path": "{$env:APPDATA}\\java-1.8.0-openjdk-1.8.0.252-2.b09.redhat.windows.x86_64",
            "sources": "{$env:APPDATA}\\java-1.8.0-openjdk-1.8.0.252-2.b09.redhat.windows.x86_64\\src.zip",
            "javadoc": "https://docs.oracle.com/javase/8/docs/api",
            "default": false
        },
        {
            "name": "JavaSE-14",
            "path": "{$env:ProgramFiles}\\AdoptOpenJDK\\jdk-14.0.2.12-hotspot",
            "sources": "{$env:ProgramFiles}\\AdoptOpenJDK\\jdk-14.0.2.12-hotspot\\lib\\src.zip",
            "javadoc": "https://api.adoptopenjdk.net/",
            "default": true
        }
    ],
[snip]

However, the paths can break if AdoptOpenJDK is updated. This isn't too big of a hassle, but it would be neat to automate the json update so that a script ran after each JDK update to correct the settings too.

mavaddat avatar Jul 17 '20 18:07 mavaddat

I have a couple of other examples that I have thought of where this would be useful:

  • Modifying the right-click menu so a program only shows up with a shift-click. For example, I can set the git gui open here to only show up on a shift-click, but that gets reset on each git upgrade. So a hook to reset that anytime git is installed/upgraded would be useful.
  • Deleting desktop shortcuts. I prefer to have a fairly clean desktop, and not every program has an option to not add an shortcut, so it would be useful to be able to automatically remove them. Could solve #4 and #344 for most people.
  • Deleting/Creating/Moving start menu shortcuts. Same as above, and it could help solve #2016
  • Working around bugs in install scripts where extra files are left behind, such as https://github.com/chocolatey-community/chocolatey-coreteampackages/issues/1566
  • Create a snapshot of the installed package versions with something like choco-package-list-backup. I know that the information could be dug out of the logs, if needed, but choco-package-list-backup is more flexible and easier to parse the resulting info.

TheCakeIsNaOH avatar Nov 18 '20 03:11 TheCakeIsNaOH

My thoughts on details of a possible implementation:

Create a new package type, the .hook package. Similar to .extension or .template packages. Then in $env:ChocolateyInstall\hook each package gets it's own folder, like $env:ChocolateyInstall\extension has. Then an extension can have a pre-<packageid>-install.ps1, a post-<packageid>-install.ps1, pre-global-uninstall.ps1, etc, as needed for each type of hook. This would not always be quite as flexible as having directly user-editable scripts (ie editable without a package upgrade/reinstall), but if that where an issue, you could always create a package to call a user-editable script elsewhere. Or for security, actually an Admin-editable script.

In regards to the types of hooks:

  • Pre/Post install package specific hooks. Multiple obvious uses, mainly for configuration of the software from the package. Should also run for upgrades, not only for installs.
  • Pre/Post install global hooks. Should these run before/after each package, or before/after the entire list of packages? If before/after the entire list, then a method of listing each package id and version should be made available.
  • Pre/Post uninstall package specific hooks. Cleanup after poorly written uninstallers, remove user configuration, kill process that may use a shared resource.
  • Pre/Post uninstall global hooks. Same as install
  • Pre pack hooks. Useful for validation (à la choco-nuspec-checker), or other testing (pester?). Not sure if a post pack hook would be useful?
  • Upgrade hooks? - IMO the install hooks should just run on upgrade. Maybe there is something I am missing where a upgrade specific hook would be useful, where it shouldn't run on first install.
  • Pre/Post global every command hooks? I'm also not sure about this one.

I can't really think of any other categories of hooks that would be useful.

Any commands that have hooks possible should have a CLI option to skip hooks. Depending on which categories of hooks are chosen, perhaps CLI options to skip specific types of hooks (eg skip the overall global hooks, but don't skip the install hooks).

At least for the individual scripts for install and uninstall, the environment variables should still be set. I'm not %100 what to do for a global hook in regards to the package name+title+version+folder variables, that's something to figure out.

The Chocolatey PowerShell functions, and extensions as well should be pre-imported, as in with normal package scripts. Stuff like install-binfile, install-ChocolateyFileAssociation, and install-chocolateyshortcut all seem like they would be useful, as would things like remove-process from the core extension. It would be good to write up some docs for which helpers should not be used, e.g. Install-ChocolateyPackage.


Re: which edition.

@ferventcoder

Chocolatey does have this concept built-in to it, but it is not consumer based.

I really don't understand what you mean by "comsumer based". Isn't everyone who uses Chocolatey a consumer? I'm not sure what the alternative to a consumer would be in this context. A developer or vendor maybe?

But this is comparatively much less useful to a developer of Chocolatey, as they presumably would have the knowledge and access to create their own packages. While a consumer that just uses Chocolatey would presumably find it much more useful. For example, a developer could make a PR on a package to add a package parameter to remove the desktop shortcut, while a consumer might be stuck asking nicely, in which case a hook that removes desktop icons would come in very useful to the consumer.

I think this could be looked at being added as well. Just unsure where this could fall.

Over at chocolatey/chocolatey-licensed-issues#11, you specified "custom user scripts". Does that mean that you are intending the open source edition to have hooks that run globally, while the licensed edition will have support each windows user account having their own hooks?

TheCakeIsNaOH avatar Jan 08 '21 21:01 TheCakeIsNaOH

I really don't understand what you mean by "comsumer based". Isn't everyone who uses Chocolatey a consumer? I'm not sure what the alternative to a consumer would be in this context. A developer or vendor maybe?

Consumer versus Business in this case - the alternative here being organizations using Chocolatey having different needs than individual users.

Over at chocolatey/chocolatey-licensed-issues#11, you specified "custom user scripts". Does that mean that you are intending the open source edition to have hooks that run globally, while the licensed edition will have support each windows user account having their own hooks?

@TheCakeIsNaOH note this is in "Triaging" label, which means it is not on the backlog and work has not been committed to putting it in. We have tagged the licensed item to put something very similar (if not the same exact thing) into the commercial editions, starting at Pro.

ferventcoder avatar Mar 30 '21 18:03 ferventcoder

Alright since this is undecided on if it is going into open source choco, if anyone is interested in an implementation of this available now, see my choco-hooks.extension package:

It only does scripts run pre/post the install/modify/uninstall scripts of each individual package, and not scripts that run pre/post of the entire run of choco.

For that, two options are choco-upgrade-all-at-startup and choco-upgrade-all-at, both of which have an option to run pre/post run scripts and are created by @bcurran3.

TheCakeIsNaOH avatar Mar 30 '21 19:03 TheCakeIsNaOH

After playing around with the .extension based hook implementation, not being able to run hooks on packages that do not have automation scripts makes these scripts much less useful. Therefore, I'm working on an implementation into Chocolatey CLI itself, which is able to run hooks even if the package does not have the appropriate automation script.

It does not do scripts on pack, or global scripts before/after install/uninstall/upgrade, at least not yet.

#2535

TheCakeIsNaOH avatar Jan 18 '22 00:01 TheCakeIsNaOH

There is an open documentation PR here: https://github.com/chocolatey/docs/pull/564

It's ready for review, but in draft to prevent merging until the Chocolatey CLI release goes out.

TheCakeIsNaOH avatar Oct 19 '22 13:10 TheCakeIsNaOH

:tada: This issue has been resolved in version 1.2.0 :tada:

The release is available on:

Your GitReleaseManager bot :package::rocket:

AdmiringWorm avatar Oct 20 '22 10:10 AdmiringWorm