mirror of
https://github.com/silverstripe/recipe-plugin.git
synced 2024-10-22 14:05:55 +02:00
Implement require-recipe
This commit is contained in:
parent
8c0c7cfdbf
commit
54310af6aa
@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\RecipePlugin;
|
||||
|
||||
use Composer\Command\BaseCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class InlineRecipeCommand extends BaseCommand
|
||||
{
|
||||
public function configure()
|
||||
{
|
||||
$this->setName('inline');
|
||||
$this->setDescription('Invoke this command to inline a recipe into your root composer.json');
|
||||
$this->addArgument(
|
||||
'recipe',
|
||||
InputArgument::REQUIRED,
|
||||
'Recipe name to inline. Must be of type '
|
||||
. RecipePlugin::RECIPE
|
||||
. ' and be included in the root as a direct dependency'
|
||||
);
|
||||
$this->addUsage('composer inline silverstripe/recipe-blogging');
|
||||
}
|
||||
|
||||
public function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
parent::execute($input, $output); // TODO: Change the autogenerated stub
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ class RecipeCommandProvider implements CommandProvider
|
||||
public function getCommands()
|
||||
{
|
||||
return [
|
||||
new InlineRecipeCommand()
|
||||
new RequireRecipeCommand()
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ class RecipeInstaller extends LibraryInstaller {
|
||||
public function installLibrary(PackageInterface $package)
|
||||
{
|
||||
// Check if silverstripe-recipe type
|
||||
if ($package->getType() !== RecipePlugin::RECIPE) {
|
||||
if ($package->getType() !== 'silverstripe-recipe') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -21,12 +21,6 @@ use Composer\Plugin\Capability\CommandProvider;
|
||||
*/
|
||||
class RecipePlugin implements PluginInterface, EventSubscriberInterface, Capable
|
||||
{
|
||||
|
||||
/**
|
||||
* Recipe type
|
||||
*/
|
||||
const RECIPE = 'silverstripe-recipe';
|
||||
|
||||
public function activate(Composer $composer, IOInterface $io)
|
||||
{
|
||||
}
|
||||
|
173
src/RequireRecipeCommand.php
Normal file
173
src/RequireRecipeCommand.php
Normal file
@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\RecipePlugin;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Composer\Command\BaseCommand;
|
||||
use Composer\Command\RequireCommand;
|
||||
use Composer\Command\UpdateCommand;
|
||||
use MongoDB\Driver\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\Output;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class RequireRecipeCommand extends BaseCommand
|
||||
{
|
||||
public function configure()
|
||||
{
|
||||
$this->setName('require-recipe');
|
||||
$this->setDescription('Invoke this command to inline a recipe into your root composer.json');
|
||||
$this->addArgument(
|
||||
'recipe',
|
||||
InputArgument::REQUIRED,
|
||||
'Recipe name to require inline'
|
||||
);
|
||||
$this->addArgument(
|
||||
'version',
|
||||
InputArgument::REQUIRED,
|
||||
'Version to require'
|
||||
);
|
||||
$this->addUsage('silverstripe/recipe-blogging 1.0.0');
|
||||
$this->setHelp(
|
||||
<<<HELP
|
||||
Running this command will inline any given recipe into your composer.json, allowing you to
|
||||
modify it as though these dependencies were natively part of your own.
|
||||
|
||||
Running command <info>composer require-recipe silverstripe/recipe-blogging 1.0.0</info> adds the following:
|
||||
|
||||
<comment>
|
||||
"require": {
|
||||
"silverstripe/blog": "3.0.0",
|
||||
"silverstripe/lumberjack": "3.0.1",
|
||||
"silverstripe/comments": "2.1.0"
|
||||
},
|
||||
"provide": {
|
||||
"silverstripe/recipe-blogging": "1.0.0"
|
||||
}
|
||||
</comment>
|
||||
HELP
|
||||
);
|
||||
}
|
||||
|
||||
public function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$recipe = $input->getArgument('recipe');
|
||||
$version = $input->getArgument('version');
|
||||
|
||||
// Get existing composer data
|
||||
$composerData = $this->loadComposer(getcwd());
|
||||
if (isset($composerData['provide'][$recipe])) {
|
||||
$output->writeln("<error>This recipe is already added to provide</error>");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Ensure composer require includes this recipe
|
||||
$returnCode = $this->requireRecipe($output, $recipe, $version);
|
||||
if ($returnCode) {
|
||||
return $returnCode;
|
||||
}
|
||||
|
||||
// Get composer data for both root and newly installed recipe
|
||||
$composerData = $this->loadComposer(getcwd());
|
||||
$recipeData = $this->loadComposer(getcwd().'/vendor/'.$recipe);
|
||||
|
||||
// Promote all dependencies
|
||||
if (!empty($recipeData['require'])) {
|
||||
$output->writeln("Inlining all dependencies for recipe <info>$recipe</info>:");
|
||||
foreach ($recipeData['require'] as $dependencyName => $dependencyVersion) {
|
||||
$output->writeln(" * Inline dependency <info>$dependencyName</info> as <info>$dependencyVersion</info>");
|
||||
$composerData['require'][$dependencyName] = $dependencyVersion;
|
||||
}
|
||||
}
|
||||
|
||||
// Move recipe from 'require' to 'provide'
|
||||
unset($composerData['require'][$recipe]);
|
||||
if (!isset($composerData['provide'])) {
|
||||
$composerData['provide'] = [];
|
||||
}
|
||||
$composerData['provide'][$recipe] = $version;
|
||||
|
||||
// Update composer.json and synchronise composer.lock
|
||||
$this->saveComposer(getcwd(), $composerData);
|
||||
$this->updateProject($output);
|
||||
|
||||
return $returnCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load composer data from the given directory
|
||||
*
|
||||
* @param string $directory
|
||||
* @return array
|
||||
*/
|
||||
protected function loadComposer($directory)
|
||||
{
|
||||
$path = $directory.'/composer.json';
|
||||
if (!file_exists($path)) {
|
||||
throw new BadMethodCallException("Could not find composer.json");
|
||||
}
|
||||
$data = json_decode(file_get_contents($path), true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
throw new \LogicException("Invalid composer.json with error: " . json_last_error_msg());
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the given data to the composer file in the given directory
|
||||
*
|
||||
* @param string $directory
|
||||
* @param array $data
|
||||
*/
|
||||
protected function saveComposer($directory, $data)
|
||||
{
|
||||
$path = $directory.'/composer.json';
|
||||
if (!file_exists($path)) {
|
||||
throw new BadMethodCallException("Could not find composer.json");
|
||||
}
|
||||
$content = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||
// Make sure errors are reported
|
||||
if (json_last_error()) {
|
||||
throw new InvalidArgumentException("Invalid composer.json data with error: " . json_last_error_msg());
|
||||
}
|
||||
file_put_contents($path, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OutputInterface $output
|
||||
* @param $recipe
|
||||
* @param $version
|
||||
* @return int
|
||||
*/
|
||||
protected function requireRecipe(OutputInterface $output, $recipe, $version)
|
||||
{
|
||||
/** @var RequireCommand $command */
|
||||
$command = $this->getApplication()->find('require');
|
||||
$package = $recipe . ':' . $version;
|
||||
$arguments = [
|
||||
'command' => 'require',
|
||||
'packages' => [$package],
|
||||
];
|
||||
$requireInput = new ArrayInput($arguments);
|
||||
$returnCode = $command->run($requireInput, $output);
|
||||
return $returnCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the project
|
||||
*
|
||||
* @param OutputInterface $output
|
||||
* @return int
|
||||
*/
|
||||
protected function updateProject(OutputInterface $output)
|
||||
{
|
||||
/** @var UpdateCommand $command */
|
||||
$command = $this->getApplication()->find('update');
|
||||
$arguments = [ 'command' => 'update' ];
|
||||
$requireInput = new ArrayInput($arguments);
|
||||
$returnCode = $command->run($requireInput, $output);
|
||||
return $returnCode;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user