Skip to content

Commit

Permalink
Merge pull request #19 from grasmash/support-patches
Browse files Browse the repository at this point in the history
 Fixes #2: Support patches.
  • Loading branch information
grasmash authored Mar 8, 2019
2 parents f08dc94 + 4c2747e commit 66245c8
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 21 deletions.
85 changes: 68 additions & 17 deletions src/Composer/ComposerizeDrupalCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ public function configure()
$this->addOption('no-update', null, InputOption::VALUE_NONE, 'Prevent "composer update" being run after file generation.');
}

/**
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
*/
/**
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
*
* @return int
*/
public function execute(InputInterface $input, OutputInterface $output)
{
$this->input = $input;
Expand Down Expand Up @@ -125,17 +127,19 @@ protected function createNewComposerJson()
protected function addRequirementsToComposerJson()
{
$root_composer_json = $this->loadRootComposerJson();
$this->requireContribProjects($root_composer_json);
$projects = $this->findContribProjects($root_composer_json);
$this->requireContribProjects($root_composer_json, $projects);
$this->requireDrupalCore($root_composer_json);
$this->addPatches($projects, $root_composer_json);

ComposerJsonManipulator::writeObjectToJsonFile(
$root_composer_json,
$this->rootComposerJsonPath
);
}

/**
* @param $matches
*
* @return mixed|string
* @throws \Exception
*/
protected function determineDrupalCoreVersion()
Expand All @@ -157,23 +161,19 @@ protected function determineDrupalCoreVersion()

/**
* @param $root_composer_json
* @param $projects
*/
protected function requireContribProjects($root_composer_json)
protected function requireContribProjects($root_composer_json, $projects)
{
$modules = DrupalInspector::findContribProjects($this->drupalRoot, "modules/contrib", $root_composer_json);
$themes = DrupalInspector::findContribProjects($this->drupalRoot, "themes/contrib", $root_composer_json);
$profiles = DrupalInspector::findContribProjects($this->drupalRoot, "profiles/contrib", $root_composer_json);

$projects = array_merge($modules, $themes, $profiles);
foreach ($projects as $project => $version) {
$package_name = "drupal/$project";
$version_constraint = DrupalInspector::getVersionConstraint($version, $this->input->getOption('exact-versions'));
foreach ($projects as $project_name => $project) {
$package_name = "drupal/$project_name";
$version_constraint = DrupalInspector::getVersionConstraint($project['version'], $this->input->getOption('exact-versions'));
$root_composer_json->require->{$package_name} = $version_constraint;

if ($version_constraint == "*") {
$this->getIO()->write("<comment>Could not determine correct version for project $package_name. Added to requirements without constraint.</comment>");
} else {
$this->getIO()->write("<info>Added $package_name version $version_constraint to requirements.</info>");
$this->getIO()->write("<info>Added $package_name with constraint $version_constraint to requirements.</info>");
}
}
}
Expand Down Expand Up @@ -336,4 +336,55 @@ protected function printPostScript()
$this->getIO()->write("These additional resources may also be helpful:");
$this->getIO()->write(" * <comment>https://www.lullabot.com/articles/drupal-8-composer-best-practices</comment>");
}

/**
* @param $root_composer_json
*
* @return array
*/
protected function findContribProjects($root_composer_json)
{
$modules = DrupalInspector::findContribProjects(
$this->drupalRoot,
"modules/contrib",
$root_composer_json
);
$themes = DrupalInspector::findContribProjects(
$this->drupalRoot,
"themes/contrib",
$root_composer_json
);
$profiles = DrupalInspector::findContribProjects(
$this->drupalRoot,
"profiles/contrib",
$root_composer_json
);
$projects = array_merge($modules, $themes, $profiles);
return $projects;
}

/**
* @param $projects
* @param $root_composer_json
*/
protected function addPatches($projects, $root_composer_json)
{
$projects = DrupalInspector::findProjectPatches($projects);
$patch_dir = $this->getBaseDir() . "/patches";
$this->fs->mkdir($patch_dir);
foreach ($projects as $project_name => $project) {
if (array_key_exists('patches', $project)) {
foreach ($project['patches'] as $key => $patch) {
$target_filename = $patch_dir . "/" . basename($patch);
$this->fs->copy($patch, $target_filename);
$relative_path = $this->fs->makePathRelative(
$target_filename,
$this->getBaseDir()
);
$relative_path = rtrim($relative_path, '/');
$root_composer_json->extra->patches["drupal/" . $project_name][$relative_path] = $relative_path;
}
}
}
}
}
42 changes: 39 additions & 3 deletions src/Utility/DrupalInspector.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
class DrupalInspector
{

/**
* @param $drupal_root
* @param $subdir
* @param $composer_json
*
* @return array
*/
public static function findContribProjects($drupal_root, $subdir, $composer_json)
{
if (!file_exists($drupal_root . "/" . $subdir)) {
Expand Down Expand Up @@ -43,7 +50,33 @@ public static function findContribProjects($drupal_root, $subdir, $composer_json
if ($semantic_version === false) {
$semantic_version = null;
}
$projects[$machine_name] = $semantic_version;
$projects[$machine_name]["version"] = $semantic_version;
$projects[$machine_name]["dir"] = dirname($path);
}

return $projects;
}

/**
* Finds all *.patch files contrib projects listed in $projects.
*
* @param array $projects
* An array of contrib projects returned by self::findContribProjects().
*
* @return array
*/
public static function findProjectPatches($projects)
{
foreach ($projects as $project_name => $project) {
$finder = new Finder();
$finder->in([$project['dir']])
->name('*.patch')
->files();

foreach ($finder as $fileInfo) {
$pathname = $fileInfo->getPathname();
$projects[$project_name]['patches'][] = $pathname;
}
}

return $projects;
Expand Down Expand Up @@ -108,9 +141,12 @@ public static function getVersionConstraint($version, $exact_versions)
}

/**
* @param $matches
* Determines the version of Drupal core by looking at Drupal.php contents.
*
* @param string $file_contents
* The contents of Drupal.php.
*
* @throws \Exception
* @return mixed|string
*/
public static function determineDrupalCoreVersionFromDrupalPhp($file_contents)
{
Expand Down
8 changes: 8 additions & 0 deletions tests/phpunit/ComposerizeDrupalCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,14 @@ protected function assertCorrectFileGeneration($relative_drupal_root)
$this->assertObjectHasAttribute($relative_drupal_root . 'themes/custom/{$name}', $composer_json->extra->{'installer-paths'});
$this->assertObjectHasAttribute($relative_drupal_root . 'libraries/{$name}', $composer_json->extra->{'installer-paths'});

// Assert patches.
$this->assertObjectHasAttribute('patches', $composer_json->extra);
$this->assertObjectHasAttribute('drupal/ctools', $composer_json->extra->patches);
$patch_relative_path = "patches/test.patch";
$this->assertObjectHasAttribute('drupal/ctools', $composer_json->extra->patches);
$this->assertObjectHasAttribute($patch_relative_path, $composer_json->extra->patches->{"drupal/ctools"});
$this->assertEquals($patch_relative_path, $composer_json->extra->patches->{"drupal/ctools"}->{$patch_relative_path});

// Assert merge-plugin.
$this->assertContains($relative_drupal_root . "modules/custom/*/composer.json", $composer_json->extra->{'merge-plugin'}->include);
}
Expand Down
4 changes: 3 additions & 1 deletion tests/phpunit/DrupalInspectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ public function testFindModules()
$composer_json = json_decode(file_get_contents($this->sandbox . "/docroot/composer.json"));
$modules = DrupalInspector::findContribProjects($this->sandbox . "/docroot", "modules/contrib", $composer_json);
$this->assertArrayHasKey('ctools', $modules);
$this->assertContains('3.0.0', $modules);
$this->assertArrayHasKey('version', $modules['ctools']);
$this->assertArrayHasKey('dir', $modules['ctools']);
$this->assertContains('3.0.0', $modules['ctools']['version']);
}

/**
Expand Down
2 changes: 2 additions & 0 deletions tests/phpunit/src/SandboxManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ public function makeSandbox()
$this->fs->mirror($sandbox_master, $sandbox);
$this->dowloadAndCopyDrupalCore($this->drupalVersion, $this->tmp, $sandbox);
$this->downloadAndCopyCtools($this->tmp, $sandbox);
// Create fake patch for ctools.
$this->fs->touch($sandbox . "/docroot/modules/contrib/ctools/test.patch");

chdir($sandbox);
$process = new Process(
Expand Down

0 comments on commit 66245c8

Please sign in to comment.