Skip to content

Commit

Permalink
add relative symlink patch for Phing
Browse files Browse the repository at this point in the history
  • Loading branch information
byrond committed Dec 23, 2021
1 parent 6e5f027 commit 7cdc28b
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 2 deletions.
10 changes: 9 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
"bin/the-build-installer"
],
"require": {
"palantirnet/phing-drush-task": "^1.1",
"cweagans/composer-patches": "^1.7",
"drupal/coder": "^8.3.6",
"drush/drush": "^9 || ^10",
"palantirnet/phing-drush-task": "^1.1",
"pear/http_request2": "^2.3",
"pear/versioncontrol_git": "@dev",
"phing/phing": "^2.14",
Expand All @@ -27,5 +28,12 @@
},
"config": {
"sort-packages": true
},
"extra": {
"patches": {
"phing/phing": {
"Support relative symliks in Phing": "patches/phing-relative-symlinks.patch"
}
}
}
}
76 changes: 76 additions & 0 deletions patches/phing-relative-symlinks.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
diff --git a/classes/phing/tasks/ext/SymlinkTask.php b/classes/phing/tasks/ext/SymlinkTask.php
index f132b4f747..87844a0d09 100644
--- a/classes/phing/tasks/ext/SymlinkTask.php
+++ b/classes/phing/tasks/ext/SymlinkTask.php
@@ -206,6 +206,46 @@ public function isRelative()
return $this->relative;
}

+ /**
+ * Given an existing path, convert it to a path relative to a given starting path.
+ *
+ * @param string $endPath Absolute path of target
+ * @param string $startPath Absolute path where traversal begins
+ *
+ * @return string Path of target relative to starting path
+ */
+ public function makePathRelative($endPath, $startPath)
+ {
+ // Normalize separators on Windows
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $endPath = str_replace('\\', '/', $endPath);
+ $startPath = str_replace('\\', '/', $startPath);
+ }
+
+ // Split the paths into arrays
+ $startPathArr = explode('/', trim($startPath, '/'));
+ $endPathArr = explode('/', trim($endPath, '/'));
+
+ // Find for which directory the common path stops
+ $index = 0;
+ while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) {
+ ++$index;
+ }
+
+ // Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels)
+ $depth = count($startPathArr) - $index;
+
+ // Repeated "../" for each level need to reach the common path
+ $traverser = str_repeat('../', $depth);
+
+ $endPathRemainder = implode('/', array_slice($endPathArr, $index));
+
+ // Construct $endPath from traversing to the common path, then to the remaining $endPath
+ $relativePath = $traverser.('' !== $endPathRemainder ? $endPathRemainder.'/' : '');
+
+ return '' === $relativePath ? './' : $relativePath;
+ }
+
/**
* Generates an array of directories / files to be linked
* If _filesets is empty, returns getTarget()
@@ -235,11 +275,7 @@ protected function getMap()
throw new BuildException('Link must be an existing directory when using fileset');
}

- if ($this->isRelative()) {
- $fromDir = $fs->getDir($this->getProject())->getPath();
- } else {
- $fromDir = $fs->getDir($this->getProject())->getAbsolutePath();
- }
+ $fromDir = $fs->getDir($this->getProject())->getAbsolutePath();

if (!is_dir($fromDir)) {
$this->log('Directory doesn\'t exist: ' . $fromDir, Project::MSG_WARN);
@@ -300,6 +336,11 @@ protected function symlink($target, $link)
{
$fs = FileSystem::getFileSystem();

+ if ($this->isRelative()) {
+ $link =(new PhingFile($link))->getAbsolutePath();
+ $target = rtrim($this->makePathRelative($target, dirname($link)), '/');
+ }
+
if (is_link($link) && @readlink($link) == $target) {
$this->log('Link exists: ' . $link, Project::MSG_INFO);

2 changes: 1 addition & 1 deletion targets/drupal.xml
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ Or, you can specify the export file directly:
<target name="drupal-first-install" depends="set-site" hidden="true">
<fail unless="drupal.site.admin_user" />

<symlink link="${build.dir}/${drupal.root}/modules/contrib/the_build_utility" target="${build.thebuild.dir}/defaults/standard/modules/the_build_utility" />
<symlink link="${build.dir}/${drupal.root}/modules/contrib/the_build_utility" target="${build.thebuild.dir}/defaults/standard/modules/the_build_utility" relative="true" />

<composer command="require" composer="${composer.composer}">
<arg value="drupal/admin_toolbar" />
Expand Down

0 comments on commit 7cdc28b

Please sign in to comment.