diff --git a/composer.json b/composer.json
index 358607e..d16ecab 100644
--- a/composer.json
+++ b/composer.json
@@ -20,6 +20,10 @@
"dev-master": "1.x-dev"
}
},
+ "scripts": {
+ "lint": "phpcs src/",
+ "lint-clean": "phpcbf src/"
+ },
"require": {
"composer-plugin-api": "^1.1"
},
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
new file mode 100644
index 0000000..dc3e763
--- /dev/null
+++ b/phpcs.xml.dist
@@ -0,0 +1,2 @@
+
+
diff --git a/src/RecipeCommandBehaviour.php b/src/RecipeCommandBehaviour.php
index c6bcc32..27cc83a 100644
--- a/src/RecipeCommandBehaviour.php
+++ b/src/RecipeCommandBehaviour.php
@@ -242,7 +242,7 @@ trait RecipeCommandBehaviour
// Add new require / extra-installed
$composerData['require'] = $require;
- if ($previouslyInstalled){
+ if ($previouslyInstalled) {
if (!isset($composerData['extra'])) {
$composerData['extra'] = [];
}
diff --git a/src/RecipeInstaller.php b/src/RecipeInstaller.php
index d14b999..767c660 100644
--- a/src/RecipeInstaller.php
+++ b/src/RecipeInstaller.php
@@ -14,9 +14,11 @@ use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use RegexIterator;
-class RecipeInstaller extends LibraryInstaller {
+class RecipeInstaller extends LibraryInstaller
+{
- public function __construct(IOInterface $io, Composer $composer) {
+ public function __construct(IOInterface $io, Composer $composer)
+ {
parent::__construct($io, $composer, null);
}
@@ -30,8 +32,14 @@ class RecipeInstaller extends LibraryInstaller {
* @param string $registrationKey Registration key for installed files
* @param string $name Name of project file type being installed
*/
- protected function installProjectFiles($recipe, $sourceRoot, $destinationRoot, $filePatterns, $registrationKey, $name = 'project')
- {
+ protected function installProjectFiles(
+ $recipe,
+ $sourceRoot,
+ $destinationRoot,
+ $filePatterns,
+ $registrationKey,
+ $name = 'project'
+ ) {
// load composer json data
$composerFile = new JsonFile(Factory::getComposerFile(), null, $this->io);
$composerData = $composerFile->read();
@@ -42,38 +50,15 @@ class RecipeInstaller extends LibraryInstaller {
// Load all project files
$fileIterator = $this->getFileIterator($sourceRoot, $filePatterns);
$any = false;
- foreach($fileIterator as $path => $info) {
- $destination = $destinationRoot . substr($path, strlen($sourceRoot));
- $relativePath = substr($path, strlen($sourceRoot) + 1); // Name path without leading '/'
-
- // Write header
+ foreach ($fileIterator as $path => $info) {
+ // Write header on first file
if (!$any) {
$this->io->write("Installing {$name} files for recipe {$recipe}:");
$any = true;
}
- // Check if file exists
- if (file_exists($destination)) {
- if (file_get_contents($destination) === file_get_contents($path)) {
- $this->io->write(
- " - Skipping $relativePath (existing, but unchanged)"
- );
- } else {
- $this->io->write(
- " - Skipping $relativePath (existing and modified in project)"
- );
- }
- } elseif (in_array($relativePath, $installedFiles)) {
- // Don't re-install previously installed files that have been deleted
- $this->io->write(
- " - Skipping $relativePath (previously installed)"
- );
- } else {
- $any++;
- $this->io->write(" - Copying $relativePath");
- $this->filesystem->ensureDirectoryExists(dirname($destination));
- copy($path, $destination);
- }
+ // Install this file
+ $relativePath = $this->installProjectFile($sourceRoot, $destinationRoot, $path, $installedFiles);
// Add file to installed (even if already exists)
if (!in_array($relativePath, $installedFiles)) {
@@ -92,6 +77,46 @@ class RecipeInstaller extends LibraryInstaller {
}
}
+ /**
+ * @param string $sourceRoot Base of source files (no trailing slash)
+ * @param string $destinationRoot Base of destination directory (no trailing slash)
+ * @param string $sourcePath Full filesystem path to the file to copy
+ * @param array $installedFiles List of installed files
+ * @return bool|string
+ */
+ protected function installProjectFile($sourceRoot, $destinationRoot, $sourcePath, $installedFiles)
+ {
+ // Relative path
+ $relativePath = substr($sourcePath, strlen($sourceRoot) + 1); // Name path without leading '/'
+
+ // Get destination path
+ $relativeDestination = $this->rewriteFilePath($destinationRoot, $relativePath);
+ $destination = $destinationRoot . DIRECTORY_SEPARATOR . $relativeDestination;
+
+ // Check if file exists
+ if (file_exists($destination)) {
+ if (file_get_contents($destination) === file_get_contents($sourcePath)) {
+ $this->io->write(
+ " - Skipping $relativePath (existing, but unchanged)"
+ );
+ } else {
+ $this->io->write(
+ " - Skipping $relativePath (existing and modified in project)"
+ );
+ }
+ } elseif (in_array($relativePath, $installedFiles) || in_array($relativeDestination, $installedFiles)) {
+ // Don't re-install previously installed files that have been deleted
+ $this->io->write(
+ " - Skipping $relativePath (previously installed)"
+ );
+ } else {
+ $this->io->write(" - Copying $relativePath");
+ $this->filesystem->ensureDirectoryExists(dirname($destination));
+ copy($sourcePath, $destination);
+ }
+ return $relativePath;
+ }
+
/**
* Get iterator of matching source files to copy
*
@@ -99,10 +124,11 @@ class RecipeInstaller extends LibraryInstaller {
* @param array $patterns List of wildcard patterns to match
* @return Iterator File iterator, where key is path and value is file info object
*/
- protected function getFileIterator($sourceRoot, $patterns) {
+ protected function getFileIterator($sourceRoot, $patterns)
+ {
// Build regexp pattern
$expressions = [];
- foreach($patterns as $pattern) {
+ foreach ($patterns as $pattern) {
$expressions[] = $this->globToRegexp($pattern);
}
$regExp = '#^' . $this->globToRegexp($sourceRoot . '/').'(('.implode(')|(', $expressions).'))$#';
@@ -127,9 +153,10 @@ class RecipeInstaller extends LibraryInstaller {
* @param string $glob
* @return string
*/
- protected function globToRegexp($glob) {
+ protected function globToRegexp($glob)
+ {
$sourceParts = explode('*', $glob);
- $regexParts = array_map(function($part) {
+ $regexParts = array_map(function ($part) {
return preg_quote($part, '#');
}, $sourceParts);
return implode('(.+)', $regexParts);
@@ -183,4 +210,38 @@ class RecipeInstaller extends LibraryInstaller {
);
}
}
+
+ /**
+ * Perform any file rewrites necessary to a relative path of a file being installed.
+ * E.g. if 'mysite' folder exists, rewrite 'mysite' to 'app' and 'mysite/code' to 'app/src'
+ *
+ * @deprecated 1.2..2.0 Will be removed in 2.0; app folder will be hard coded and no
+ * rewrites supported.
+ * @param string $destinationRoot Project root
+ * @param string $relativePath Relative path to the resource being installed
+ * @return string Relative path we should write to
+ */
+ protected function rewriteFilePath($destinationRoot, $relativePath)
+ {
+ // If app folder exists, no rewrite
+ if (is_dir($destinationRoot . DIRECTORY_SEPARATOR . 'app')) {
+ return $relativePath;
+ }
+ // if mysite folder does NOT exist, no rewrite
+ if (!is_dir($destinationRoot . DIRECTORY_SEPARATOR . 'mysite')) {
+ return $relativePath;
+ }
+
+ // Return first rewrite
+ $rewrites = [
+ 'app/src' => 'mysite/code',
+ 'app' => 'mysite',
+ ];
+ foreach ($rewrites as $from => $to) {
+ if (stripos($relativePath, $from) === 0) {
+ return $to . substr($relativePath, strlen($from));
+ }
+ }
+ return $relativePath;
+ }
}