4

I use the command composer require otra/otra:dev-develop --no-update --no-cache && composer update --no-autoloader to install my own framework.

I have put this section in my composer.json from my framework :

"scripts": {
    "pre-install-cmd": "@composer config bin-dir bin/"
}

But Composer does not run it. Is this normal, does Composer consider this as a dependency and not the root package so it does not allow my script to run?

If this is the case, how can I have the same behaviour?

I want to :

  • have my binary in the bin folder, not vendor/bin without having to ask the user to do a symlink manually (or another solution)
  • copy a web folder from my framework to the root of the project.

Edit : with create-project command If I type composer create-project otra/otra:dev-develop crashtest --remove-vcs, I get this composer.json :

{
  "name": "otra/otra",
  "type": "library",
  "description": "The OTRA PHP framework",
  "keywords": ["framework"],
  "homepage": "https://github.com/lperamo/otra",
  "license": "X11",
  "authors": [
    {
      "name": "Lionel Péramo",
      "email": "contact@lionel-peramo.com",
      "homepage": "https://wexample.com"
    }
  ],
  "bin" : ["otra.php"],
  "config": {
    "bin-dir" : "bin/",
    "sort-packages": true
  },
  "require": {
    "ext-mbstring": "*",
    "php": ">=7.4.0",
    "symfony/yaml": "^4.0"
  },
  "require-dev": {
    "ext-pdo": "*",
    "ext-pdo_mysql": "*"
  },
  "scripts": {
    "pre-install-cmd": "@composer config bin-dir bin/"
  }
}

which is exactly the same as my framework so I cannot update it via Composer. I could with git if I do not use --remove-vcs but it is not the goal.

The output of the composer command is :

Installing otra/otra (dev-develop ab37237565155dab11812a7b2982d30ee240f051)

  • Installing otra/otra (dev-develop ab37237): Cloning ab37237565 from cache

Created project in crashtest

Loading composer repositories with package information

Installing dependencies (including require-dev) from lock file

miken32
  • 42,008
  • 16
  • 111
  • 154
lionelp
  • 443
  • 1
  • 7
  • 21
  • Does this answer your question? [Composer run-script of nested packages](https://stackoverflow.com/questions/46769237/composer-run-script-of-nested-packages) – Nico Haase Apr 26 '20 at 17:04

2 Answers2

11

Only scripts defined in the project's proper composer.json file are executed.

Scripts from required and installed packages are never executed because it would be terrible safety risk.

This is summarily explained in the docs:

Only scripts defined in the root package's composer.json are executed. If a dependency of the root package specifies its own scripts, Composer does not execute those additional scripts.

If your package users need to perform additional steps to use your package or library, explain those steps in your package documentation, and or provide scripts that they can execute manually and will perform those steps for them.


If your package is a "framework", as opposed to a library, what you could do is take advantage of composers create-project command.

That would require you to setup are repository with the default structure for a project, which would in turn depend on your package.

That's the way it's done with Symfony's Skeleton, for example.

With this kind of setup, you can create custom installation scripts and activate them with the post-create-project-cmd, and do some some extra setup steps, even interactive one, with something like this. (docs)

Be mindful that this script would only run when the package is installed using create-project, and never when using require.

yivi
  • 42,438
  • 18
  • 116
  • 138
  • 1
    Thanks for the confirmation of the root thing.The fact is ... put things in documentation with the goal that the user will do it himself is exactly what I don't want. I want to automate those steps in order to save him time and simplify his life.That is why I wanted to use Composer for that. – lionelp Jan 26 '20 at 15:29
  • You could take advantage of "create-project". It seems that's what you are actually looking for. – yivi Jan 26 '20 at 17:02
  • A project created with `create-project` is not updatable unless I am mistaken. I already thought of that option. I could only update the framework dependencies not the framework itself. – lionelp Jan 27 '20 at 09:31
  • Yes, it's perfectly updateable. Once setup the regular composer flow applies. – yivi Jan 27 '20 at 09:31
  • How since the framework is not anymore in composer.json ? – lionelp Jan 27 '20 at 09:34
  • The framework **should** be in composer.json. What `create-project` does is: first do a `git clone`, and then a `composer install`. That's all. That dependencies such as the framework are declared is vital, of course. – yivi Jan 27 '20 at 09:35
  • I finally understand a little how skeletons work. So I have now my binary at the right place and my framework in `composer.json`. You said that skeletons do not allow scripts but Symfony seems to succeed to install something when we do `composer create-project symfony/website-skeleton symfonyTest` ... Is it Flex and not Composer that installs some more things ? – lionelp Feb 03 '20 at 16:19
  • 1
    Yes, `flex` has additional powers. – yivi Feb 03 '20 at 16:24
  • 2
    @lionelp I remembered I wrote [this other answer](https://stackoverflow.com/a/58595941/1426539) which you might find useful. – yivi Feb 03 '20 at 17:00
  • Ok thanks, I will keep that in my favorites. That being said, for this project, I do not want too much dependencies and I ask myself somewhat how Flex launch scripts since other thins cannot launch scripts automatically... So I am thinking about launching a `composer run-script` afterwards even if this solution does not please me. – lionelp Feb 04 '20 at 09:42
  • "That won't allow you to execute scripts"... In fact, I just succeed to run scripts via the file `composer.json` that lies in the skeleton version :D I teste via this command `composer create-project otra/skeleton:1.0.0 --remove-vcs yourProjectFolderName --no-cache`. – lionelp Feb 11 '20 at 18:56
0

Nobody mentioned, this can be achieved by creating a composer plugin and defining event handler for event post-package-install

JohnyProkie
  • 389
  • 1
  • 6
  • 13