composer / composer

Dependency Manager for PHP

Home Page:https://getcomposer.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Plugin class in the project being created with `project-create` is not discovered

AlexSkrypnyk opened this issue · comments

I have a project skeleton package called myorg/skeleton.

It has a plugin class in it that I want to run on post-root-package-install event, not from scripts (scripts is working correctly).

When I do composer create-project myorg/skeleton, the plugin is not included into discovery.

My composer.json:

{
  "name": "myorg/skeleton",
  "require": {
    "php": ">=8.2",
    "composer-plugin-api": "^2"
  },
  "minimum-stability": "dev",
  "autoload": {
    "psr-4": {
      "MyOrg\\Composer\\Plugin\\Skeleton\\": ".skeleton"
    },
    "classmap": [
      ".skeleton/InitializerPlugin.php"
    ]
  },
  "extra": {
    "class": "MyOrg\\Composer\\Plugin\\Skeleton\\InitializerPlugin",
  }
}

Plugin file in .skeleton/InitializerPlugin.php:

<?php

namespace MyOrg\Composer\Plugin\Skeleton;

use Composer\Composer;
use Composer\EventDispatcher\EventSubscriberInterface;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;

class InitializerPlugin implements PluginInterface, EventSubscriberInterface {

  /**
   * {@inheritdoc}
   */
  public function activate(Composer $composer, IOInterface $io) {
    die('HI FROM PLUGIN ACTIVATE');
  }

  public function deactivate(Composer $composer, IOInterface $io) {
  }

  public function uninstall(Composer $composer, IOInterface $io) {
  }
  
  public static function getSubscribedEvents() {
    die('HI FROM PLUGIN getSubscribedEvents');
  }

}

When I run this command:

export COMPOSER_DEBUG_EVENTS=1
composer create-project --prefer-dist myorg/skeleton="@dev" --no-install t1

I get the following output:

Dispatching init event
Dispatching pre-command-run (create-project) event
Creating a "myorg/skeleton=@dev" project at "./t1"
Dispatching init event
Installing myorg/skeleton (dev-main)
Dispatching pre-package-install (Installing myorg/skeleton (dev-main)) event
  - Installing myorg/skeleton (dev-main): Mirroring from ../scaffold
Dispatching post-package-install (Installing myorg/skeleton (dev-main)) event
Created project in /Users/o_o/www/drevops-sandbox/consumer/t1
Dispatching init event
Dispatching post-root-package-install event. <--- SHOULD FAIL AFTER THIS LINE
Dispatching post-create-project-cmd event

And I expected this to happen:
The new project files should be created, but there should be an error with text HI FROM PLUGIN getSubscribedEvents or HI FROM PLUGIN ACTIVATE.

Composer version

Composer version 2.7.999-dev+source @release_date@
PHP version 8.2.17 (/opt/homebrew/Cellar/php@8.2/8.2.17/bin/php)

Míy gut say that this could be a works as designed... ™️ ... but what happens when you move the plugin code to a new package and add that package as dependency of the project?

@mxr576
I need to use --no-install so having it in a separate package will not suit this case.

It is okay if you need to use --no-install, but would not it be enough if the plugin would do its job when the project is installed?

(We have a similar logic in our proprietary solution and the dedicated plugin approach works there --- although we have just added a workaround to our code ensuring the plugin registers its downloaders when the project is installed without composer.lock (and for that we had to use Reflections 🙈 )

@mxr576
In my case it would not be enough - I need the plugin to work without installation.
This whole issue is about feature parity between scripts and events: I want to understand if Events are first-class citizens as scripts by design.

I took a look and this would be quite messy to fix, as we never actually look at the root package as a plugin, and changing that might be possible but I'm not entirely sure what the impact would be. You should IMO use scripts here.