소스 검색

Merge remote-tracking branch 'hjanuschka/gitlab_paging'

Jordi Boggiano 7 년 전
부모
커밋
086b750b76
2개의 변경된 파일84개의 추가작업 그리고 8개의 파일을 삭제
  1. 26 8
      src/Composer/Repository/Vcs/GitLabDriver.php
  2. 58 0
      tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php

+ 26 - 8
src/Composer/Repository/Vcs/GitLabDriver.php

@@ -280,17 +280,20 @@ class GitLabDriver extends VcsDriver
     {
         $resource = $this->getApiUrl().'/repository/'.$type;
 
-        $data = JsonFile::parseJson($this->getContents($resource), $resource);
+        do {
+            $data = JsonFile::parseJson($this->getContents($resource), $resource);
 
-        $references = array();
+            $references = array();
 
-        foreach ($data as $datum) {
-            $references[$datum['name']] = $datum['commit']['id'];
+            foreach ($data as $datum) {
+                $references[$datum['name']] = $datum['commit']['id'];
 
-            // Keep the last commit date of a reference to avoid
-            // unnecessary API call when retrieving the composer file.
-            $this->commits[$datum['commit']['id']] = $datum['commit'];
-        }
+              // Keep the last commit date of a reference to avoid
+             // unnecessary API call when retrieving the composer file.
+              $this->commits[$datum['commit']['id']] = $datum['commit'];
+            }
+            $resource = $this->getNextPage();
+        } while ($resource);
 
         return $references;
     }
@@ -444,6 +447,21 @@ class GitLabDriver extends VcsDriver
         return true;
     }
 
+    protected function getNextPage()
+    {
+        $headers = $this->remoteFilesystem->getLastHeaders();
+        foreach ($headers as $header) {
+            if (substr($header, 0, 5) === 'Link:') {
+                $links = explode(',', substr($header, 5));
+                foreach ($links as $link) {
+                    if (preg_match('{<(.+?)>; *rel="next"}', $link, $match)) {
+                        return $match[1];
+                    }
+                }
+            }
+        }
+    }
+
     /**
      * @param  array       $configuredDomains
      * @param  string      $guessedDomain

+ 58 - 0
tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php

@@ -216,6 +216,9 @@ JSON;
             ->willReturn($tagData)
             ->shouldBeCalledTimes(1)
         ;
+        $this->remoteFilesystem->getLastHeaders()
+          ->willReturn(array());
+        
         $driver->setRemoteFilesystem($this->remoteFilesystem->reveal());
 
         $expected = array(
@@ -227,6 +230,58 @@ JSON;
         $this->assertEquals($expected, $driver->getTags(), 'Tags are cached');
     }
 
+    public function testGetPaginatedRefs() {
+        $driver = $this->testInitialize('https://gitlab.com/mygroup/myproject', 'https://gitlab.com/api/v4/projects/mygroup%2Fmyproject');
+
+        $apiUrl = 'https://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/branches';
+
+        // @link http://doc.gitlab.com/ce/api/repositories.html#list-project-repository-branches
+        $branchData = <<<JSON
+[
+    {
+       "name": "mymaster",
+        "commit": {
+            "id": "97eda36b5c1dd953a3792865c222d4e85e5f302e",
+            "committed_date": "2013-01-03T21:04:07.000+01:00"
+        }
+    },
+    {
+        "name": "staging",
+        "commit": {
+            "id": "502cffe49f136443f2059803f2e7192d1ac066cd",
+            "committed_date": "2013-03-09T16:35:23.000+01:00"
+        }
+    }
+]
+JSON;
+
+        $this->remoteFilesystem
+            ->getContents('gitlab.com', $apiUrl, false, array())
+            ->willReturn($branchData)
+            ->shouldBeCalledTimes(1)
+        ;
+
+         $this->remoteFilesystem
+            ->getContents('gitlab.com', "http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=2&per_page=20", false, array())
+            ->willReturn($branchData)
+            ->shouldBeCalledTimes(1)
+        ;
+
+        $this->remoteFilesystem->getLastHeaders()
+          ->willReturn(array('Link: <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=2&per_page=20>; rel="next", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=1&per_page=20>; rel="first", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=3&per_page=20>; rel="last"'), array('Link: <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=2&per_page=20>; rel="prev", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=1&per_page=20>; rel="first", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=3&per_page=20>; rel="last"'))
+          ->shouldBeCalledTimes(2);
+
+        $driver->setRemoteFilesystem($this->remoteFilesystem->reveal());
+
+        $expected = array(
+            'mymaster' => '97eda36b5c1dd953a3792865c222d4e85e5f302e',
+            'staging' => '502cffe49f136443f2059803f2e7192d1ac066cd',
+        );
+
+        $this->assertEquals($expected, $driver->getBranches());
+        $this->assertEquals($expected, $driver->getBranches(), 'Branches are cached');
+
+    }
     public function testGetBranches()
     {
         $driver = $this->testInitialize('https://gitlab.com/mygroup/myproject', 'https://gitlab.com/api/v4/projects/mygroup%2Fmyproject');
@@ -258,6 +313,9 @@ JSON;
             ->willReturn($branchData)
             ->shouldBeCalledTimes(1)
         ;
+        $this->remoteFilesystem->getLastHeaders()
+          ->willReturn(array());
+
         $driver->setRemoteFilesystem($this->remoteFilesystem->reveal());
 
         $expected = array(