From 935a66d3149f12d21cff6ec3d17aa48a06bd53a8 Mon Sep 17 00:00:00 2001 From: Otto Rask Date: Mon, 25 Sep 2017 16:58:23 +0300 Subject: [PATCH 1/2] Add option for copying files instead of moving them Adds a new composer.json config flag which allows devs to decide if the dropin files should be copied instead of moved from the source to the destination. --- readme.md | 15 ++++++++++ src/Dropin.php | 80 ++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 90 insertions(+), 5 deletions(-) diff --git a/readme.md b/readme.md index cd45a3a..62ace07 100644 --- a/readme.md +++ b/readme.md @@ -96,6 +96,21 @@ I created this originally for installing multiple languages for WordPress with c } ``` +## Moving v. copying files + +By default this dropin installer moves files from the source to the destination, +which means the files disappear from the source. + +If you would prefer copying instead (which keeps the files at the source after +installation) insert the following configuration to your `composer.json` `config` +declarations: + +```json +"config": { + "dropin-installer": "copy" +} +``` + ##But how about the impossible looking syntax? Dropin syntax consists from four parts: ```"{path}": "{directive}:{target}:{files}"``` diff --git a/src/Dropin.php b/src/Dropin.php index aa77255..af6f062 100644 --- a/src/Dropin.php +++ b/src/Dropin.php @@ -170,13 +170,27 @@ public function dropNewFiles(PackageInterface $package){ $src = "{$vendorDir}/{$info['package']}"; } + $config = $this->composer->getPackage()->getConfig(); + $shouldCopy = isset($config['dropin-installer']) && $config['dropin-installer'] === 'copy'; + $installFiles = self::getFilesToInstall($info); - $this->io->write(" Moving dropin files...\n"); - if ($installFiles == "*") { - self::rmove($src,$dest); + if ($shouldCopy) { + $this->io->write(" Copying dropin files...\n"); + if ($installFiles == "*") { + self::rcopy($src, $dest); + } else { + foreach ($installFiles as $file) { + self::copy("{$src}/{$file}", $dest); + } + } } else { - foreach($installFiles as $file) { - self::move("{$src}/{$file}",$dest); + $this->io->write(" Moving dropin files...\n"); + if ($installFiles == "*") { + self::rmove($src, $dest); + } else { + foreach ($installFiles as $file) { + self::move("{$src}/{$file}", $dest); + } } } } @@ -300,6 +314,62 @@ private static function move($src, $dest){ } rename($src, "$dest/" . basename($src)); } + /** + * Recursively copy files from one directory to another + * + * @param string $src - Source of files being copied + * @param string $dest - Destination of files being copied + */ + private static function rcopy($src, $dest){ + // If source is not a directory stop processing + if(!is_dir($src)) { + echo "Source is not a directory"; + return false; + } + + // If the destination directory does not exist create it + if(!is_dir($dest)) { + if(!mkdir($dest,0777,true)) { + // If the destination directory could not be created stop processing + echo "Can't create destination path: {$dest}\n"; + return false; + } + } + + // Open the source directory to read in files + $i = new \DirectoryIterator($src); + foreach($i as $f) { + #Skip useless files&folders + if (self::isFileIgnored($f->getFilename())) continue; + + if($f->isFile()) { + copy($f->getRealPath(), "$dest/" . $f->getFilename()); + } else if(!$f->isDot() && $f->isDir()) { + self::rcopy($f->getRealPath(), "$dest/$f"); + #unlink($f->getRealPath()); + } + } + #We could Remove original directories but don't do it + #unlink($src); + } + /** + * Copy a file from one location to another. + * + * @param $src - File being copied + * @param $dest - Destinatin directory + */ + private static function copy($src, $dest) + { + // If the destination directory does not exist create it + if(!is_dir($dest)) { + if(!mkdir($dest,0777,true)) { + // If the destination directory could not be created stop processing + echo "Can't create destination path: {$dest}\n"; + return false; + } + } + copy($src, "$dest/" . basename($src)); + } /** * Returns type and information of dropin directive */ From 6c258804e7dc7e947a14304cc1827bad02149d16 Mon Sep 17 00:00:00 2001 From: Otto Rask Date: Fri, 22 Dec 2017 14:14:45 +0200 Subject: [PATCH 2/2] Add tests for copy flag installations Also introduce composer test command and alter test setup a little. --- .gitignore | 9 +++-- .travis.yml | 9 +++-- composer.json | 6 +++ readme.md | 11 +++++- ...oodimonniComposerCopiedFilesExistsTest.php | 15 ++++++++ tests/copy/composer.json | 38 +++++++++++++++++++ tests/{ => copy}/phpunit.xml | 0 ...oodimonniComposerMovedFilesExistsTest.php} | 6 +-- tests/{ => move}/composer.json | 0 tests/move/phpunit.xml | 6 +++ tests/testpkg/composer.json | 5 +++ tests/testpkg/dropin-test.php | 3 ++ 12 files changed, 98 insertions(+), 10 deletions(-) create mode 100644 tests/copy/KoodimonniComposerCopiedFilesExistsTest.php create mode 100644 tests/copy/composer.json rename tests/{ => copy}/phpunit.xml (100%) rename tests/{KoodimonniComposerFilesExistsTest.php => move/KoodimonniComposerMovedFilesExistsTest.php} (79%) rename tests/{ => move}/composer.json (100%) create mode 100644 tests/move/phpunit.xml create mode 100644 tests/testpkg/composer.json create mode 100644 tests/testpkg/dropin-test.php diff --git a/.gitignore b/.gitignore index 44e33d9..65bb426 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,9 @@ composer.lock # Stuff from tests -tests/htdocs -tests/vendor -tests/composer.lock \ No newline at end of file +tests/move/htdocs +tests/copy/htdocs +tests/move/vendor +tests/copy/vendor +tests/move/composer.lock +tests/copy/composer.lock diff --git a/.travis.yml b/.travis.yml index 16cf310..a3bb4e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,10 +18,12 @@ before_script: # We use the same repo straight from github because it required lesser amount of hacks # Here we force the same current git commit id for composer - - sed -i -e "s|%%TRAVIS_COMMIT%%|$TRAVIS_COMMIT|g" tests/composer.json + - sed -i -e "s|%%TRAVIS_COMMIT%%|$TRAVIS_COMMIT|g" tests/move/composer.json + - sed -i -e "s|%%TRAVIS_COMMIT%%|$TRAVIS_COMMIT|g" tests/copy/composer.json # Install test run into tests/ folder using tests/composer.json - - composer install --working-dir=./tests/ + - composer install --working-dir=./tests/move/ + - composer install --working-dir=./tests/copy/ script: # Sanity php syntax check @@ -31,4 +33,5 @@ script: - composer validate composer.json # Run the real tests finally - - "phpunit tests/*.php" + - "vendor/bin/phpunit tests/move/*.php" + - "vendor/bin/phpunit tests/copy/*.php" diff --git a/composer.json b/composer.json index 8a551d4..7e52dfa 100644 --- a/composer.json +++ b/composer.json @@ -24,5 +24,11 @@ }, "extra": { "class": "Koodimonni\\Composer\\Dropin" + }, + "scripts": { + "test": [ + "composer install --working-dir=./tests/move/ && vendor/bin/phpunit ./tests/move/*.php", + "composer install --working-dir=./tests/copy/ && vendor/bin/phpunit ./tests/copy/*.php" + ] } } diff --git a/readme.md b/readme.md index 62ace07..3097c62 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,7 @@ [![Build Status](https://travis-ci.org/Koodimonni/Composer-Dropin-Installer.svg?branch=master)](https://travis-ci.org/Koodimonni/Composer-Dropin-Installer) [![Latest Stable Version](https://poser.pugx.org/koodimonni/composer-dropin-installer/v/stable)](https://packagist.org/packages/koodimonni/composer-dropin-installer) [![Total Downloads](https://poser.pugx.org/koodimonni/composer-dropin-installer/downloads)](https://packagist.org/packages/koodimonni/composer-dropin-installer) [![Latest Unstable Version](https://poser.pugx.org/koodimonni/composer-dropin-installer/v/unstable)](https://packagist.org/packages/koodimonni/composer-dropin-installer) [![License](https://poser.pugx.org/koodimonni/composer-dropin-installer/license)](https://packagist.org/packages/koodimonni/composer-dropin-installer) -This composer plugin helps you to move your composer packaged files where you want them to be. +This composer plugin helps you to move or copy your composer packaged files where you want them to be. Composer only allows you to install full directories into their own directories. There's really useful [composer/installers](https://github.com/composer/installers) for custom installation paths but it overwrites everything in folder and doesn't allow coexist of two or more projects. We just let composer install things and take it from there. @@ -141,6 +141,15 @@ phpunit.xml ``` * Script requires unix filesystem (OS X,Linux) +## Testing + +Run PHPUnit tests with + + $ composer test + +Tests are run inside the `tests/` directory where two dummy Composer projects are used to test dropin +installation methods. + ##Todo * Handle deletions on removal and on update. This could be easily done with json-database in [vendor-dir] diff --git a/tests/copy/KoodimonniComposerCopiedFilesExistsTest.php b/tests/copy/KoodimonniComposerCopiedFilesExistsTest.php new file mode 100644 index 0000000..13fbf41 --- /dev/null +++ b/tests/copy/KoodimonniComposerCopiedFilesExistsTest.php @@ -0,0 +1,15 @@ +assertFileExists(dirname( __FILE__ ) . '/htdocs/dropin-test.php'); + } + public function testPackageFileExistsInVendor() + { + $this->assertFileExists(dirname( __FILE__ ) . '/vendor/dropininternal/dropin-test-package/dropin-test.php'); + } + +} diff --git a/tests/copy/composer.json b/tests/copy/composer.json new file mode 100644 index 0000000..b9f1bb4 --- /dev/null +++ b/tests/copy/composer.json @@ -0,0 +1,38 @@ +{ + "name": "koodimonni/composer-dropin-installer-tests", + "description": "composer.json for testing composer-dropin-installer", + "license": "WTFPL", + "type": "project", + "authors": [ + { + "name": "Onni Hakala", + "email": "onni@koodimonni.fi" + } + ], + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/Koodimonni/Composer-Dropin-Installer" + }, + { + "type": "path", + "url": "../testpkg" + }, + { + "packagist": false + } + ], + "require": { + "koodimonni/composer-dropin-installer": "dev-master#%%TRAVIS_COMMIT%%", + "dropininternal/dropin-test-package": "dev-master" + }, + "extra": { + "dropin-paths": { + "htdocs/": ["package:dropininternal/dropin-test-package"] + } + }, + "config": { + "dropin-installer": "copy" + }, + "minimum-stability": "dev" +} diff --git a/tests/phpunit.xml b/tests/copy/phpunit.xml similarity index 100% rename from tests/phpunit.xml rename to tests/copy/phpunit.xml diff --git a/tests/KoodimonniComposerFilesExistsTest.php b/tests/move/KoodimonniComposerMovedFilesExistsTest.php similarity index 79% rename from tests/KoodimonniComposerFilesExistsTest.php rename to tests/move/KoodimonniComposerMovedFilesExistsTest.php index 73a8f8c..422407f 100644 --- a/tests/KoodimonniComposerFilesExistsTest.php +++ b/tests/move/KoodimonniComposerMovedFilesExistsTest.php @@ -1,7 +1,7 @@ assertFileExists(dirname( __FILE__ ) . '/htdocs/wp-content/languages/fi.po'); @@ -11,4 +11,4 @@ public function testFinnishLanguageNotExistsInVendor() $this->assertFileNotExists(dirname( __FILE__ ) . '/vendor/koodimonni-language/fi/fi.po'); } -} \ No newline at end of file +} diff --git a/tests/composer.json b/tests/move/composer.json similarity index 100% rename from tests/composer.json rename to tests/move/composer.json diff --git a/tests/move/phpunit.xml b/tests/move/phpunit.xml new file mode 100644 index 0000000..e197d83 --- /dev/null +++ b/tests/move/phpunit.xml @@ -0,0 +1,6 @@ + + + + ./ + + \ No newline at end of file diff --git a/tests/testpkg/composer.json b/tests/testpkg/composer.json new file mode 100644 index 0000000..19d087a --- /dev/null +++ b/tests/testpkg/composer.json @@ -0,0 +1,5 @@ +{ + "name": "dropininternal/dropin-test-package", + "type": "library", + "version": "dev-master" +} diff --git a/tests/testpkg/dropin-test.php b/tests/testpkg/dropin-test.php new file mode 100644 index 0000000..2056365 --- /dev/null +++ b/tests/testpkg/dropin-test.php @@ -0,0 +1,3 @@ +