Skip to content
This repository has been archived by the owner on Mar 1, 2023. It is now read-only.

fixed #33 #38

Merged
merged 4 commits into from
Aug 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ install:
if [[ "$SETUP" = "high" ]]; then
$COMPOSER_UP
elif [[ "$SETUP" = "lowest" ]]; then
composer self-update 1.6.5
$COMPOSER_UP --prefer-lowest --prefer-stable;
else
$COMPOSER_UP
Expand Down
118 changes: 82 additions & 36 deletions src/Automatic/Automatic.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,24 @@
use Closure;
use Composer\Composer;
use Composer\Config;
use Composer\Console\Application;
use Composer\DependencyResolver\Operation\InstallOperation;
use Composer\DependencyResolver\Operation\UninstallOperation;
use Composer\DependencyResolver\Operation\UpdateOperation;
use Composer\DependencyResolver\Pool;
use Composer\EventDispatcher\EventSubscriberInterface;
use Composer\Factory;
use Composer\Installer;
use Composer\Installer\InstallerEvent;
use Composer\Installer\InstallerEvents;
use Composer\Installer\PackageEvent;
use Composer\Installer\PackageEvents;
use Composer\Installer\SuggestedPackagesReporter;
use Composer\IO\IOInterface;
use Composer\IO\NullIO;
use Composer\Json\JsonFile;
use Composer\Package\Comparer\Comparer;
use Composer\Package\Locker;
use Composer\Plugin\CommandEvent;
use Composer\Plugin\PluginEvents;
use Composer\Plugin\PluginInterface;
use Composer\Plugin\PreFileDownloadEvent;
Expand All @@ -30,6 +34,7 @@
use Composer\Script\ScriptEvents;
use FilesystemIterator;
use Narrowspark\Automatic\Common\Contract\Exception\InvalidArgumentException;
use Narrowspark\Automatic\Common\Contract\Exception\RuntimeException;
use Narrowspark\Automatic\Common\Contract\Package as PackageContract;
use Narrowspark\Automatic\Common\Contract\ScriptExtender as ScriptExtenderContract;
use Narrowspark\Automatic\Common\Traits\ExpandTargetDirTrait;
Expand All @@ -44,6 +49,7 @@
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use ReflectionClass;
use Symfony\Component\Console\Input\ArgvInput;

class Automatic implements PluginInterface, EventSubscriberInterface
{
Expand Down Expand Up @@ -118,7 +124,6 @@ public static function getSubscribedEvents(): array
PackageEvents::POST_PACKAGE_UPDATE => 'record',
PackageEvents::POST_PACKAGE_UNINSTALL => 'record',
PluginEvents::PRE_FILE_DOWNLOAD => 'onFileDownload',
PluginEvents::COMMAND => 'onCommand',
ScriptEvents::POST_INSTALL_CMD => 'onPostInstall',
ScriptEvents::POST_UPDATE_CMD => 'onPostUpdate',
ScriptEvents::POST_CREATE_PROJECT_CMD => [['onPostCreateProject', \PHP_INT_MAX]],
Expand Down Expand Up @@ -182,6 +187,54 @@ public function activate(Composer $composer, IOInterface $io): void
'This file locks the automatic information of your project to a known state',
'This file is @generated automatically',
]);

$backtrace = \debug_backtrace();

foreach ($backtrace as $trace) {
if (isset($trace['object']) && $trace['object'] instanceof Installer) {
/** @var \Composer\Installer $installer */
$installer = $trace['object'];
$installer->setSuggestedPackagesReporter(new SuggestedPackagesReporter(new NullIO()));

break;
}
}

foreach ($backtrace as $trace) {
if (! isset($trace['object']) || ! isset($trace['args'][0])) {
continue;
}

if (! $trace['object'] instanceof Application || ! $trace['args'][0] instanceof ArgvInput) {
continue;
}

/** @var \Symfony\Component\Console\Input\InputInterface $input */
$input = $trace['args'][0];
$app = $trace['object'];

try {
/** @var null|string $command */
$command = $input->getFirstArgument();
$command = $command ? $app->find($command)->getName() : null;
} catch (\InvalidArgumentException $e) {
$command = null;
}

if ($command === 'create-project') {
if (\version_compare(self::getComposerVersion(), '1.7.0', '>=')) {
$input->setOption('remove-vcs', true);
} else {
$input->setInteractive(false);
}
} elseif ($command === 'suggests') {
$input->setOption('by-package', true);
}

if ($input->hasOption('no-suggest')) {
$input->setOption('no-suggest', true);
}
}
}

