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

Commit

Permalink
fixes #50 (#53)
Browse files Browse the repository at this point in the history
| Q               | A
| --------------- | ---
| Bug fix?        | no
| New feature?    | yes
| BC breaks?      | no
| Deprecations?   | no
| Related tickets | fixes #50
| License         | MIT
| Doc PR          | -
  • Loading branch information
prisis authored Aug 20, 2018
1 parent e3591dc commit bcbddab
Show file tree
Hide file tree
Showing 13 changed files with 428 additions and 133 deletions.
247 changes: 168 additions & 79 deletions src/Automatic/Automatic.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Composer\IO\IOInterface;
use Composer\IO\NullIO;
use Composer\Json\JsonFile;
use Composer\Package\BasePackage;
use Composer\Package\Locker;
use Composer\Plugin\PluginEvents;
use Composer\Plugin\PluginInterface;
Expand Down Expand Up @@ -158,93 +159,19 @@ public function activate(Composer $composer, IOInterface $io): void
$installationManager->addInstaller($this->container->get(ConfiguratorInstaller::class));
$installationManager->addInstaller($this->container->get(SkeletonInstaller::class));

$manager = RepositoryFactory::manager(
$this->container->get(IOInterface::class),
$this->container->get(Config::class),
$this->container->get(Composer::class)->getEventDispatcher(),
$this->container->get(ParallelDownloader::class)
);

if (\getenv('SYMFONY_REQUIRE') !== false) {
$symfonyRequire = \getenv('SYMFONY_REQUIRE');
} else {
$symfonyRequire = $this->container->get('composer-extra')['symfony']['require'] ?? '>=3.4';
}

$setRepositories = Closure::bind(function (RepositoryManager $manager) use ($symfonyRequire) {
$manager->repositoryClasses = $this->repositoryClasses;
$manager->setRepositoryClass('composer', TruncatedComposerRepository::class);
$manager->repositories = $this->repositories;

$i = 0;

foreach (RepositoryFactory::defaultRepos(null, $this->config, $manager) as $repo) {
$manager->repositories[$i++] = $repo;

if ($repo instanceof TruncatedComposerRepository) {
$repo->setSymfonyRequire($symfonyRequire);
}
}

$manager->setLocalRepository($this->getLocalRepository());
}, $composer->getRepositoryManager(), RepositoryManager::class);
/** @var \Narrowspark\Automatic\LegacyTagsManager $tagsManager */
$tagsManager = $this->container->get(LegacyTagsManager::class);

$setRepositories($manager);
$this->configureLegacyTagsManager($io, $tagsManager);

$composer->setRepositoryManager($manager);
$composer->setRepositoryManager($this->extendRepositoryManager($composer, $io, $tagsManager));

$this->container->get(Lock::class)->add('@readme', [
'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 !== null ? $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);
}
}
$this->extendComposer(\debug_backtrace());
}

/**
Expand Down Expand Up @@ -447,6 +374,8 @@ public function onPostUpdate(Event $event, array $operations = []): void
);
}

$io->writeError('<info>Writing automatic lock file</info>');

$lock->write();

if ($this->shouldUpdateComposerLock) {
Expand Down Expand Up @@ -594,6 +523,34 @@ public function onFileDownload(PreFileDownloadEvent $event): void
}
}

/**
* Add found legacy tags to the tags manager.
*
* @param \Composer\IO\IOInterface $io
* @param array $requires
* @param \Narrowspark\Automatic\LegacyTagsManager $tagsManager
*
* @return void
*/
private function addLegacyTags(IOInterface $io, array $requires, LegacyTagsManager $tagsManager): void
{
foreach ($requires as $name => $version) {
if (\is_int($name)) {
$io->writeError(\sprintf('Constrain [%s] skipped, because package name is a number [%s]', $version, $name));

continue;
}

if (\mb_strpos($name, '/') === false) {
$io->writeError(\sprintf('Constrain [%s] skipped, package name [%s] without a slash is not supported', $version, $name));

continue;
}

$tagsManager->addConstraint($name, $version);
}
}

