[WIP] Issue 1135 create project in existing directory #1206

Closed
wants to merge 7 commits into
from
View
13 src/Composer/Downloader/VcsDownloader.php
@@ -55,7 +55,11 @@ public function download(PackageInterface $package, $path)
}
$this->io->write(" - Installing <info>" . $package->getName() . "</info> (<comment>" . VersionParser::formatVersion($package) . "</comment>)");
- $this->filesystem->removeDirectory($path);
+
+ if (!$this->filesystem->directoryIsEmpty($path, array('composer.json'))) {
+ $this->filesystem->removeDirectory($path);
+ }
+
$this->doDownload($package, $path);
$this->io->write('');
}
@@ -135,9 +139,10 @@ public function remove(PackageInterface $package, $path)
/**
* Prompt the user to check if changes should be stashed/removed or the operation aborted
*
- * @param string $path
- * @param bool $stash if true (update) the changes can be stashed and reapplied after an update,
- * if false (remove) the changes should be assumed to be lost if the operation is not aborted
+ * @param string $path
+ * @param Boolean $update if true (update) the changes can be stashed and reapplied after an update,
+ * if false (remove) the changes should be assumed to be lost if the operation is not aborted
+ *
* @throws \RuntimeException in case the operation must be aborted
*/
protected function cleanChanges($path, $update)
View
16 src/Composer/Installer/ProjectInstaller.php
@@ -15,6 +15,7 @@
use Composer\Package\PackageInterface;
use Composer\Downloader\DownloadManager;
use Composer\Repository\InstalledRepositoryInterface;
+use Composer\Util\Filesystem;
/**
* Project Installer is used to install a single package into a directory as
@@ -58,13 +59,16 @@ public function isInstalled(InstalledRepositoryInterface $repo, PackageInterface
public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
{
$installPath = $this->installPath;
- if (file_exists($installPath)) {
- throw new \InvalidArgumentException("Project directory $installPath already exists.");
- }
- if (!file_exists(dirname($installPath))) {
- throw new \InvalidArgumentException("Project root " . dirname($installPath) . " does not exist.");
+ $fs = new FileSystem();
+
+ if ($fs->directoryExists($installPath)) {
+ if (!$fs->directoryIsEmpty($installPath, array('composer.json'))) {
+ throw new \InvalidArgumentException("Project directory \"$installPath\" must be empty.");
+ }
+ } else {
+ mkdir($installPath, 0777, true);
}
- mkdir($installPath, 0777);
+
$this->downloadManager->download($package, $installPath);
}
View
27 src/Composer/Util/Filesystem.php
@@ -74,6 +74,33 @@ public function ensureDirectoryExists($directory)
}
}
+ public function directoryExists($dir)
+ {
+ return is_dir($dir);
+ }
+
+ /**
+ * @param string $dir
+ * @param array $excluding
+ * @return bool
+ * @throws \RuntimeException
+ */
+ public function directoryIsEmpty($dir, $excluding = array())
+ {
+ if (!$this->directoryExists($dir)) {
+ throw new \RuntimeException("Directory \"$dir\" does not exist");
+ }
+
+ $excludeList = array('.', '..');
+ if (!empty($excluding)) {
+ $excludeList = array_merge($excludeList, $excluding);
+ }
+
+ $dirContent = array_diff(scandir($dir), $excludeList);
+
+ return empty($dirContent);
+ }
+
public function rename($source, $target)
{
if (true === @rename($source, $target)) {
View
3 tests/Composer/Test/Fixtures/projectTestDirectory/composer.json
@@ -0,0 +1,3 @@
+{
+ "name": "vendor/package-name-sample"
+}
View
33 tests/Composer/Test/Util/FilesystemTest.php
@@ -93,4 +93,37 @@ public function providePathCouples()
array('C:/Temp', 'c:\Temp\test', "test"),
);
}
+
+ public function testDirectoryExists()
+ {
+ $fs = new Filesystem();
+ $directory1 = '/does/not/exist';
+ $directory2 = __DIR__;
+
+ $this->assertFalse($fs->directoryExists($directory1));
+ $this->assertTrue($fs->directoryExists($directory2));
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testDirectoryIsEmptyRuntimeException()
+ {
+ $fs = new Filesystem();
+ $dir = '/does/not/exist';
+
+ $fs->directoryIsEmpty($dir);
+ }
+
+ public function testDirectoryIsEmpty()
+ {
+ $fs = new Filesystem();
+ $dir = __DIR__;
+ $project = __DIR__.'/../Fixtures/projectTestDirectory';
+
+ $this->assertFalse($fs->directoryIsEmpty($dir));
+ $this->assertTrue($fs->directoryIsEmpty($project, array('composer.json')));
+ $this->assertFalse($fs->directoryIsEmpty($project));
+
+ }
}