Browse Source

Tweak --no-cache option to be available globally and to not break VCS drivers relying on it, refs #7880, refs #6650

Jordi Boggiano 6 years ago
parent
commit
02ceb74151

+ 2 - 0
doc/03-cli.md

@@ -22,6 +22,8 @@ The following options are available with every command:
 * **--quiet (-q):** Do not output any message.
 * **--no-interaction (-n):** Do not ask any interactive question.
 * **--no-plugins:** Disables plugins.
+* **--no-cache:** Disables the use of the cache directory. Same as setting the COMPOSER_CACHE_DIR
+  env var to /dev/null (or NUL on Windows).
 * **--working-dir (-d):** If specified, use the given directory as working directory.
 * **--profile:** Display timing and memory usage information
 * **--ansi:** Force ANSI output.

+ 6 - 1
src/Composer/Cache.php

@@ -44,7 +44,7 @@ class Cache
         $this->whitelist = $whitelist;
         $this->filesystem = $filesystem ?: new Filesystem();
 
-        if (preg_match('{(^|[\\\\/])(\$null|NUL|/dev/null)([\\\\/]|$)}', $cacheDir)) {
+        if (!self::isUsable($cacheDir)) {
             $this->enabled = false;
 
             return;
@@ -59,6 +59,11 @@ class Cache
         }
     }
 
+    public static function isUsable($path)
+    {
+        return !preg_match('{(^|[\\\\/])(\$null|nul|NUL|/dev/null)([\\\\/]|$)}', $path);
+    }
+
     public function isEnabled()
     {
         return $this->enabled;

+ 0 - 14
src/Composer/Command/InstallCommand.php

@@ -15,7 +15,6 @@ namespace Composer\Command;
 use Composer\Installer;
 use Composer\Plugin\CommandEvent;
 use Composer\Plugin\PluginEvents;
-use Composer\Util\Platform;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Input\InputArgument;
@@ -41,7 +40,6 @@ class InstallCommand extends BaseCommand
                 new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
                 new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of require-dev packages (enabled by default, only present for BC).'),
                 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'),
-                new InputOption('no-cache', null, InputOption::VALUE_NONE, 'Do not use the cache directory'),
                 new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'DEPRECATED: Use no-plugins instead.'),
                 new InputOption('no-autoloader', null, InputOption::VALUE_NONE, 'Skips autoloader generation'),
                 new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'),
@@ -95,18 +93,6 @@ EOT
         $install = Installer::create($io, $composer);
 
         $config = $composer->getConfig();
-
-        if ($input->getOption('no-cache')) {
-            $io->write('Skipping cache directory');
-            $config->merge(
-                array(
-                    'config' => array(
-                        'cache-dir' => Platform::isWindows() ? 'nul' : '/dev/null',
-                    )
-                )
-            );
-        }
-
         list($preferSource, $preferDist) = $this->getPreferredInstallOptions($config, $input);
 
         $optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader');

+ 0 - 14
src/Composer/Command/UpdateCommand.php

@@ -17,7 +17,6 @@ use Composer\Installer;
 use Composer\IO\IOInterface;
 use Composer\Plugin\CommandEvent;
 use Composer\Plugin\PluginEvents;
-use Composer\Util\Platform;
 use Symfony\Component\Console\Helper\Table;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
@@ -45,7 +44,6 @@ class UpdateCommand extends BaseCommand
                 new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of require-dev packages (enabled by default, only present for BC).'),
                 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'),
                 new InputOption('lock', null, InputOption::VALUE_NONE, 'Only updates the lock file hash to suppress warning about the lock file being out of date.'),
-                new InputOption('no-cache', null, InputOption::VALUE_NONE, 'Do not use the cache directory'),
                 new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'DEPRECATED: Use no-plugins instead.'),
                 new InputOption('no-autoloader', null, InputOption::VALUE_NONE, 'Skips autoloader generation'),
                 new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'),
@@ -130,18 +128,6 @@ EOT
         $install = Installer::create($io, $composer);
 
         $config = $composer->getConfig();
-
-        if ($input->getOption('no-cache')) {
-            $io->write('Skipping cache directory');
-            $config->merge(
-                array(
-                    'config' => array(
-                        'cache-dir' => Platform::isWindows() ? 'nul' : '/dev/null',
-                    )
-                )
-            );
-        }
-
         list($preferSource, $preferDist) = $this->getPreferredInstallOptions($config, $input);
 
         $optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader');

+ 6 - 0
src/Composer/Console/Application.php

@@ -118,6 +118,11 @@ class Application extends BaseApplication
         )));
         ErrorHandler::register($io);
 
+        if ($input->hasParameterOption('--no-cache')) {
+            $io->writeError('Disabling cache usage', true, IOInterface::DEBUG);
+            putenv('COMPOSER_CACHE_DIR='.(Platform::isWindows() ? 'nul' : '/dev/null'));
+        }
+
         // switch working dir
         if ($newWorkDir = $this->getNewWorkingDir($input)) {
             $oldWorkingDir = getcwd();
@@ -451,6 +456,7 @@ class Application extends BaseApplication
         $definition->addOption(new InputOption('--profile', null, InputOption::VALUE_NONE, 'Display timing and memory usage information'));
         $definition->addOption(new InputOption('--no-plugins', null, InputOption::VALUE_NONE, 'Whether to disable plugins.'));
         $definition->addOption(new InputOption('--working-dir', '-d', InputOption::VALUE_REQUIRED, 'If specified, use the given directory as working directory.'));
+        $definition->addOption(new InputOption('--no-cache', null, InputOption::VALUE_NONE, 'Prevent use of the cache'));
 
         return $definition;
     }

