diff --git a/src/RecipeCommandBehaviour.php b/src/RecipeCommandBehaviour.php
index e7a3202..017d28f 100644
--- a/src/RecipeCommandBehaviour.php
+++ b/src/RecipeCommandBehaviour.php
@@ -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 {$installedVersion} to {$constraint}"
+ );
+ } else {
+ // Show a guessed constraint
+ $constraint = $this->findBestConstraint($installedVersion);
+ if ($constraint) {
+ $output->writeln(
+ "Updating existing recipe from {$installedVersion} to {$constraint} "
+ . "(auto-detected constraint)"
+ );
+ } else {
+ $output->writeln(
+ "Updating existing recipe from {$installedVersion} 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 {$recipe}:");
+ foreach ($installedRecipe->getRequires() as $requireName => $require) {
+ $requireVersion = $require->getPrettyConstraint();
+ $output->writeln(
+ " * Inline dependency {$requireName} as {$requireVersion}"
+ );
+ $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);
+ }
}
diff --git a/src/RecipeCommandProvider.php b/src/RecipeCommandProvider.php
index 167c567..8e2c10e 100644
--- a/src/RecipeCommandProvider.php
+++ b/src/RecipeCommandProvider.php
@@ -15,7 +15,8 @@ class RecipeCommandProvider implements CommandProvider
public function getCommands()
{
return [
- new RequireRecipeCommand()
+ new RequireRecipeCommand(),
+ new UpdateRecipeCommand(),
];
}
}
diff --git a/src/RequireRecipeCommand.php b/src/RequireRecipeCommand.php
index f514cfd..ed4d806 100644
--- a/src/RequireRecipeCommand.php
+++ b/src/RequireRecipeCommand.php
@@ -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 {$installedVersion} to {$constraint}"
- );
- } else {
- // Show a guessed constraint
- $constraint = $this->findBestConstraint($installedVersion);
- if ($constraint) {
- $output->writeln(
- "Updating existing recipe from {$installedVersion} to {$constraint} "
- . "(auto-detected constraint)"
- );
- } else {
- $output->writeln(
- "Updating existing recipe from {$installedVersion} 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 {$recipe}:");
- foreach ($installedRecipe->getRequires() as $requireName => $require) {
- $requireVersion = $require->getPrettyConstraint();
- $output->writeln(
- " * Inline dependency {$requireName} as {$requireVersion}"
- );
- $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);
}
}
diff --git a/src/UpdateRecipeCommand.php b/src/UpdateRecipeCommand.php
new file mode 100644
index 0000000..0d5fe57
--- /dev/null
+++ b/src/UpdateRecipeCommand.php
@@ -0,0 +1,54 @@
+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(
+ <<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);
+ }
+}