Completed basic .gitignore support to updating package.xml files.
authorGunnar Wrobel <p@rdus.de>
Tue, 2 Nov 2010 19:32:03 +0000 (20:32 +0100)
committerGunnar Wrobel <p@rdus.de>
Tue, 2 Nov 2010 19:39:06 +0000 (20:39 +0100)
Do not expect the .gitignore format support to be perfect. I just did
some basic checks and hope that it works for most packages now. For
some package contents additional fine tuning may be needed but I think
we can do that once we encounter problems.

Just ensure that you still check your updated package.xml before
commiting it ;)

components/TODO
components/lib/Components/Helper/Root.php
components/lib/Components/Pear/Package/Contents/Factory.php
components/lib/Components/Pear/Package/Contents/Ignore.php
components/test/Components/Integration/Components/Module/PearPackageXmlTest.php
components/test/Components/StoryTestCase.php
components/test/Components/fixture/.gitignore
components/test/Components/fixture/simple/IGNORE.txt [new file with mode: 0644]
components/test/Components/fixture/simple/ignore/test1 [new file with mode: 0644]
components/test/Components/fixture/simple/ignore/test2 [new file with mode: 0644]

index d30304e..37a8e0f 100644 (file)
@@ -4,9 +4,6 @@
 
  - Document usage
 
- - Allow filtering (see http://github.com/horde/horde/commit/404e8d1ea7c0bf99373aec2ce7f2534a442149b3)
-   Potentially check with git if the file is relevant or not.
-
  - Allow channel dependency detection with external/local package
    dependencies.
 
index d6d9d22..7a90c91 100644 (file)
@@ -121,4 +121,14 @@ class Components_Helper_Root
     {
         return $this->_base;
     }
+
+    /**
+     * Return the root position of the repository.
+     *
+     * @return string The root path.
+     */
+    public function getRoot()
+    {
+        return $this->_root_path;
+    }
 }
\ No newline at end of file
index 0f23b78..655b8fc 100644 (file)
@@ -57,7 +57,7 @@ class Components_Pear_Package_Contents_Factory
             $package->_options['packagedirectory'],
             new Components_Pear_Package_Contents_Ignore(
                 $root->getGitIgnore(),
-                $root->getBase()
+                $root->getRoot()
             )
         );
     }
index 9bf48e1..3e73c88 100644 (file)
@@ -44,14 +44,21 @@ class Components_Pear_Package_Contents_Ignore
     private $_include = array();
 
     /**
+     * The root position of the repository.
+     *
+     * @var string
+     */
+    private $_root;
+
+    /**
      * Constructor.
      *
      * @param string $gitignore The gitignore information
-     * @param string $base      An optional base for the files that should be checked.
+     * @param string $root      The root position for the files that should be checked.
      */
-    public function __construct($gitignore, $base = '')
+    public function __construct($gitignore, $root)
     {
-        $this->_base = $base;
+        $this->_root = $root;
         $this->_prepare($gitignore);
     }
 
@@ -76,12 +83,9 @@ class Components_Pear_Package_Contents_Ignore
             return !$return;
         }
 
