Execute post-install/post-update scripts of dependencies - composer PHP

Is there a valid reason why scripts are not executed for dependencies? I'm sure this has been discussed before, but I couldn't find an issue here.

I have a use case. I have written a component that allows NPM packages to be installed/updated at the same time as Composer's dependencies by using the scripts system.

The component works great for end projects, but obviously cannot be used for dependencies currently, which is where it would actually be useful.

Even if it's not something that will be implemented, it would be nice to know why it's not possible or desirable.

Asked Nov 05 '21 20:11
avatar ezzatron
ezzatron

9 Answer:

@Seldaek

So, here is our use case. We would like to use composer to be able to install our framework, and individual packages that are plugins to the framework. As part of the installation process, we want to copy specific stub files that we just installed out of the vendor directory and into a user editable space so that the user can edit them and not worry about composer stomping on those edits on the next update. We are trying to use scripts to do the copy of those files.

With the current architecture, I need to tell these users to make certain 'scripts' entries to the composer.json file. HOWEVER, if there is already a 'scripts' entry there because of other dependencies, we need to tell them to MERGE the entries into what is already there. If they remove our framework, they will have to un-merge by hand.

Now, our users are not all experts. I would like to avoid the requirement of needing to know how to hand-edit a .json file before being able to use our framework. Explaining how to do this hand-editing, and to be careful of every little comma and bracket can lead to quite a bit of frustration that will be a barrier to entry for our beginning developers. With the current architecture, I can't tell them to just execute 'composer require'.

I guess I don't understand your point about losing user control. If I require a package in my top level composer.json file, I want that package to install. If that package fires off some scripts during installation, as a user of that package, I WANT that. I could easily inspect that package's composer.json file to see what it is trying to do if something goes wrong. The package creator can communicate in its documentation that it is firing off scripts at install and update time. Composer could notify the user during the composer execution process by outputing "Executing xyz script from package ABC" as part of the messages it sends out. Composer could have some options to not execute package scripts, or even have an interactive option to ask for confirmation on each script it finds. All of these would give the user sufficient control in the very unlikely event that the user would want that.

If you still don't agree, then perhaps at a minimum have the composer require and composer remove operations look for scripts entries in the required packages and merge and underage those entries to avoid a bunch of user error in the manipulation of the composer.json file.

You could have a custom installer allowing hooks in packages it installs, or maybe even with a plugin if we add the given hook. I feel it'd be best than to add this in composer itself.

Don't both of these options require a bunch of work by the developer, and the user has to create special entries in the top-level composer.json file? And these packages are then allowed to fire custom scripts on their own. I don't see how doing more work is better, when the end result is basically the same thing, that a package that was installed is firing a script at install time. I don't see how calling it a 'composer-plugin' means that the user has more control than the scenario that any required package could fire off scripts.

1
Answered Jul 01 '15 at 17:29
avatar  of spekary
spekary

Couldn't see any solutions on this thread. Here is a workaround I now use to invoke post install events manually on selected packages.

composer run-script post-install-cmd -d ./vendor/[name]/[package]

You could also write a simple bash loop to trigger them all with this method if needed.

1
Answered Aug 09 '16 at 17:08
avatar  of SplicePHP
SplicePHP

@hinikato I'm really against this, because it removes the control from the users and places it in the hands of package authors. It's a good thing for metadata like autoloading because that makes things easier for everyone, but in this case, executing stuff is something that is best done by the root package, where you can control what is executed and in what order.

1
Answered Feb 28 '13 at 14:51
avatar  of Seldaek
Seldaek

@spekary Thank you!

If I require a package in my top level composer.json file, I want that package to install. If that package fires off some scripts during installation, as a user of that package, I WANT that.

I totally agree. There should at least be some kind of option like --run-dep-scripts to explicitly allow a dependency to fire off some custom scripts during installation.

If at the end of the day I still need to edit some JSON files by hand to get my dependencies to work then why bother with composer in the first place?