+ 2 - 1
src/Composer/Downloader/GitDownloader.php

@@ -19,6 +19,7 @@ use Composer\Util\Filesystem;
 use Composer\Util\Git as GitUtil;
 use Composer\Util\Platform;
 use Composer\Util\ProcessExecutor;
+use Composer\Cache;
 
 /**
  * @author Jordi Boggiano <j.boggiano@seld.be>
@@ -51,7 +52,7 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
         $msg = "Cloning ".$this->getShortHash($ref);
 
         $command = 'git clone --no-checkout %url% %path% && cd '.$flag.'%path% && git remote add composer %url% && git fetch composer';
-        if ($gitVersion && version_compare($gitVersion, '2.3.0-rc0', '>=')) {
+        if ($gitVersion && version_compare($gitVersion, '2.3.0-rc0', '>=') && Cache::isUsable($cachePath)) {
             $this->io->writeError('', true, IOInterface::DEBUG);
             $this->io->writeError(sprintf('    Cloning to cache at %s', ProcessExecutor::escape($cachePath)), true, IOInterface::DEBUG);
             try {

+ 5 - 0
src/Composer/Repository/Vcs/FossilDriver.php

@@ -12,6 +12,7 @@
 
 namespace Composer\Repository\Vcs;
 
+use Composer\Cache;
 use Composer\Config;
 use Composer\Util\ProcessExecutor;
 use Composer\Util\Filesystem;
@@ -45,6 +46,10 @@ class FossilDriver extends VcsDriver
         if (Filesystem::isLocalPath($this->url) && is_dir($this->url)) {
             $this->checkoutDir = $this->url;
         } else {
+            if (!Cache::isUsable($this->config->get('cache-repo-dir')) || !Cache::isUsable($this->config->get('cache-vcs-dir'))) {
+                throw new \RuntimeException('FossilDriver requires a usable cache directory, and it looks like you set it to be disabled');
+            }
+
             $localName = preg_replace('{[^a-z0-9]}i', '-', $this->url);
             $this->repoFile = $this->config->get('cache-repo-dir') . '/' . $localName . '.fossil';
             $this->checkoutDir = $this->config->get('cache-vcs-dir') . '/' . $localName . '/';

+ 4 - 0
src/Composer/Repository/Vcs/GitDriver.php

@@ -41,6 +41,10 @@ class GitDriver extends VcsDriver
             $this->repoDir = $this->url;
             $cacheUrl = realpath($this->url);
         } else {
+            if (!Cache::isUsable($this->config->get('cache-vcs-dir'))) {
+                throw new \RuntimeException('GitDriver requires a usable cache directory, and it looks like you set it to be disabled');
+            }
+
             $this->repoDir = $this->config->get('cache-vcs-dir') . '/' . preg_replace('{[^a-z0-9.]}i', '-', $this->url) . '/';
 
             GitUtil::cleanEnv();

+ 5 - 0
src/Composer/Repository/Vcs/HgDriver.php

@@ -13,6 +13,7 @@
 namespace Composer\Repository\Vcs;
 
 use Composer\Config;
+use Composer\Cache;
 use Composer\Util\Hg as HgUtils;
 use Composer\Util\ProcessExecutor;
 use Composer\Util\Filesystem;
@@ -37,6 +38,10 @@ class HgDriver extends VcsDriver
         if (Filesystem::isLocalPath($this->url)) {
             $this->repoDir = $this->url;
         } else {
+            if (!Cache::isUsable($this->config->get('cache-vcs-dir'))) {
+                throw new \RuntimeException('HgDriver requires a usable cache directory, and it looks like you set it to be disabled');
+            }
+
             $cacheDir = $this->config->get('cache-vcs-dir');
             $this->repoDir = $cacheDir . '/' . preg_replace('{[^a-z0-9]}i', '-', $this->url) . '/';
 

+ 5 - 0
src/Composer/Repository/Vcs/PerforceDriver.php

@@ -13,6 +13,7 @@
 namespace Composer\Repository\Vcs;
 
 use Composer\Config;
+use Composer\Cache;
 use Composer\IO\IOInterface;
 use Composer\Util\ProcessExecutor;
 use Composer\Util\Perforce;
@@ -54,6 +55,10 @@ class PerforceDriver extends VcsDriver
             return;
         }
 
+        if (!Cache::isUsable($this->config->get('cache-vcs-dir'))) {
+            throw new \RuntimeException('PerforceDriver requires a usable cache directory, and it looks like you set it to be disabled');
+        }
+
         $repoDir = $this->config->get('cache-vcs-dir') . '/' . $this->depot;
         $this->perforce = Perforce::create($repoConfig, $this->getUrl(), $repoDir, $this->process, $this->io);
     }