-        if ($this->_matches($this->_ignore, $this->_base . $path)
-            && !$this->_matches($this->_include, $this->_base . $path)) {
-            return $return;
-        }
-        if ($this->_matches($this->_ignore, $file)
-            && !$this->_matches($this->_include, $file)) {
+        $rooted_path = substr($path, strlen($this->_root));
+        if ($this->_matches($this->_ignore, $rooted_path)
+            && !$this->_matches($this->_include, $rooted_path)) {
             return $return;
         }
         return !$return;
@@ -90,7 +94,7 @@ class Components_Pear_Package_Contents_Ignore
     private function _matches($matches, $path)
     {
         foreach ($matches as $match) {
-            preg_match('/^' . strtoupper($match).'$/', strtoupper($path), $find);
+            preg_match('/' . $match.'/', $path, $find);
             if (count($find)) {
                 return true;
             }
@@ -109,11 +113,11 @@ class Components_Pear_Package_Contents_Ignore
     {
         foreach (split("\n", $gitignore) as $line) {
             $line = strtr($line, ' ', '');
-            if (empty($line) || strpos($line, '#') == 1) {
+            if (empty($line) || strpos($line, '#') === 0) {
                 continue;
             }
-            if (strpos($line, '!') == 1) {
-                $this->_include[] = $this->_getRegExpableSearchString($line);
+            if (strpos($line, '!') === 0) {
+                $this->_include[] = $this->_getRegExpableSearchString(substr($line, 1));
             } else {
                 $this->_ignore[] = $this->_getRegExpableSearchString($line);
             }
@@ -130,20 +134,21 @@ class Components_Pear_Package_Contents_Ignore
      */
     private function _getRegExpableSearchString($s)
     {
-        $y = '\/';
-        if (DIRECTORY_SEPARATOR == '\\') {
-            $y = '\\\\';
+        if ($s[0] == DIRECTORY_SEPARATOR) {
+            $pre = '^';
+        } else {
+            $pre = '.*';
         }
 
-        $s = str_replace('/', DIRECTORY_SEPARATOR, $s);
-        $x = strtr($s, array('?' => '.', '*' => '.*', '.' => '\\.', '\\' => '\\\\', '/' => '\\/',
-                             '[' => '\\[', ']' => '\\]', '-' => '\\-'));
+        $x = strtr($s, array('?' => '.', '*' => '[^\/]*', '.' => '\\.', '\\' => '\\\\',
+                             '/' => '\\/', '-' => '\\-'));
 
-        if (strpos($s, DIRECTORY_SEPARATOR) !== false &&
-              strrpos($s, DIRECTORY_SEPARATOR) === strlen($s) - 1) {
-            $x = "(?:.*$y$x?.*|$x.*)";
+        if (substr($s, strlen($s) - 1) == DIRECTORY_SEPARATOR) {
+            $post = '.*';
+        } else {
+            $post = '$';
         }
 
-        return $x;
+        return $pre . $x . $post;
     }
 }
\ No newline at end of file
index d69bbb7..8e334bb 100644 (file)
@@ -131,6 +131,18 @@ extends Components_StoryTestCase
             ->and('the new package.xml will install script files in a default location');
     }
 
+    /**
+     * @scenario
+     */
+    public function thePOptionHeedsTheGitIgnoreFile()
+    {
+        $this->given('the default Components setup')
+            ->when('calling the package with the packagexml option and a Horde component')
+            ->then('the new package.xml of the Horde component will not contain the file', 'IGNORE.txt')
+            ->and('the new package.xml of the Horde component will not contain the file', 'test1')
+            ->and('the new package.xml of the Horde component will contain the file', 'test2');
+    }
+
 
     /**
      * @todo Test (and fix) the reactions to three more scenarios:
index 6e0e369..21c7561 100644 (file)
@@ -358,6 +358,18 @@ extends PHPUnit_Extensions_Story_TestCase
                 $world['output']
             );
             break;
+        case 'the new package.xml of the Horde component will not contain the file':
+            $this->assertNotRegExp(
+                '#' . $arguments[0] . '#',
+                $world['output']
+            );
+            break;
+        case 'the new package.xml of the Horde component will contain the file':
+            $this->assertRegExp(
+                '#' . $arguments[0] . '#',
+                $world['output']
+            );
+            break;
         case 'a new package.xml will be created.':
             $this->assertTrue(
                 file_exists($this->_temp_dir . DIRECTORY_SEPARATOR . 'package.xml')
diff --git a/components/test/Components/fixture/simple/IGNORE.txt b/components/test/Components/fixture/simple/IGNORE.txt
new file mode 100644 (file)
index 0000000..34bf5a1
--- /dev/null
@@ -0,0 +1 @@
+IGNORE
diff --git a/components/test/Components/fixture/simple/ignore/test1 b/components/test/Components/fixture/simple/ignore/test1
new file mode 100644 (file)
index 0000000..62a6e3c
--- /dev/null
@@ -0,0 +1 @@
+T
diff --git a/components/test/Components/fixture/simple/ignore/test2 b/components/test/Components/fixture/simple/ignore/test2
new file mode 100644 (file)
index 0000000..62a6e3c
--- /dev/null
@@ -0,0 +1 @@
+T