1
Answered Jul 01 '15 at 17:57
avatar  of younishd
younishd

The intention is to have a composer package that handles compilation of CoffeeScript and JavaScript libraries into production-ready minified javascript versions. We call this package build-javascript, and it can be brought into any of our other packages as a dev dependency when that package has some javascript component to it.

In order to do this, build-javascript needs the CoffeeScript compiler and uglify.js which are available through NPM. We actually have the system working fine right now, but we have to commit the node_modules directory to the build-javascript repo, which is obviously not ideal. That is the problem I was trying to solve by creating a bridge between Composer and NPM.

In a more general sense, it's quite common for PHP devs to use some client-side scripting in their projects. Allowing Composer packages to bring in their own NPM dependencies seems like a good idea to me, whether it be baked into Composer or possible through a post-install script type arrangement.

1
Answered Oct 11 '12 at 04:47
avatar  of ezzatron
ezzatron

I need too that composer send child commands after the installation process, but after thinking about that, i demand me what script should be launch and in what order. It exists 4 phases for 3 commands :

install update uninstall
pre-install-cmd pre-update-cmd pre-package-uninstall
pre-package-install pre-package-update post-package-uninstall
post-install-cmd post-update-cmd
post-package-install post-package-update

Should the pre-install-cmd be launch before the parent pre-install-cmd or after, same question for update and unintall commands. In my mind the order could be one of theres

parent pre
child1 pre
child2 pre
parent post
child1 post
child2 post
child1 pre
child2 pre
parent pre
child1 post
child2 post
parent post
child1 pre
child2 pre
parent pre
parent post
child2 post
child1 post
parent pre
child1 pre
child2 pre
child2 post
child1 post
parent post
child1 pre
child2 pre
parent pre
parent post
child1 post
child2 post

Note: I volontary omit cases ( parentpre>parentpost>childpre>childpost and childpre>childpost>parentpre>parentpost)

Personally i prefer the third which is more semantically exact (first arrived first out, and a dependency exists before the dependents packages)

The fith is just a variation on the requires, easiest to implement mainly if the requires are accessibles and acceded as a tree and not as a flat list.

In this case, a tree access, for each event, the designer should defined if a command should be launch one or each time the require appears.

1
Answered Nov 19 '12 at 03:48
avatar  of nicodmf
nicodmf

There are moderate security concerns with doing that, but we just did not do it because we were not sure whether it was a good idea. We named the events in a way that we can add a post-install script that would be executed on the package when it is actually installed, so it should be no problem to add without breaking anything.

That said, I don't think it's a huge drawback that users of your lib must add the scripts to their own composer.json.. It is one extra step but at least it makes it very obvious what is executed, and it's easy to remain in control as a user, so I would still favor the status quo.

1
Answered Oct 09 '12 at 12:32
avatar  of Seldaek
Seldaek

@Seldaek, are you saying that supporting of running scripts in dependencies will not be supported now or in future?

We are preparing to use Composer in connection with MediaWiki/SemanticMediaWiki and while we can educate people to update the MediaWiki composer.json with something like:

php composer.phar require mediawiki/semantic-media-wiki @dev

I would not expect a user to search the Semantic MediaWiki composer.json file, look for scripts, and make him/her to copy this part into the MediaWiki related composer.json file (root composer file). If this is required from a "normal" user then it defies the idea of handling dependencies without deeper knowledge of a related package.

"scripts": {
    "post-install-cmd": "SMW\\Maintenance\\ComposerInstaller::postInstallEvent"
}

We do an effort to make the migration to use Composer in connection with MW/SMW as easy as possible but making a user understand to edit a json file by hand is certainly rather difficult.

1
Answered Dec 21 '13 at 11:50
avatar  of mwjames
mwjames

I ran into this issue as well. I'd like to see it...Its useful for github enterprise users.

A key like

"authorizevendorscripts":true

would work?

1
Answered Feb 12 '14 at 17:34
avatar  of leafpeak
leafpeak