From fefe329c28e5d81feabd928538613af952fc6642 Mon Sep 17 00:00:00 2001 From: Alexandre Bacco Date: Sun, 10 Mar 2013 20:33:22 +0100 Subject: [PATCH 1/4] Add a showContents() method to Contents API --- lib/Github/Api/Repository/Contents.php | 29 ++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/lib/Github/Api/Repository/Contents.php b/lib/Github/Api/Repository/Contents.php index 23ffed4bbc8..c700cf77f74 100644 --- a/lib/Github/Api/Repository/Contents.php +++ b/lib/Github/Api/Repository/Contents.php @@ -72,4 +72,33 @@ public function archive($username, $repository, $format, $reference = null) 'ref' => $reference )); } + + /** + * Get the contents of a file in a repository + * + * @param string $username the user who owns the repository + * @param string $repository the name of the repository + * @param string $path path to file + * @param string $reference reference to a branch or commit + * + * @return string content of file + */ + public function showContents($username, $repository, $path, $reference = null) + { + $file = $this->show($username, $repository, $path, $reference); + + if (!isset($file['type']) || 'file' !== $file['type']) { + throw new \Exception(sprintf('Path "%s" is not a file.', $path)); + } + + if (!isset($file['content'])) { + throw new \Exception(sprintf('Unable to access "content" for file "%s" (possible keys: "%s").', $path, implode(', ', array_keys($file)))); + } + + if (!isset($file['encoding']) || 'base64' !== $file['encoding']) { + throw new \Exception(sprintf('Encoding of file "%s" is not supported.', $path)); + } + + return base64_decode($file['content']); + } } From b02176f74ba0738a3aa2c2a77e386461a7391c04 Mon Sep 17 00:00:00 2001 From: Alexandre Bacco Date: Tue, 12 Mar 2013 10:51:55 +0100 Subject: [PATCH 2/4] Rename showContents() to download() --- lib/Github/Api/Repository/Contents.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Github/Api/Repository/Contents.php b/lib/Github/Api/Repository/Contents.php index c700cf77f74..b3c8ad9d213 100644 --- a/lib/Github/Api/Repository/Contents.php +++ b/lib/Github/Api/Repository/Contents.php @@ -83,7 +83,7 @@ public function archive($username, $repository, $format, $reference = null) * * @return string content of file */ - public function showContents($username, $repository, $path, $reference = null) + public function download($username, $repository, $path, $reference = null) { $file = $this->show($username, $repository, $path, $reference); From bae4bed77f4249d27d12bd49e6ef61d02f537550 Mon Sep 17 00:00:00 2001 From: Alexandre Bacco Date: Tue, 12 Mar 2013 10:53:10 +0100 Subject: [PATCH 3/4] Add test for Api\Respository\Contents:download --- .../Tests/Api/Repository/ContentsTest.php | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/test/Github/Tests/Api/Repository/ContentsTest.php b/test/Github/Tests/Api/Repository/ContentsTest.php index 5639a4e6ede..a37cf3f7a09 100644 --- a/test/Github/Tests/Api/Repository/ContentsTest.php +++ b/test/Github/Tests/Api/Repository/ContentsTest.php @@ -85,6 +85,29 @@ public function shouldFetchZipballArchive() $this->assertEquals($expectedValue, $api->archive('KnpLabs', 'php-github-api', 'zipball')); } + + /** + * @test + */ + public function shouldDownloadForGivenPath() + { + // The show() method return + $getValue = json_decode( + '{"sha":"5639a4e6ede372d7ea25b1064be4e2045c2a053d","size":2648,"name":"ContentsTest.php","path":"test\/Github\/Tests\/Api\/Repository\/ContentsTest.php","type":"file","url":"https:\/\/api.github.com\/repos\/KnpLabs\/php-github-api\/contents\/test\/Github\/Tests\/Api\/Repository\/ContentsTest.php","git_url":"https:\/\/api.github.com\/repos\/KnpLabs\/php-github-api\/git\/blobs\/5639a4e6ede372d7ea25b1064be4e2045c2a053d","html_url":"https:\/\/github.com\/KnpLabs\/php-github-api\/blob\/master\/test\/Github\/Tests\/Api\/Repository\/ContentsTest.php","_links":{"self":"https:\/\/api.github.com\/repos\/KnpLabs\/php-github-api\/contents\/test\/Github\/Tests\/Api\/Repository\/ContentsTest.php","git":"https:\/\/api.github.com\/repos\/KnpLabs\/php-github-api\/git\/blobs\/5639a4e6ede372d7ea25b1064be4e2045c2a053d","html":"https:\/\/github.com\/KnpLabs\/php-github-api\/blob\/master\/test\/Github\/Tests\/Api\/Repository\/ContentsTest.php"},"content":"PD9waHAKCm5hbWVzcGFjZSBHaXRodWJcVGVzdHNcQXBpXFJlcG9zaXRvcnk7\nCgp1c2UgR2l0aHViXFRlc3RzXEFwaVxUZXN0Q2FzZTsKCmNsYXNzIENvbnRl\nbnRzVGVzdCBleHRlbmRzIFRlc3RDYXNlCnsKICAgIC8qKgogICAgICogQHRl\nc3QKICAgICAqLwogICAgcHVibGljIGZ1bmN0aW9uIHNob3VsZFNob3dDb250\nZW50Rm9yR2l2ZW5QYXRoKCkKICAgIHsKICAgICAgICAkZXhwZWN0ZWRWYWx1\nZSA9ICc8P3BocCAvLy4uJzsKCiAgICAgICAgJGFwaSA9ICR0aGlzLT5nZXRB\ncGlNb2NrKCk7CiAgICAgICAgJGFwaS0+ZXhwZWN0cygkdGhpcy0+b25jZSgp\nKQogICAgICAgICAgICAtPm1ldGhvZCgnZ2V0JykKICAgICAgICAgICAgLT53\naXRoKCdyZXBvcy9LbnBMYWJzL3BocC1naXRodWItYXBpL2NvbnRlbnRzL3Rl\nc3QlMkZHaXRodWIlMkZUZXN0cyUyRkFwaSUyRlJlcG9zaXRvcnklMkZDb250\nZW50c1Rlc3QucGhwJywgYXJyYXkoJ3JlZicgPT4gbnVsbCkpCiAgICAgICAg\nICAgIC0+d2lsbCgkdGhpcy0+cmV0dXJuVmFsdWUoJGV4cGVjdGVkVmFsdWUp\nKTsKCiAgICAgICAgJHRoaXMtPmFzc2VydEVxdWFscygkZXhwZWN0ZWRWYWx1\nZSwgJGFwaS0+c2hvdygnS25wTGFicycsICdwaHAtZ2l0aHViLWFwaScsICd0\nZXN0L0dpdGh1Yi9UZXN0cy9BcGkvUmVwb3NpdG9yeS9Db250ZW50c1Rlc3Qu\ncGhwJykpOwogICAgfQoKICAgIC8qKgogICAgICogQHRlc3QKICAgICAqLwog\nICAgcHVibGljIGZ1bmN0aW9uIHNob3VsZFNob3dSZWFkbWUoKQogICAgewog\nICAgICAgICRleHBlY3RlZFZhbHVlID0gJ1JFQURNRS4uLic7CgogICAgICAg\nICRhcGkgPSAkdGhpcy0+Z2V0QXBpTW9jaygpOwogICAgICAgICRhcGktPmV4\ncGVjdHMoJHRoaXMtPm9uY2UoKSkKICAgICAgICAgICAgLT5tZXRob2QoJ2dl\ndCcpCiAgICAgICAgICAgIC0+d2l0aCgncmVwb3MvS25wTGFicy9waHAtZ2l0\naHViLWFwaS9yZWFkbWUnLCBhcnJheSgncmVmJyA9PiBudWxsKSkKICAgICAg\nICAgICAgLT53aWxsKCR0aGlzLT5yZXR1cm5WYWx1ZSgkZXhwZWN0ZWRWYWx1\nZSkpOwoKICAgICAgICAkdGhpcy0+YXNzZXJ0RXF1YWxzKCRleHBlY3RlZFZh\nbHVlLCAkYXBpLT5yZWFkbWUoJ0tucExhYnMnLCAncGhwLWdpdGh1Yi1hcGkn\nKSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAdGVzdAogICAgICovCiAgICBw\ndWJsaWMgZnVuY3Rpb24gc2hvdWxkRmV0Y2hUYXJiYWxsQXJjaGl2ZVdoZW5G\nb3JtYXROb3RSZWNvZ25pemVkKCkKICAgIHsKICAgICAgICAkZXhwZWN0ZWRW\nYWx1ZSA9ICd0YXInOwoKICAgICAgICAkYXBpID0gJHRoaXMtPmdldEFwaU1v\nY2soKTsKICAgICAgICAkYXBpLT5leHBlY3RzKCR0aGlzLT5vbmNlKCkpCiAg\nICAgICAgICAgIC0+bWV0aG9kKCdnZXQnKQogICAgICAgICAgICAtPndpdGgo\nJ3JlcG9zL0tucExhYnMvcGhwLWdpdGh1Yi1hcGkvdGFyYmFsbCcsIGFycmF5\nKCdyZWYnID0+IG51bGwpKQogICAgICAgICAgICAtPndpbGwoJHRoaXMtPnJl\ndHVyblZhbHVlKCRleHBlY3RlZFZhbHVlKSk7CgogICAgICAgICR0aGlzLT5h\nc3NlcnRFcXVhbHMoJGV4cGVjdGVkVmFsdWUsICRhcGktPmFyY2hpdmUoJ0tu\ncExhYnMnLCAncGhwLWdpdGh1Yi1hcGknLCAnc29tZUZvcm1hdCcpKTsKICAg\nIH0KCiAgICAvKioKICAgICAqIEB0ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBm\ndW5jdGlvbiBzaG91bGRGZXRjaFRhcmJhbGxBcmNoaXZlKCkKICAgIHsKICAg\nICAgICAkZXhwZWN0ZWRWYWx1ZSA9ICd0YXInOwoKICAgICAgICAkYXBpID0g\nJHRoaXMtPmdldEFwaU1vY2soKTsKICAgICAgICAkYXBpLT5leHBlY3RzKCR0\naGlzLT5vbmNlKCkpCiAgICAgICAgICAgIC0+bWV0aG9kKCdnZXQnKQogICAg\nICAgICAgICAtPndpdGgoJ3JlcG9zL0tucExhYnMvcGhwLWdpdGh1Yi1hcGkv\ndGFyYmFsbCcsIGFycmF5KCdyZWYnID0+IG51bGwpKQogICAgICAgICAgICAt\nPndpbGwoJHRoaXMtPnJldHVyblZhbHVlKCRleHBlY3RlZFZhbHVlKSk7Cgog\nICAgICAgICR0aGlzLT5hc3NlcnRFcXVhbHMoJGV4cGVjdGVkVmFsdWUsICRh\ncGktPmFyY2hpdmUoJ0tucExhYnMnLCAncGhwLWdpdGh1Yi1hcGknLCAndGFy\nYmFsbCcpKTsKICAgIH0KCiAgICAvKioKICAgICAqIEB0ZXN0CiAgICAgKi8K\nICAgIHB1YmxpYyBmdW5jdGlvbiBzaG91bGRGZXRjaFppcGJhbGxBcmNoaXZl\nKCkKICAgIHsKICAgICAgICAkZXhwZWN0ZWRWYWx1ZSA9ICd6aXAnOwoKICAg\nICAgICAkYXBpID0gJHRoaXMtPmdldEFwaU1vY2soKTsKICAgICAgICAkYXBp\nLT5leHBlY3RzKCR0aGlzLT5vbmNlKCkpCiAgICAgICAgICAgIC0+bWV0aG9k\nKCdnZXQnKQogICAgICAgICAgICAtPndpdGgoJ3JlcG9zL0tucExhYnMvcGhw\nLWdpdGh1Yi1hcGkvemlwYmFsbCcsIGFycmF5KCdyZWYnID0+IG51bGwpKQog\nICAgICAgICAgICAtPndpbGwoJHRoaXMtPnJldHVyblZhbHVlKCRleHBlY3Rl\nZFZhbHVlKSk7CgogICAgICAgICR0aGlzLT5hc3NlcnRFcXVhbHMoJGV4cGVj\ndGVkVmFsdWUsICRhcGktPmFyY2hpdmUoJ0tucExhYnMnLCAncGhwLWdpdGh1\nYi1hcGknLCAnemlwYmFsbCcpKTsKICAgIH0KCiAgICBwcm90ZWN0ZWQgZnVu\nY3Rpb24gZ2V0QXBpQ2xhc3MoKQogICAgewogICAgICAgIHJldHVybiAnR2l0\naHViXEFwaVxSZXBvc2l0b3J5XENvbnRlbnRzJzsKICAgIH0KfQo=\n","encoding":"base64"}', + true + ); + + // The download() method return + $expectedValue = base64_decode($getValue['content']); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('repos/KnpLabs/php-github-api/contents/test%2FGithub%2FTests%2FApi%2FRepository%2FContentsTest.php', array('ref' => null)) + ->will($this->returnValue($getValue)); + + $this->assertEquals($expectedValue, $api->download('KnpLabs', 'php-github-api', 'test/Github/Tests/Api/Repository/ContentsTest.php')); + } protected function getApiClass() { From bb961f0d259f445a30fc4dc8eaf28a285a427757 Mon Sep 17 00:00:00 2001 From: winzou Date: Thu, 14 Mar 2013 11:58:19 +0100 Subject: [PATCH 4/4] Improve after feedbacks --- lib/Github/Api/Repository/Contents.php | 19 +++++++++++++------ .../Repository/ContentsDownloadFixture.php | 6 ++++++ .../Tests/Api/Repository/ContentsTest.php | 5 +---- 3 files changed, 20 insertions(+), 10 deletions(-) create mode 100644 test/Github/Tests/Api/Repository/ContentsDownloadFixture.php diff --git a/lib/Github/Api/Repository/Contents.php b/lib/Github/Api/Repository/Contents.php index b3c8ad9d213..95d99469949 100644 --- a/lib/Github/Api/Repository/Contents.php +++ b/lib/Github/Api/Repository/Contents.php @@ -4,6 +4,8 @@ use Github\Api\AbstractApi; use Github\Exception\MissingArgumentException; +use Github\Exception\InvalidArgumentException; +use Github\Exception\ErrorException; /** * @link http://developer.github.com/v3/repos/contents/ @@ -81,24 +83,29 @@ public function archive($username, $repository, $format, $reference = null) * @param string $path path to file * @param string $reference reference to a branch or commit * - * @return string content of file + * @return string|null content of file, or null in case of base64_decode failure + * + * @throws InvalidArgumentException If $path is not a file or if its encoding is different from base64 + * @throws ErrorException If $path doesn't include a 'content' index */ public function download($username, $repository, $path, $reference = null) { $file = $this->show($username, $repository, $path, $reference); if (!isset($file['type']) || 'file' !== $file['type']) { - throw new \Exception(sprintf('Path "%s" is not a file.', $path)); + throw new InvalidArgumentException(sprintf('Path "%s" is not a file.', $path)); } if (!isset($file['content'])) { - throw new \Exception(sprintf('Unable to access "content" for file "%s" (possible keys: "%s").', $path, implode(', ', array_keys($file)))); + throw new ErrorException(sprintf('Unable to access "content" for file "%s" (possible keys: "%s").', $path, implode(', ', array_keys($file)))); } - if (!isset($file['encoding']) || 'base64' !== $file['encoding']) { - throw new \Exception(sprintf('Encoding of file "%s" is not supported.', $path)); + if (!isset($file['encoding'])) { + throw new InvalidArgumentException(sprintf('Can\t decode contents of file "%s" as no encoding is defined.', $path)); + } elseif ('base64' !== $file['encoding']) { + throw new InvalidArgumentException(sprintf('Encoding "%s" of file "%s" is not supported.', $file['encoding'], $path)); } - return base64_decode($file['content']); + return base64_decode($file['content']) ?: null; } } diff --git a/test/Github/Tests/Api/Repository/ContentsDownloadFixture.php b/test/Github/Tests/Api/Repository/ContentsDownloadFixture.php new file mode 100644 index 00000000000..07dece20576 --- /dev/null +++ b/test/Github/Tests/Api/Repository/ContentsDownloadFixture.php @@ -0,0 +1,6 @@ +