Explorar o código

Merge pull request #8186 from freality/script_event_originating

allow Composer\Script\Event to reference originating event
Jordi Boggiano %!s(int64=5) %!d(string=hai) anos
pai
achega
79e4ff4373

+ 3 - 1
src/Composer/EventDispatcher/EventDispatcher.php

@@ -196,7 +196,9 @@ class EventDispatcher
                     }
 
                     try {
-                        $return = $this->dispatch($scriptName, new Script\Event($scriptName, $event->getComposer(), $event->getIO(), $event->isDevMode(), $args, $flags));
+                        $scriptEvent = new Script\Event($scriptName, $event->getComposer(), $event->getIO(), $event->isDevMode(), $args, $flags);
+                        $scriptEvent->setOriginatingEvent($event);
+                        $return = $this->dispatch($scriptName, $scriptEvent);
                     } catch (ScriptExecutionException $e) {
                         $this->io->writeError(sprintf('<error>Script %s was called via %s</error>', $callable, $event->getName()), true, IOInterface::QUIET);
                         throw $e;

+ 44 - 0
src/Composer/Script/Event.php

@@ -39,6 +39,11 @@ class Event extends BaseEvent
      */
     private $devMode;
 
+    /**
+     * @var BaseEvent
+     */
+    private $originatingEvent;
+
     /**
      * Constructor.
      *
@@ -55,6 +60,7 @@ class Event extends BaseEvent
         $this->composer = $composer;
         $this->io = $io;
         $this->devMode = $devMode;
+        $this->originatingEvent = null;
     }
 
     /**
@@ -86,4 +92,42 @@ class Event extends BaseEvent
     {
         return $this->devMode;
     }
+
+    /**
+     * Set the originating event.
+     *
+     * @return \Composer\EventDispatcher\Event|null
+     */
+    public function getOriginatingEvent()
+    {
+        return $this->originatingEvent;
+    }
+
+    /**
+     * Set the originating event.
+     *
+     * @param \Composer\EventDispatcher\Event $event
+     * @return $this
+     */
+    public function setOriginatingEvent(BaseEvent $event)
+    {
+        $this->originatingEvent = $this->calculateOriginatingEvent($event);
+
+        return $this;
+    }
+
+    /**
+     * Returns the upper-most event in chain.
+     *
+     * @param \Composer\EventDispatcher\Event $event
+     * @return \Composer\EventDispatcher\Event
+     */
+    private function calculateOriginatingEvent(BaseEvent $event)
+    {
+        if ($event instanceof Event && $event->getOriginatingEvent()) {
+            return $this->calculateOriginatingEvent($event->getOriginatingEvent());
+        }
+
+        return $event;
+    }
 }

+ 80 - 0
tests/Composer/Test/Script/EventTest.php

@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Test\Script;
+
+use Composer\Composer;
+use Composer\Config;
+use Composer\Script\Event;
+use Composer\Test\TestCase;
+
+class EventTest extends TestCase
+{
+    public function testEventSetsOriginatingEvent()
+    {
+        $io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
+        $composer = $this->createComposerInstance();
+
+        $originatingEvent = new \Composer\EventDispatcher\Event('originatingEvent');
+
+        $scriptEvent = new Event('test', $composer, $io, true);
+
+        $this->assertNull(
+            $scriptEvent->getOriginatingEvent(),
+            'originatingEvent is initialized as null'
+        );
+
+        $scriptEvent->setOriginatingEvent($originatingEvent);
+
+        $this->assertSame(
+            $originatingEvent,
+            $scriptEvent->getOriginatingEvent(),
+            'getOriginatingEvent() SHOULD return test event'
+        );
+    }
+
+    public function testEventCalculatesNestedOriginatingEvent()
+    {
+        $io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
+        $composer = $this->createComposerInstance();
+
+        $originatingEvent = new \Composer\EventDispatcher\Event('upperOriginatingEvent');
+        $intermediateEvent = new Event('intermediate', $composer, $io, true);
+        $intermediateEvent->setOriginatingEvent($originatingEvent);
+
+        $scriptEvent = new Event('test', $composer, $io, true);
+        $scriptEvent->setOriginatingEvent($intermediateEvent);
+
+        $this->assertNotSame(
+            $intermediateEvent,
+            $scriptEvent->getOriginatingEvent(),
+            'getOriginatingEvent() SHOULD NOT return intermediate events'
+        );
+
+        $this->assertSame(
+            $originatingEvent,
+            $scriptEvent->getOriginatingEvent(),
+            'getOriginatingEvent() SHOULD return upper-most event'
+        );
+    }
+
+    private function createComposerInstance()
+    {
+        $composer = new Composer;
+        $config = new Config;
+        $composer->setConfig($config);
+        $package = $this->getMockBuilder('Composer\Package\RootPackageInterface')->getMock();
+        $composer->setPackage($package);
+
+        return $composer;
+    }
+}