Split require-recipe into require-recipe and update-recipe

This commit is contained in:
Damian Mooyman 2017-07-10 12:22:15 +12:00
parent fb72c0fcc4
commit c8288e2be5
No known key found for this signature in database
GPG Key ID: 78B823A10DE27D1A
4 changed files with 129 additions and 58 deletions

View File

@ -182,4 +182,75 @@ trait RecipeCommandBehaviour
// Cannot guess; Let composer choose (equivalent to `composer require vendor/library`)
return null;
}
/**
* Install or update a recipe with a given constraint and current version
*
* @param OutputInterface $output
* @param string $recipe
* @param string $constraint
* @param string $installedVersion
* @return int
*/
protected function installRecipe(OutputInterface $output, $recipe, $constraint, $installedVersion)
{
if ($installedVersion) {
if ($constraint) {
$output->writeln(
"Updating existing recipe from <info>{$installedVersion}</info> to <info>{$constraint}</info>"
);
} else {
// Show a guessed constraint
$constraint = $this->findBestConstraint($installedVersion);
if ($constraint) {
$output->writeln(
"Updating existing recipe from <info>{$installedVersion}</info> to <info>{$constraint}</info> "
. "(auto-detected constraint)"
);
} else {
$output->writeln(
"Updating existing recipe from <info>{$installedVersion}</info> to latest version"
);
}
}
}
// Ensure composer require includes this recipe
$returnCode = $this->requireRecipe($output, $recipe, $constraint);
if ($returnCode) {
return $returnCode;
}
// Begin modification of composer.json
$composerData = $this->loadComposer(getcwd() . '/composer.json');
// Get composer data for both root and newly installed recipe
$installedRecipe = $this
->getComposer()
->getRepositoryManager()
->getLocalRepository()
->findPackage($recipe, '*');
if ($installedRecipe) {
$output->writeln("Inlining all dependencies for recipe <info>{$recipe}</info>:");
foreach ($installedRecipe->getRequires() as $requireName => $require) {
$requireVersion = $require->getPrettyConstraint();
$output->writeln(
" * Inline dependency <info>{$requireName}</info> as <info>{$requireVersion}</info>"
);
$composerData['require'][$requireName] = $requireVersion;
}
}
// Move recipe from 'require' to 'provide'
$installedVersion = $this->findInstalledVersion($recipe) ?: $installedVersion;
unset($composerData['require'][$recipe]);
if (!isset($composerData['provide'])) {
$composerData['provide'] = [];
}
$composerData['provide'][$recipe] = $installedVersion;
// Update composer.json and synchronise composer.lock
$this->saveComposer(getcwd(), $composerData);
return $this->updateProject($output);
}
}

View File

@ -15,7 +15,8 @@ class RecipeCommandProvider implements CommandProvider
public function getCommands()
{
return [
new RequireRecipeCommand()
new RequireRecipeCommand(),
new UpdateRecipeCommand(),
];
}
}

View File

@ -58,63 +58,8 @@ HELP
// Check if this is already installed and notify users
$installedVersion = $this->findInstalledVersion($recipe);
if ($installedVersion) {
if ($constraint) {
$output->writeln(
"Updating existing recipe from <info>{$installedVersion}</info> to <info>{$constraint}</info>"
);
} else {
// Show a guessed constraint
$constraint = $this->findBestConstraint($installedVersion);
if ($constraint) {
$output->writeln(
"Updating existing recipe from <info>{$installedVersion}</info> to <info>{$constraint}</info> "
. "(auto-detected constraint)"
);
} else {
$output->writeln(
"Updating existing recipe from <info>{$installedVersion}</info> to latest version"
);
}
}
}
// Ensure composer require includes this recipe
$returnCode = $this->requireRecipe($output, $recipe, $constraint);
if ($returnCode) {
return $returnCode;
}
// Begin modification of composer.json
$composerData = $this->loadComposer(getcwd() .'/composer.json');
// Get composer data for both root and newly installed recipe
$installedRecipe = $this
->getComposer()
->getRepositoryManager()
->getLocalRepository()
->findPackage($recipe, '*');
if ($installedRecipe) {
$output->writeln("Inlining all dependencies for recipe <info>{$recipe}</info>:");
foreach ($installedRecipe->getRequires() as $requireName => $require) {
$requireVersion = $require->getPrettyConstraint();
$output->writeln(
" * Inline dependency <info>{$requireName}</info> as <info>{$requireVersion}</info>"
);
$composerData['require'][$requireName] = $requireVersion;
}
}
// Move recipe from 'require' to 'provide'
$installedVersion = $this->findInstalledVersion($recipe) ?: $installedVersion;
unset($composerData['require'][$recipe]);
if (!isset($composerData['provide'])) {
$composerData['provide'] = [];
}
$composerData['provide'][$recipe] = $installedVersion;
// Update composer.json and synchronise composer.lock
$this->saveComposer(getcwd(), $composerData);
return $this->updateProject($output);
// Install recipe
return $this->installRecipe($output, $recipe, $constraint, $installedVersion);
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace SilverStripe\RecipePlugin;
use BadMethodCallException;
use Composer\Command\BaseCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class UpdateRecipeCommand extends BaseCommand
{
use RecipeCommandBehaviour;
public function configure()
{
$this->setName('update-recipe');
$this->setDescription('Invoke this command to update an existing recipe');
$this->addArgument(
'recipe',
InputArgument::REQUIRED,
'Recipe name to require inline'
);
$this->addArgument(
'version',
InputArgument::OPTIONAL,
'Version or constraint to update to'
);
$this->addUsage('silverstripe/recipe-blogging');
$this->setHelp(
<<<HELP
This command will detect any recipe that is installed, whether inline or required directly, and update to
the latest version based on stability settings.
HELP
);
}
public function execute(InputInterface $input, OutputInterface $output)
{
$recipe = $input->getArgument('recipe');
$constraint = $input->getArgument('version');
// Check if this is already installed and notify users
$installedVersion = $this->findInstalledVersion($recipe);
if (!$installedVersion) {
throw new BadMethodCallException(
"Recipe {$recipe} is not installed. Please install with require or require-recipe first"
);
}
// Update recipe
return $this->installRecipe($output, $recipe, $constraint, $installedVersion);
}
}