/**
Expand Down Expand Up @@ -230,24 +283,6 @@ public function record(PackageEvent $event): void
}
}

/**
* Execute on composer command event.
*
* @param \Composer\Plugin\CommandEvent $event
*
* @return void
*/
public function onCommand(CommandEvent $event): void
{
if ($event->getInput()->hasOption('no-suggest')) {
$event->getInput()->setOption('no-suggest', true);
}

if ($event->getInput()->hasOption('remove-vcs')) {
$event->getInput()->setOption('remove-vcs', true);
}
}

/**
* Execute on composer create project event.
*
Expand Down Expand Up @@ -338,7 +373,7 @@ public function onPostUpdate(Event $event, array $operations = []): void

foreach ((array) $lock->get(ConfiguratorInstaller::LOCK_KEY) as $packageName => $classList) {
foreach ($configuratorsClassmap[$packageName] as $path) {
includeFile(\str_replace('%vendor_path%', $this->container->get('vendor-dir'), $path));
include \str_replace('%vendor_path%', $this->container->get('vendor-dir'), $path);
}

/** @var \Narrowspark\Automatic\Common\Configurator\AbstractConfigurator $class */
Expand Down Expand Up @@ -393,7 +428,8 @@ public function onPostUpdate(Event $event, array $operations = []): void
'',
'<info>Some files may have been created or updated to configure your new packages.</info>',
'<comment>The automatic.lock file has all information about the installed packages.</comment>',
'Please <comment>review</comment>, <comment>edit</comment> and <comment>commit</comment> them: these files are <comment>yours</comment>.'
'Please <comment>review</comment>, <comment>edit</comment> and <comment>commit</comment> them: these files are <comment>yours</comment>.',
"\nTo show the package suggests run <comment>composer suggests</comment>."
);
}

Expand Down Expand Up @@ -804,9 +840,7 @@ private function getErrorMessage(IOInterface $io): ?string
return 'You must enable the openssl extension in your "php.ini" file.';
}

\preg_match('/\d+.\d+.\d+/m', Composer::VERSION, $matches);

if ($matches !== null && \version_compare($matches[0], '1.6.0') === -1) {
if (\version_compare(self::getComposerVersion(), '1.6.0', '<')) {
return \sprintf('Your version "%s" of Composer is too old; Please upgrade.', Composer::VERSION);
}
// @codeCoverageIgnoreEnd
Expand All @@ -818,16 +852,28 @@ private function getErrorMessage(IOInterface $io): ?string

return null;
}
}

/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param mixed $file
*/
function includeFile($file)
{
include $file;
/**
* Get the composer version.
*
* @throws \Narrowspark\Automatic\Common\Contract\Exception\RuntimeException
*
* @return string
*/
private static function getComposerVersion(): string
{
\preg_match('/\d+.\d+.\d+/m', Composer::VERSION, $matches);

if ($matches !== null) {
return $matches[0];
}

\preg_match('/\d+.\d+.\d+/m', Composer::BRANCH_ALIAS_VERSION, $matches);

if ($matches !== null) {
return $matches[0];
}

throw new RuntimeException('No composer version found.');
}
}
24 changes: 1 addition & 23 deletions tests/Automatic/AutomaticTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
use Composer\IO\IOInterface;
use Composer\IO\NullIO;
use Composer\Package\Package;
use Composer\Plugin\CommandEvent;
use Composer\Plugin\PreFileDownloadEvent;
use Composer\Repository\RepositoryManager;
use Composer\Repository\WritableRepositoryInterface;
Expand Down Expand Up @@ -80,7 +79,7 @@ protected function tearDown(): void

public function testGetSubscribedEvents(): void
{
static::assertCount(14, Automatic::getSubscribedEvents());
static::assertCount(13, Automatic::getSubscribedEvents());
}

public function testActivate(): void
Expand Down Expand Up @@ -155,27 +154,6 @@ public function testActivateWithNoInteractive(): void
$this->automatic->activate($this->composerMock, $this->ioMock);
}

public function testOnCommand(): void
{
$commandEventMock = $this->mock(CommandEvent::class);
$commandEventMock->shouldReceive('getInput->hasOption')
->once()
->with('no-suggest')
->andReturn(true);
$commandEventMock->shouldReceive('getInput->setOption')
->once()
->with('no-suggest', true);
$commandEventMock->shouldReceive('getInput->hasOption')
->once()
->with('remove-vcs')
->andReturn(true);
$commandEventMock->shouldReceive('getInput->setOption')
->once()
->with('remove-vcs', true);

$this->automatic->onCommand($commandEventMock);
}

public function testRecordWithUpdateRecord(): void
{
$packageEventMock = $this->mock(PackageEvent::class);
Expand Down