Browse Source

initial steps with new config value, implementation of discard changes for git and svn

Ricard Clau 12 years ago
parent
commit
48ac383599

+ 4 - 1
doc/04-schema.md

@@ -608,7 +608,7 @@ The following options are supported:
 * **cache-files-dir:** Defaults to `$cache-dir/files`. Stores the zip archives
   of packages.
 * **cache-repo-dir:** Defaults to `$cache-dir/repo`. Stores repository metadata
-  for the `composer` type and the VCS repos of type `svn`, `github` and `*bitbucket`.
+  for the `composer` type and the VCS repos of type `svn`, `github` and `bitbucket`.
 * **cache-vcs-dir:** Defaults to `$cache-dir/vcs`. Stores VCS clones for
   loading VCS repository metadata for the `git`/`hg` types and to speed up installs.
 * **cache-files-ttl:** Defaults to `15552000` (6 months). Composer caches all
@@ -622,6 +622,9 @@ The following options are supported:
 * **notify-on-install:** Defaults to `true`. Composer allows repositories to
   define a notification URL, so that they get notified whenever a package from
   that repository is installed. This option allows you to disable that behaviour.
+* **discard-changes:** Defaults to `false` and can be any of `true`, `false` or
+  `stash`. This option allows you to set the default style of handling dirty
+  updates, specially useful for non-interactive mode.
 
 Example:
 

+ 4 - 0
res/composer-schema.json

@@ -167,6 +167,10 @@
                 "cache-files-maxsize": {
                     "type": ["string", "integer"],
                     "description": "The cache max size for the files cache, defaults to \"300MiB\"."
+                },
+                "discard-changes": {
+                    "type": ["string"],
+                    "description": "The default style of handling dirty updates, defaults to \"false\" and can be any of \"true\", \"false\" or \"stash\"."
                 }
             }
         },

+ 4 - 0
src/Composer/Command/ConfigCommand.php

@@ -271,6 +271,10 @@ EOT
                 function ($val) { return preg_match('/^\s*([0-9.]+)\s*(?:([kmg])(?:i?b)?)?\s*$/i', $val) > 0; },
                 function ($val) { return $val; }
             ),
+            'discard-changes' => array(
+                function ($val) { return in_array($val, array('true', 'false', 'stash')); },
+                function ($val) { return $val; }
+            ),
         );
         $multiConfigValues = array(
             'github-protocols' => array(

+ 10 - 0
src/Composer/Config.php

@@ -33,6 +33,7 @@ class Config
         'cache-ttl' => 15552000, // 6 months
         'cache-files-ttl' => null, // fallback to cache-ttl
         'cache-files-maxsize' => '300MiB',
+        'discard-changes' => 'false',
     );
 
     public static $defaultRepositories = array(
@@ -174,6 +175,15 @@ class Config
             case 'home':
                 return rtrim($this->process($this->config[$key]), '/\\');
 
+            case 'discard-changes':
+                if (!in_array($this->config[$key], array('true', 'false', 'stash'))) {
+                    throw new \RuntimeException(
+                        "Invalid value of 'discard-changes' from your config: {$this->config[$key]}"
+                    );
+                }
+
+                return $this->config[$key];
+
             default:
                 if (!isset($this->config[$key])) {
                     return null;

+ 42 - 9
src/Composer/Downloader/GitDownloader.php

@@ -90,8 +90,23 @@ class GitDownloader extends VcsDownloader
      */
     protected function cleanChanges($path, $update)
     {
+        $discardChanges = $this->config->get('discard-changes');
         if (!$this->io->isInteractive()) {
-            return parent::cleanChanges($path, $update);
+            switch ($discardChanges) {
+                case 'true':
+                    return $this->discardChanges($path);
+
+                case 'stash':
+                    if (!$update) {
+                        return parent::cleanChanges($path, $update);
+                    } else {
+                        return $this->stashChanges($path);
+                    }
+
+                case 'false':
+                default:
+                    return parent::cleanChanges($path, $update);
+            }
         }
 
         if (!$changes = $this->getLocalChanges($path)) {
@@ -110,9 +125,7 @@ class GitDownloader extends VcsDownloader
         while (true) {
             switch ($this->io->ask('    <info>Discard changes [y,n,v,'.($update ? 's,' : '').'?]?</info> ', '?')) {
                 case 'y':
-                    if (0 !== $this->process->execute('git reset --hard', $output, $path)) {
-                        throw new \RuntimeException("Could not reset changes\n\n:".$this->process->getErrorOutput());
-                    }
+                    $this->discardChanges($path);
                     break 2;
 
                 case 's':
@@ -120,11 +133,7 @@ class GitDownloader extends VcsDownloader
                         goto help;
                     }
 
-                    if (0 !== $this->process->execute('git stash', $output, $path)) {
-                        throw new \RuntimeException("Could not stash changes\n\n:".$this->process->getErrorOutput());
-                    }
-
-                    $this->hasStashedChanges = true;
+                    $this->stashChanges($path);
                     break 2;
 
                 case 'n':
@@ -369,4 +378,28 @@ class GitDownloader extends VcsDownloader
 
         return $output;
     }
+
+    /**
+     * @param $path
+     * @throws \RuntimeException
+     */
+    protected function discardChanges($path)
+    {
+        if (0 !== $this->process->execute('git reset --hard', $output, $path)) {
+            throw new \RuntimeException("Could not reset changes\n\n:".$this->process->getErrorOutput());
+        }
+    }
+
+    /**
+     * @param $path
+     * @throws \RuntimeException
+     */
+    protected function stashChanges($path)
+    {
+        if (0 !== $this->process->execute('git stash', $output, $path)) {
+            throw new \RuntimeException("Could not stash changes\n\n:".$this->process->getErrorOutput());
+        }
+
+        $this->hasStashedChanges = true;
+    }
 }

+ 18 - 4
src/Composer/Downloader/SvnDownloader.php

@@ -88,8 +88,17 @@ class SvnDownloader extends VcsDownloader
      */
     protected function cleanChanges($path, $update)
     {
+        $discardChanges = $this->config->get('discard-changes');
         if (!$this->io->isInteractive()) {
-            return parent::cleanChanges($path, $update);
+            switch ($discardChanges) {
+                case 'true':
+                    return $this->discardChanges($path);
+
+                case 'false':
+                case 'stash':
+                default:
+                    return parent::cleanChanges($path, $update);
+            }
         }
 
         if (!$changes = $this->getLocalChanges($path)) {
@@ -108,9 +117,7 @@ class SvnDownloader extends VcsDownloader
         while (true) {
             switch ($this->io->ask('    <info>Discard changes [y,n,v,?]?</info> ', '?')) {
                 case 'y':
-                    if (0 !== $this->process->execute('svn revert -R .', $output, $path)) {
-                        throw new \RuntimeException("Could not reset changes\n\n:".$this->process->getErrorOutput());
-                    }
+                    $this->discardChanges($path);
                     break 2;
 
                 case 'n':
@@ -150,4 +157,11 @@ class SvnDownloader extends VcsDownloader
 
         return $output;
     }
+
+    protected function discardChanges($path)
+    {
+        if (0 !== $this->process->execute('svn revert -R .', $output, $path)) {
+            throw new \RuntimeException("Could not reset changes\n\n:".$this->process->getErrorOutput());
+        }
+    }
 }