/**
* Check which package should be recorded.
*
Expand Down Expand Up @@ -894,4 +851,136 @@ private static function getComposerVersion(): string

throw new RuntimeException('No composer version found.');
}

/**
* Configure the LegacyTagsManager with legacy package requires.
*
* @param \Composer\IO\IOInterface $io
* @param \Narrowspark\Automatic\LegacyTagsManager $tagsManager
*
* @return void
*/
private function configureLegacyTagsManager(IOInterface $io, LegacyTagsManager $tagsManager): void
{
$extra = $this->container->get('composer-extra');
$envRequire = \getenv('AUTOMATIC_REQUIRE');

if ($envRequire !== false) {
$requires = [];

foreach (\explode(',', $envRequire) as $packageString) {
[$packageName, $version] = \explode('=', $packageString, 2);

$requires[$packageName] = $version;
}

$this->addLegacyTags($io, $requires, $tagsManager);
} elseif (isset($extra['require'])) {
$this->addLegacyTags($io, $extra['require'], $tagsManager);
}
}

/**
* Extend the composer object with some automatic settings.
*
* @param array $backtrace
*
* @return void
*/
private function extendComposer($backtrace): void
{
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 !== null ? $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);
}

// When prefer-lowest is set and no stable version has been released,
// we consider "dev" more stable than "alpha", "beta" or "RC". This
// allows testing lowest versions with potential fixes applied.
if ($input->hasParameterOption('--prefer-lowest', true)) {
BasePackage::$stabilities['dev'] = 1 + BasePackage::STABILITY_STABLE;
}
}
}

/**
* Extend the repository manager with a truncated composer repository.
*
* @param \Composer\Composer $composer
* @param \Composer\IO\IOInterface $io
* @param \Narrowspark\Automatic\LegacyTagsManager $tagsManager
*
* @return \Composer\Repository\RepositoryManager
*/
private function extendRepositoryManager(Composer $composer, IOInterface $io, LegacyTagsManager $tagsManager): RepositoryManager
{
$manager = RepositoryFactory::manager(
$io,
$this->container->get(Config::class),
$this->container->get(Composer::class)->getEventDispatcher(),
$this->container->get(ParallelDownloader::class)
);

$setRepositories = Closure::bind(function (RepositoryManager $manager) use ($tagsManager) {
$manager->repositoryClasses = $this->repositoryClasses;
$manager->setRepositoryClass('composer', TruncatedComposerRepository::class);
$manager->repositories = $this->repositories;

$i = 0;

foreach (RepositoryFactory::defaultRepos(null, $this->config, $manager) as $repo) {
$manager->repositories[$i++] = $repo;

if ($repo instanceof TruncatedComposerRepository) {
$repo->setTagsManager($tagsManager);
}
}

$manager->setLocalRepository($this->getLocalRepository());
}, $composer->getRepositoryManager(), RepositoryManager::class);

$setRepositories($manager);

return $manager;
}
}
2 changes: 1 addition & 1 deletion src/Automatic/Configurator/GitIgnoreConfigurator.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function unconfigure(PackageContract $package): void
{
$file = $this->path->getWorkingDir() . \DIRECTORY_SEPARATOR . '.gitignore';

/** @codeCoverageIgnoreStart */
// @codeCoverageIgnoreStart
if (! \file_exists($file)) {
return;
}
Expand Down
3 changes: 3 additions & 0 deletions src/Automatic/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ public function __construct(Composer $composer, IOInterface $io)
$container->get('composer-extra')
);
},
LegacyTagsManager::class => static function (Container $container) {
return new LegacyTagsManager($container->get(IOInterface::class));
},
];
}

Expand Down
Loading

0 comments on commit bcbddab

Please sign in to comment.