From e26dcb2267b34df0b8c0ed0af029ec1a125b4616 Mon Sep 17 00:00:00 2001 From: Christian Daguerre Date: Fri, 6 Jan 2017 16:21:39 +0100 Subject: [PATCH 01/83] Added method to retrieve issues closed by a merge request --- lib/Gitlab/Api/MergeRequests.php | 427 ++++++++++---------- test/Gitlab/Tests/Api/MergeRequestsTest.php | 20 +- 2 files changed, 238 insertions(+), 209 deletions(-) diff --git a/lib/Gitlab/Api/MergeRequests.php b/lib/Gitlab/Api/MergeRequests.php index 91f24d7ad..4d4e7f66c 100644 --- a/lib/Gitlab/Api/MergeRequests.php +++ b/lib/Gitlab/Api/MergeRequests.php @@ -1,208 +1,219 @@ -get($this->getProjectPath($project_id, $object), array( - 'page' => $page, - 'per_page' => $per_page, - 'state' => $state, - 'order_by' => $order_by, - 'sort' => $sort - )); - } - - /** - * @param int $project_id - * @param int $page - * @param int $per_page - * @param string $order_by - * @param string $sort - * @return mixed - */ - public function all($project_id, $page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT) - { - return $this->getList($project_id, self::STATE_ALL, $page, $per_page, $order_by, $sort); - } - - /** - * @param int $project_id - * @param int $page - * @param int $per_page - * @param string $order_by - * @param string $sort - * @return mixed - */ - public function merged($project_id, $page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT) - { - return $this->getList($project_id, self::STATE_MERGED, $page, $per_page, $order_by, $sort); - } - - /** - * @param int $project_id - * @param int $page - * @param int $per_page - * @param string $order_by - * @param string $sort - * @return mixed - */ - public function opened($project_id, $page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT) - { - return $this->getList($project_id, self::STATE_OPENED, $page, $per_page, $order_by, $sort); - } - - /** - * @param int $project_id - * @param int $page - * @param int $per_page - * @param string $order_by - * @param string $sort - * @return mixed - */ - public function closed($project_id, $page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT) - { - return $this->getList($project_id, self::STATE_CLOSED, $page, $per_page, $order_by, $sort); - } - - /** - * @param int $project_id - * @param int $mr_id - * @return mixed - */ - public function show($project_id, $mr_id) - { - return $this->get($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id))); - } - - /** - * @param int $project_id - * @param string $source - * @param string $target - * @param string $title - * @param int $assignee - * @param int $target_project_id - * @param string $description - * @return mixed - */ - public function create($project_id, $source, $target, $title, $assignee = null, $target_project_id = null, $description = null) - { - return $this->post($this->getProjectPath($project_id, 'merge_requests'), array( - 'source_branch' => $source, - 'target_branch' => $target, - 'title' => $title, - 'assignee_id' => $assignee, - 'target_project_id' => $target_project_id, - 'description' => $description - )); - } - - /** - * @param int $project_id - * @param int $mr_id - * @param array $params - * @return mixed - */ - public function update($project_id, $mr_id, array $params) - { - return $this->put($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id)), $params); - } - - /** - * @param int $project_id - * @param int $mr_id - * @param string $message - * @return mixed - */ - public function merge($project_id, $mr_id, $message = null) - { - if (is_array($message)) { - $params = $message; - } else { - $params = array('merge_commit_message' => $message); - } - - return $this->put($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/merge'), $params); - } - - /** - * @param int $project_id - * @param int $mr_id - * @return mixed - */ - public function showNotes($project_id, $mr_id, $page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = 'desc') - { - return $this->getList($project_id, null, $page, $per_page, $order_by, $sort, 'merge_requests/'.$this->encodePath($mr_id).'/notes'); - } - - /** - * @param int $project_id - * @param int $mr_id - * @return mixed - */ - public function showComments($project_id, $mr_id) - { - return $this->get($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/comments')); - } - - /** - * @param int $project_id - * @param int $mr_id - * @param int $note - * @return mixed - */ - public function addComment($project_id, $mr_id, $note) - { - return $this->post($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/comments'), array( - 'note' => $note - )); - } - - /** - * @param int $project_id - * @param int $mr_id - * @return mixed - */ - public function changes($project_id, $mr_id) - { - return $this->get($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/changes')); - } - - /** - * @param $project_id - * @param $mr_iid - * @return mixed - */ - public function getByIid($project_id, $mr_iid) - { - return $this->get($this->getProjectPath($project_id, 'merge_requests'), array('iid' => $mr_iid)); - } - - /** - * @param int $project_id - * @param int $mr_id - * @return mixed - */ - public function commits($project_id, $mr_id) - { - return $this->get($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/commits')); - } -} +get($this->getProjectPath($project_id, $object), array( + 'page' => $page, + 'per_page' => $per_page, + 'state' => $state, + 'order_by' => $order_by, + 'sort' => $sort + )); + } + + /** + * @param int $project_id + * @param int $page + * @param int $per_page + * @param string $order_by + * @param string $sort + * @return mixed + */ + public function all($project_id, $page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT) + { + return $this->getList($project_id, self::STATE_ALL, $page, $per_page, $order_by, $sort); + } + + /** + * @param int $project_id + * @param int $page + * @param int $per_page + * @param string $order_by + * @param string $sort + * @return mixed + */ + public function merged($project_id, $page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT) + { + return $this->getList($project_id, self::STATE_MERGED, $page, $per_page, $order_by, $sort); + } + + /** + * @param int $project_id + * @param int $page + * @param int $per_page + * @param string $order_by + * @param string $sort + * @return mixed + */ + public function opened($project_id, $page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT) + { + return $this->getList($project_id, self::STATE_OPENED, $page, $per_page, $order_by, $sort); + } + + /** + * @param int $project_id + * @param int $page + * @param int $per_page + * @param string $order_by + * @param string $sort + * @return mixed + */ + public function closed($project_id, $page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT) + { + return $this->getList($project_id, self::STATE_CLOSED, $page, $per_page, $order_by, $sort); + } + + /** + * @param int $project_id + * @param int $mr_id + * @return mixed + */ + public function show($project_id, $mr_id) + { + return $this->get($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id))); + } + + /** + * @param int $project_id + * @param string $source + * @param string $target + * @param string $title + * @param int $assignee + * @param int $target_project_id + * @param string $description + * @return mixed + */ + public function create($project_id, $source, $target, $title, $assignee = null, $target_project_id = null, $description = null) + { + return $this->post($this->getProjectPath($project_id, 'merge_requests'), array( + 'source_branch' => $source, + 'target_branch' => $target, + 'title' => $title, + 'assignee_id' => $assignee, + 'target_project_id' => $target_project_id, + 'description' => $description + )); + } + + /** + * @param int $project_id + * @param int $mr_id + * @param array $params + * @return mixed + */ + public function update($project_id, $mr_id, array $params) + { + return $this->put($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id)), $params); + } + + /** + * @param int $project_id + * @param int $mr_id + * @param string $message + * @return mixed + */ + public function merge($project_id, $mr_id, $message = null) + { + if (is_array($message)) { + $params = $message; + } else { + $params = array('merge_commit_message' => $message); + } + + return $this->put($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/merge'), $params); + } + + /** + * @param int $project_id + * @param int $mr_id + * @return mixed + */ + public function showNotes($project_id, $mr_id, $page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = 'desc') + { + return $this->getList($project_id, null, $page, $per_page, $order_by, $sort, 'merge_requests/'.$this->encodePath($mr_id).'/notes'); + } + + /** + * @param int $project_id + * @param int $mr_id + * @return mixed + */ + public function showComments($project_id, $mr_id) + { + return $this->get($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/comments')); + } + + /** + * @param int $project_id + * @param int $mr_id + * @param int $note + * @return mixed + */ + public function addComment($project_id, $mr_id, $note) + { + return $this->post($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/comments'), array( + 'note' => $note + )); + } + + /** + * @param int $project_id + * @param int $mr_id + * @return mixed + */ + public function changes($project_id, $mr_id) + { + return $this->get($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/changes')); + } + + /** + * @param $project_id + * @param $mr_iid + * @return mixed + */ + public function getByIid($project_id, $mr_iid) + { + return $this->get($this->getProjectPath($project_id, 'merge_requests'), array('iid' => $mr_iid)); + } + + /** + * @param int $project_id + * @param int $mr_id + * @return mixed + */ + public function commits($project_id, $mr_id) + { + return $this->get($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/commits')); + } + + + /** + * @param int $project_id + * @param int $mr_id + * @return mixed + */ + public function closesIssues($project_id, $mr_id) + { + return $this->get($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/closes_issues')); + } +} diff --git a/test/Gitlab/Tests/Api/MergeRequestsTest.php b/test/Gitlab/Tests/Api/MergeRequestsTest.php index bd6e6eb2b..894f0bb68 100644 --- a/test/Gitlab/Tests/Api/MergeRequestsTest.php +++ b/test/Gitlab/Tests/Api/MergeRequestsTest.php @@ -49,7 +49,7 @@ public function shouldGetAllWithParams() $api = $this->getApiMock(array('getList')); $api->expects($this->once()) ->method('getList') - ->with(1, MergeRequests::STATE_ALL, 2, 5, 'title', 'desc') + ->with(1, MergeRequests::STATE_ALL, 2, 5, 'title', 'desc') ->will($this->returnValue($expectedArray)) ; @@ -336,6 +336,24 @@ public function shouldGetMergeRequestChanges() $this->assertEquals($expectedArray, $api->changes(1, 2)); } + + /** + * @test + */ + public function shouldGetIssuesClosedByMergeRequest() + { + $expectedArray = array('id' => 1, 'title' => 'A merge request'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/merge_request/2/closes_issues') + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->closesIssues(1, 2)); + } + /** * @test */ From 83cf330da4f2598e1e3a773bbf29760ff08d770b Mon Sep 17 00:00:00 2001 From: Christian Daguerre Date: Fri, 6 Jan 2017 18:30:51 +0100 Subject: [PATCH 02/83] Added issue boards api --- lib/Gitlab/Api/IssueBoards.php | 92 ++++++++++ lib/Gitlab/Client.php | 5 + test/Gitlab/Tests/Api/IssueBoardsTest.php | 194 ++++++++++++++++++++++ 3 files changed, 291 insertions(+) create mode 100644 lib/Gitlab/Api/IssueBoards.php create mode 100644 test/Gitlab/Tests/Api/IssueBoardsTest.php diff --git a/lib/Gitlab/Api/IssueBoards.php b/lib/Gitlab/Api/IssueBoards.php new file mode 100644 index 000000000..d00c5a369 --- /dev/null +++ b/lib/Gitlab/Api/IssueBoards.php @@ -0,0 +1,92 @@ +getProjectPath($project_id, 'boards'); + + $params = array_merge(array( + 'page' => $page, + 'per_page' => $per_page + ), $params); + + return $this->get($path, $params); + } + + /** + * @param int $project_id + * @param int $board_id + * @return mixed + */ + public function allLists($project_id, $board_id) + { + return $this->get($this->getProjectPath($project_id, 'boards/'.$this->encodePath($board_id).'/lists')); + } + + + /** + * @param int $project_id + * @param int $board_id + * @param int $list_id + * @return mixed + */ + public function showList($project_id, $board_id, $list_id) + { + return $this->get($this->getProjectPath($project_id, 'boards/'.$this->encodePath($board_id).'/lists'.$this->encodePath($list_id))); + } + + /** + * @param int $project_id + * @param int $board_id + * @param int $label_id + * @return mixed + */ + public function createList($project_id, $board_id, $label_id) + { + $params = array( + 'id' => $project_id, + 'board_id' => $board_id, + 'label_id' => $label_id + ); + + return $this->get($this->getProjectPath($project_id, 'boards/'.$this->encodePath($board_id).'/lists'), $params); + } + + /** + * @param int $project_id + * @param int $board_id + * @param int $label_id + * @param int $position + * @return mixed + */ + public function updateList($project_id, $board_id, $label_id, $position) + { + $params = array( + 'id' => $project_id, + 'board_id' => $board_id, + 'label_id' => $label_id, + 'position' => $position + ); + + return $this->put($this->getProjectPath($project_id, 'boards/'.$this->encodePath($board_id).'/lists/'.$this->encodePath($list_id)), $params); + } + + /** + * @param int $project_id + * @param int $board_id + * @param int $label_id + * @return mixed + */ + public function deleteList($project_id, $board_id, $label_id) + { + return $this->delete($this->getProjectPath($project_id, 'boards/'.$this->encodePath($board_id).'/lists/'.$this->encodePath($list_id))); + } +} diff --git a/lib/Gitlab/Client.php b/lib/Gitlab/Client.php index 94674b96f..b54fbef1c 100644 --- a/lib/Gitlab/Client.php +++ b/lib/Gitlab/Client.php @@ -113,6 +113,11 @@ public function api($name) $api = new Api\Issues($this); break; + case 'board': + case 'issue_boards': + $api = new Api\IssueBoards($this); + break; + case 'mr': case 'merge_requests': $api = new Api\MergeRequests($this); diff --git a/test/Gitlab/Tests/Api/IssueBoardsTest.php b/test/Gitlab/Tests/Api/IssueBoardsTest.php new file mode 100644 index 000000000..1bd42832a --- /dev/null +++ b/test/Gitlab/Tests/Api/IssueBoardsTest.php @@ -0,0 +1,194 @@ + 1, 'title' => 'A board'), + array('id' => 2, 'title' => 'Another board'), + ); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('boards', array('page' => 1, 'per_page' => AbstractApi::PER_PAGE)) + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->all()); + } + // + // /** + // * @test + // */ + // public function shouldGetProjectIssuesWithPagination() + // { + // $expectedArray = array( + // array('id' => 1, 'title' => 'An issue'), + // array('id' => 2, 'title' => 'Another issue'), + // ); + // + // $api = $this->getApiMock(); + // $api->expects($this->once()) + // ->method('get') + // ->with('projects/1/issues', array('page' => 2, 'per_page' => 5)) + // ->will($this->returnValue($expectedArray)) + // ; + // + // $this->assertEquals($expectedArray, $api->all(1, 2, 5)); + // } + // + // /** + // * @test + // */ + // public function shouldGetProjectIssuesWithParams() + // { + // $expectedArray = array( + // array('id' => 1, 'title' => 'An issue'), + // array('id' => 2, 'title' => 'Another issue'), + // ); + // + // $api = $this->getApiMock(); + // $api->expects($this->once()) + // ->method('get') + // ->with('projects/1/issues', array('page' => 2, 'per_page' => 5, 'order_by' => 'created_at', 'sort' => 'desc', 'labels' => 'foo,bar', 'state' => 'open')) + // ->will($this->returnValue($expectedArray)) + // ; + // + // $this->assertEquals($expectedArray, $api->all(1, 2, 5, array('order_by' => 'created_at', 'sort' => 'desc', 'labels' => 'foo,bar', 'state' => 'open'))); + // } + // + // /** + // * @test + // */ + // public function shouldShowIssue() + // { + // $expectedArray = array('id' => 2, 'title' => 'Another issue'); + // + // $api = $this->getApiMock(); + // $api->expects($this->once()) + // ->method('get') + // ->with('projects/1/issues?iid=2') + // ->will($this->returnValue($expectedArray)) + // ; + // + // $this->assertEquals($expectedArray, $api->show(1, 2)); + // } + // + // /** + // * @test + // */ + // public function shouldCreateIssue() + // { + // $expectedArray = array('id' => 3, 'title' => 'A new issue'); + // + // $api = $this->getApiMock(); + // $api->expects($this->once()) + // ->method('post') + // ->with('projects/1/issues', array('title' => 'A new issue', 'labels' => 'foo,bar')) + // ->will($this->returnValue($expectedArray)) + // ; + // + // $this->assertEquals($expectedArray, $api->create(1, array('title' => 'A new issue', 'labels' => 'foo,bar'))); + // } + // + // /** + // * @test + // */ + // public function shouldUpdateIssue() + // { + // $expectedArray = array('id' => 2, 'title' => 'A renamed issue'); + // + // $api = $this->getApiMock(); + // $api->expects($this->once()) + // ->method('put') + // ->with('projects/1/issues/2', array('title' => 'A renamed issue', 'labels' => 'foo')) + // ->will($this->returnValue($expectedArray)) + // ; + // + // $this->assertEquals($expectedArray, $api->update(1, 2, array('title' => 'A renamed issue', 'labels' => 'foo'))); + // } + // + // /** + // * @test + // */ + // public function shouldGetIssueComments() + // { + // $expectedArray = array( + // array('id' => 1, 'body' => 'A comment'), + // array('id' => 2, 'body' => 'Another comment') + // ); + // + // $api = $this->getApiMock(); + // $api->expects($this->once()) + // ->method('get') + // ->with('projects/1/issues/2/notes') + // ->will($this->returnValue($expectedArray)) + // ; + // + // $this->assertEquals($expectedArray, $api->showComments(1, 2)); + // } + // + // /** + // * @test + // */ + // public function shouldGetIssueComment() + // { + // $expectedArray = array('id' => 3, 'body' => 'A new comment'); + // + // $api = $this->getApiMock(); + // $api->expects($this->once()) + // ->method('get') + // ->with('projects/1/issues/2/notes/3') + // ->will($this->returnValue($expectedArray)) + // ; + // + // $this->assertEquals($expectedArray, $api->showComment(1, 2, 3)); + // } + // + // /** + // * @test + // */ + // public function shouldCreateComment() + // { + // $expectedArray = array('id' => 3, 'body' => 'A new comment'); + // + // $api = $this->getApiMock(); + // $api->expects($this->exactly(2)) + // ->method('post') + // ->with('projects/1/issues/2/notes', array('body' => 'A new comment')) + // ->will($this->returnValue($expectedArray)) + // ; + // + // $this->assertEquals($expectedArray, $api->addComment(1, 2, array('body' => 'A new comment'))); + // $this->assertEquals($expectedArray, $api->addComment(1, 2, 'A new comment')); + // } + // + // /** + // * @test + // */ + // public function shouldUpdateComment() + // { + // $expectedArray = array('id' => 3, 'body' => 'An edited comment'); + // + // $api = $this->getApiMock(); + // $api->expects($this->once()) + // ->method('put') + // ->with('projects/1/issues/2/notes/3', array('body' => 'An edited comment')) + // ->will($this->returnValue($expectedArray)) + // ; + // + // $this->assertEquals($expectedArray, $api->updateComment(1, 2, 3, 'An edited comment')); + // } + + protected function getApiClass() + { + return 'Gitlab\Api\IssueBoards'; + } +} From 93bc1c38cc8b0421e07c4a558af14334bf346bc6 Mon Sep 17 00:00:00 2001 From: "Kidd, Don W. Mr" Date: Tue, 25 Apr 2017 08:56:50 -0400 Subject: [PATCH 03/83] Adding of path to list of properties in Node Model, also fixed Project Test so test now passes --- lib/Gitlab/Model/Node.php | 2 ++ test/Gitlab/Tests/Api/ProjectsTest.php | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/Gitlab/Model/Node.php b/lib/Gitlab/Model/Node.php index 8add42a07..bb9451687 100644 --- a/lib/Gitlab/Model/Node.php +++ b/lib/Gitlab/Model/Node.php @@ -21,9 +21,11 @@ class Node extends AbstractModel 'type', 'mode', 'id', + 'path', 'project' ); + /** * @param Client $client * @param Project $project diff --git a/test/Gitlab/Tests/Api/ProjectsTest.php b/test/Gitlab/Tests/Api/ProjectsTest.php index 66a120ded..47bb26432 100644 --- a/test/Gitlab/Tests/Api/ProjectsTest.php +++ b/test/Gitlab/Tests/Api/ProjectsTest.php @@ -65,11 +65,12 @@ public function shouldGetOwnedProjects() { $expectedArray = $this->getMultipleProjectsData(); - $api = $this->getMultipleProjectsRequestMock('projects/owned', $expectedArray, 3, 50); + $api = $this->getMultipleProjectsRequestMock('projects?owned=1', $expectedArray, 3, 50); $this->assertEquals($expectedArray, $api->owned(3, 50)); } + /** * @test */ From df94484315913eaabe2606d03616037e62436de7 Mon Sep 17 00:00:00 2001 From: "Kidd, Don W. Mr" Date: Fri, 28 Apr 2017 16:11:51 -0400 Subject: [PATCH 04/83] Add Projects to Group Model and added to API so projects can be obtained from API\Groups from within Model similar to how Members can be selected from with the Group model. --- lib/Gitlab/Api/Groups.php | 14 ++++++++++++++ lib/Gitlab/Model/Group.php | 11 +++++++++++ 2 files changed, 25 insertions(+) diff --git a/lib/Gitlab/Api/Groups.php b/lib/Gitlab/Api/Groups.php index 2696d4457..4ec574d64 100644 --- a/lib/Gitlab/Api/Groups.php +++ b/lib/Gitlab/Api/Groups.php @@ -133,4 +133,18 @@ public function removeMember($group_id, $user_id) { return $this->delete('groups/'.$this->encodePath($group_id).'/members/'.$this->encodePath($user_id)); } + + /** + * @param $id + * @param int $page + * @param int $per_page + * @return mixed + */ + public function projects($id, $page = 1, $per_page = self::PER_PAGE) + { + return $this->get('groups/'.$this->encodePath($id).'/projects', array( + 'page' => $page, + 'per_page' => $per_page + )); + } } diff --git a/lib/Gitlab/Model/Group.php b/lib/Gitlab/Model/Group.php index 614d50ffb..38891d6c1 100644 --- a/lib/Gitlab/Model/Group.php +++ b/lib/Gitlab/Model/Group.php @@ -125,4 +125,15 @@ public function removeMember($user_id) return true; } + + /** + * @return Group + */ + public function projects() + { + + $data = $this->api('groups')->projects($this->id); + + return Group::fromArray($this->getClient(),$data); + } } From baaa2cd24f6ef5f7a2c8439421ab82ee7e9d2612 Mon Sep 17 00:00:00 2001 From: Gordon Franke Date: Thu, 1 Jun 2017 21:54:56 +0200 Subject: [PATCH 05/83] add license file --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..8791c72e0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Matt Humphrey + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From e6c0f4175c5b688462fcec70448ba37aa3e579c9 Mon Sep 17 00:00:00 2001 From: Gordon Franke Date: Mon, 5 Jun 2017 21:05:57 +0200 Subject: [PATCH 06/83] speedup travis build with containers --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index d6b864cc0..97190200d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,7 @@ language: php +sudo: false + php: - 5.3 - 5.4 From 10672a0a8cd7d3ca924818ff71903c9511fc421e Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Wed, 7 Jun 2017 10:06:58 +0200 Subject: [PATCH 07/83] fix composer.json line endings (dos2unix) --- composer.json | 70 +++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/composer.json b/composer.json index 3c29600a4..6d2832506 100644 --- a/composer.json +++ b/composer.json @@ -1,35 +1,35 @@ -{ - "name": "m4tthumphrey/php-gitlab-api", - "type": "library", - "description": "GitLab API client", - "homepage": "https://github.com/m4tthumphrey/php-gitlab-api", - "keywords": ["gitlab", "api"], - "license": "MIT", - "authors": [ - { - "name": "Matt Humphrey", - "homepage": "http://m4tt.io" - }, - { - "name": "KnpLabs Team", - "homepage": "http://knplabs.com" - }, - { - "name": "Thibault Duplessis", - "email": "thibault.duplessis@gmail.com", - "homepage": "http://ornicar.github.com" - } - ], - "require": { - "php": ">=5.3.2", - "ext-curl": "*", - "ext-xml": "*", - "kriswallsmith/buzz": ">=0.7" - }, - "require-dev": { - "phpunit/phpunit": "~4.5" - }, - "autoload": { - "psr-0": { "Gitlab\\": "lib/" } - } -} +{ + "name": "m4tthumphrey/php-gitlab-api", + "type": "library", + "description": "GitLab API client", + "homepage": "https://github.com/m4tthumphrey/php-gitlab-api", + "keywords": ["gitlab", "api"], + "license": "MIT", + "authors": [ + { + "name": "Matt Humphrey", + "homepage": "http://m4tt.io" + }, + { + "name": "KnpLabs Team", + "homepage": "http://knplabs.com" + }, + { + "name": "Thibault Duplessis", + "email": "thibault.duplessis@gmail.com", + "homepage": "http://ornicar.github.com" + } + ], + "require": { + "php": ">=5.3.2", + "ext-curl": "*", + "ext-xml": "*", + "kriswallsmith/buzz": ">=0.7" + }, + "require-dev": { + "phpunit/phpunit": "~4.5" + }, + "autoload": { + "psr-0": { "Gitlab\\": "lib/" } + } +} From 269797b1f80c41f3a5eda81c35f1cd2603df7200 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Wed, 7 Jun 2017 10:03:50 +0200 Subject: [PATCH 08/83] bump minimum PHP version to 5.6 --- .travis.yml | 3 --- composer.json | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index d6b864cc0..f5ac69f8c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,6 @@ language: php php: - - 5.3 - - 5.4 - - 5.5 - 5.6 - 7.0 diff --git a/composer.json b/composer.json index 6d2832506..5e9d3e649 100644 --- a/composer.json +++ b/composer.json @@ -21,9 +21,9 @@ } ], "require": { - "php": ">=5.3.2", - "ext-curl": "*", - "ext-xml": "*", + "php": "^5.6 || ^7.0", + "ext-curl": "*", + "ext-xml": "*", "kriswallsmith/buzz": ">=0.7" }, "require-dev": { From 683108a6b4f34e7a8a375711e8c4589fa93c1dfe Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Wed, 7 Jun 2017 10:04:16 +0200 Subject: [PATCH 09/83] add PHP 7.1 to travis-ci matrix --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index f5ac69f8c..6343ee738 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ language: php php: - 5.6 - 7.0 + - 7.1 before_script: - travis_retry composer self-update From 32f7a309e4bb0c7bce1fe57bc98b06182f913663 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Wed, 7 Jun 2017 10:30:15 +0200 Subject: [PATCH 10/83] replace psr-0 autoloading by psr-4 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5e9d3e649..aaaa1ff98 100644 --- a/composer.json +++ b/composer.json @@ -30,6 +30,6 @@ "phpunit/phpunit": "~4.5" }, "autoload": { - "psr-0": { "Gitlab\\": "lib/" } + "psr-4": { "Gitlab\\": "lib/Gitlab/" } } } From 07fb0b6667a4cdb221ac565c6f2b4cbd11756cee Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Wed, 7 Jun 2017 10:31:01 +0200 Subject: [PATCH 11/83] replace phpunit custom bootstrap by autoload-dev --- composer.json | 8 ++++++++ phpunit.xml.dist | 4 ++-- test/bootstrap.php | 18 ------------------ 3 files changed, 10 insertions(+), 20 deletions(-) delete mode 100644 test/bootstrap.php diff --git a/composer.json b/composer.json index aaaa1ff98..786bef04f 100644 --- a/composer.json +++ b/composer.json @@ -31,5 +31,13 @@ }, "autoload": { "psr-4": { "Gitlab\\": "lib/Gitlab/" } + }, + "autoload-dev": { + "psr-4": { "Gitlab\\Tests\\": "test/Gitlab/Tests/" } + }, + "extra": { + "branch-alias": { + "dev-master": "9.0.x-dev" + } } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index e01386f15..7351de836 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -9,7 +9,7 @@ processIsolation="false" stopOnFailure="false" syntaxCheck="false" - bootstrap="test/bootstrap.php" + bootstrap="vendor/autoload.php" > @@ -22,4 +22,4 @@ ./lib/Gitlab/ - \ No newline at end of file + diff --git a/test/bootstrap.php b/test/bootstrap.php deleted file mode 100644 index 83bc8b088..000000000 --- a/test/bootstrap.php +++ /dev/null @@ -1,18 +0,0 @@ -add('Gitlab\Tests', __DIR__); - -return $loader; \ No newline at end of file From e49bc7313ae53e26501993353dcc1d404ae26b01 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Fri, 2 Jun 2017 17:26:20 +0200 Subject: [PATCH 12/83] replace buzz by httplug --- README.md | 31 +-- UPGRADE.md | 14 ++ composer.json | 11 +- doc/customize.md | 28 +++ lib/Gitlab/Api/AbstractApi.php | 99 +++++++- lib/Gitlab/Client.php | 188 ++++++-------- lib/Gitlab/HttpClient/Builder.php | 117 +++++++++ lib/Gitlab/HttpClient/HttpClient.php | 231 ------------------ lib/Gitlab/HttpClient/HttpClientInterface.php | 98 -------- .../HttpClient/Listener/AuthListener.php | 95 ------- .../HttpClient/Listener/ErrorListener.php | 97 -------- .../Listener/PaginationListener.php | 38 --- lib/Gitlab/HttpClient/Message/FormRequest.php | 8 - lib/Gitlab/HttpClient/Message/Request.php | 8 - lib/Gitlab/HttpClient/Message/Response.php | 48 ---- .../HttpClient/Message/ResponseMediator.php | 73 ++++++ lib/Gitlab/HttpClient/Plugin/ApiVersion.php | 29 +++ .../HttpClient/Plugin/Authentication.php | 86 +++++++ .../Plugin/GitlabExceptionThrower.php | 86 +++++++ lib/Gitlab/HttpClient/Plugin/History.php | 44 ++++ lib/Gitlab/ResultPager.php | 27 +- test/Gitlab/Tests/Api/AbstractApiTest.php | 177 -------------- test/Gitlab/Tests/Api/ApiTestCase.php | 23 -- test/Gitlab/Tests/Api/DeployKeysTest.php | 2 +- test/Gitlab/Tests/Api/GroupsTest.php | 2 +- test/Gitlab/Tests/Api/IssuesTest.php | 2 +- test/Gitlab/Tests/Api/KeysTest.php | 4 +- test/Gitlab/Tests/Api/MergeRequestsTest.php | 2 +- test/Gitlab/Tests/Api/MilestonesTest.php | 2 +- .../Tests/Api/ProjectNamespacesTest.php | 2 +- test/Gitlab/Tests/Api/ProjectsTest.php | 2 +- test/Gitlab/Tests/Api/RepositoriesTest.php | 2 +- test/Gitlab/Tests/Api/SnippetsTest.php | 2 +- test/Gitlab/Tests/Api/SystemHooksTest.php | 2 +- test/Gitlab/Tests/Api/TagsTest.php | 4 +- test/Gitlab/Tests/Api/TestCase.php | 37 ++- test/Gitlab/Tests/Api/UsersTest.php | 2 +- test/Gitlab/Tests/HttpClient/BuilderTest.php | 54 ++++ .../Message/ResponseMediatorTest.php | 77 ++++++ .../HttpClient/Plugin/ApiVersionTest.php | 67 +++++ test/Gitlab/Tests/ResultPagerTest.php | 113 +++++++++ 41 files changed, 1012 insertions(+), 1022 deletions(-) create mode 100644 UPGRADE.md create mode 100644 doc/customize.md create mode 100644 lib/Gitlab/HttpClient/Builder.php delete mode 100644 lib/Gitlab/HttpClient/HttpClient.php delete mode 100644 lib/Gitlab/HttpClient/HttpClientInterface.php delete mode 100644 lib/Gitlab/HttpClient/Listener/AuthListener.php delete mode 100644 lib/Gitlab/HttpClient/Listener/ErrorListener.php delete mode 100644 lib/Gitlab/HttpClient/Listener/PaginationListener.php delete mode 100644 lib/Gitlab/HttpClient/Message/FormRequest.php delete mode 100644 lib/Gitlab/HttpClient/Message/Request.php delete mode 100644 lib/Gitlab/HttpClient/Message/Response.php create mode 100644 lib/Gitlab/HttpClient/Message/ResponseMediator.php create mode 100644 lib/Gitlab/HttpClient/Plugin/ApiVersion.php create mode 100644 lib/Gitlab/HttpClient/Plugin/Authentication.php create mode 100644 lib/Gitlab/HttpClient/Plugin/GitlabExceptionThrower.php create mode 100644 lib/Gitlab/HttpClient/Plugin/History.php delete mode 100644 test/Gitlab/Tests/Api/AbstractApiTest.php delete mode 100644 test/Gitlab/Tests/Api/ApiTestCase.php create mode 100644 test/Gitlab/Tests/HttpClient/BuilderTest.php create mode 100644 test/Gitlab/Tests/HttpClient/Message/ResponseMediatorTest.php create mode 100644 test/Gitlab/Tests/HttpClient/Plugin/ApiVersionTest.php create mode 100644 test/Gitlab/Tests/ResultPagerTest.php diff --git a/README.md b/README.md index b8cbdb352..a209994c5 100644 --- a/README.md +++ b/README.md @@ -7,25 +7,16 @@ Based on [php-github-api](https://github.com/m4tthumphrey/php-github-api) and co Installation ------------ -1. Install Composer - ```bash - $ curl -sS https://getcomposer.org/installer | php - $ sudo mv composer.phar /usr/local/bin/composer - ``` +Via [composer](https://getcomposer.org) -2. Add the following to your require block in composer.json config. - - > Note: be careful when using the `dev-master` tag as this may have unexpected results depending on your version of - Gitlab. See the Versioning section below for more information. - - `php composer.phar require m4tthumphrey/php-gitlab-api:dev-master` +```bash +composer require m4tthumphrey/php-gitlab-api php-http/guzzle6-adapter +``` -3. Include Composer's autoloader: +Why `php-http/guzzle6-adapter`? We are decoupled from any HTTP messaging client with help by [HTTPlug](http://httplug.io). - ```php - require_once dirname(__DIR__).'/vendor/autoload.php'; - ``` +You can visit [HTTPlug for library users](http://docs.php-http.org/en/latest/httplug/users.html) to get more information about installing HTTPlug related packages. Versioning ---------- @@ -41,8 +32,9 @@ General API Usage ----------------- ```php -$client = new \Gitlab\Client('http://git.yourdomain.com/api/v3/'); // change here -$client->authenticate('your_gitlab_token_here', \Gitlab\Client::AUTH_URL_TOKEN); // change here +$client = \Gitlab\Client::create('http://git.yourdomain.com') + ->authenticate('your_gitlab_token_here', \Gitlab\Client::AUTH_URL_TOKEN) +; $project = $client->api('projects')->create('My Project', array( 'description' => 'This is a project', @@ -57,8 +49,9 @@ Model Usage You can also use the library in an object oriented manner: ```php -$client = new \Gitlab\Client('http://git.yourdomain.com/api/v3/'); // change here -$client->authenticate('your_gitlab_token_here', \Gitlab\Client::AUTH_URL_TOKEN); // change here +$client = \Gitlab\Client::create('http://git.yourdomain.com') + ->authenticate('your_gitlab_token_here', \Gitlab\Client::AUTH_URL_TOKEN) +; # Creating a new project $project = \Gitlab\Model\Project::create($client, 'My Project', array( diff --git a/UPGRADE.md b/UPGRADE.md new file mode 100644 index 000000000..b777e0e97 --- /dev/null +++ b/UPGRADE.md @@ -0,0 +1,14 @@ +# UPGRADE FROM 8.0 to 9.0 + +Since 9.0, lib no longer use buzz 0.7+, instead it has an HTTPlug abstraction layer. + +## `Gitlab\Client` changes + +* The constructor no longer allow to specify base url. Use `setUrl` or `Client::create` instead. +* The default url is set to `https://gitlab.com`. +* The `$options` constructor argument have been removed, the `getOption` and `setOption` methods have been removed. +See [documentation](doc/customize.md) to know how to customize the client timeout and how to use a custom user agent. +* The `setBaseUrl` and `getBaseUrl` methods have been removed. Use `setUrl` instead. +* The `clearHeaders` and `setHeaders` methods have been removed. See [documentation](doc/customize.md) to know how use custom headers. +* The `setHttpClient` method have been removed. Use a `Gitlab\HttpClient\Builder` instead. +* The `getHttpClient` method return type is changed to `Http\Client\Common\HttpMethodsClient`. diff --git a/composer.json b/composer.json index 786bef04f..ffb501948 100644 --- a/composer.json +++ b/composer.json @@ -22,11 +22,16 @@ ], "require": { "php": "^5.6 || ^7.0", - "ext-curl": "*", - "ext-xml": "*", - "kriswallsmith/buzz": ">=0.7" + "php-http/client-common": "^1.5", + "php-http/client-implementation": "^1.0", + "php-http/discovery": "^1.2", + "php-http/httplug": "^1.1", + "php-http/multipart-stream-builder": "^1.0" }, "require-dev": { + "guzzlehttp/psr7": "^1.2", + "php-http/guzzle6-adapter": "^1.0", + "php-http/mock-client": "^1.0", "phpunit/phpunit": "~4.5" }, "autoload": { diff --git a/doc/customize.md b/doc/customize.md new file mode 100644 index 000000000..6cb130858 --- /dev/null +++ b/doc/customize.md @@ -0,0 +1,28 @@ +## Customize `php-gitlab-api` + +### How to set custom headers (including `User-Agent`)? + +By providing a `Gitlab\HttpClient\Builder` to the `Gitlab\Client` constructor, you can customize the HTTP client. + +```php +$plugin = new Http\Client\Common\Plugin\HeaderSetPlugin([ + 'User-Agent' => 'Foobar', +]); + +$builder = new Gitlab\HttpClient\Builder(); +$builder->addPlugin($plugin); + +$client = new Gitlab\Client($builder); +``` +Read more about [HTTPlug plugins here](http://docs.php-http.org/en/latest/plugins/introduction.html#how-it-works). + +### How to customize the HTTP client timeout? +As timeout configuration is not compatible with HTTP client abstraction, you have to create the `Gitlab\Client` with +an explicit HTTP client implementation. + +```php +$httpClient = Http\Adapter\Guzzle6::createWithConfig([ + 'timeout' => 1.0 +]); +$client = Gitlab\Client::createWithHttpClient($httpClient); +``` diff --git a/lib/Gitlab/Api/AbstractApi.php b/lib/Gitlab/Api/AbstractApi.php index d6e3ab723..e08996973 100644 --- a/lib/Gitlab/Api/AbstractApi.php +++ b/lib/Gitlab/Api/AbstractApi.php @@ -1,6 +1,10 @@ client = $client; + $this->streamFactory = $streamFactory ?: StreamFactoryDiscovery::find(); } /** @@ -48,9 +59,11 @@ public function configure() */ protected function get($path, array $parameters = array(), $requestHeaders = array()) { - $response = $this->client->getHttpClient()->get($path, $parameters, $requestHeaders); + $path = $this->preparePath($path, $parameters); - return $response->getContent(); + $response = $this->client->getHttpClient()->get($path, $requestHeaders); + + return ResponseMediator::getContent($response); } /** @@ -62,9 +75,35 @@ protected function get($path, array $parameters = array(), $requestHeaders = arr */ protected function post($path, array $parameters = array(), $requestHeaders = array(), array $files = array()) { - $response = $this->client->getHttpClient()->post($path, $parameters, $requestHeaders, $files); - - return $response->getContent(); + $path = $this->preparePath($path); + + $body = null; + if (empty($files) && !empty($parameters)) { + $body = $this->streamFactory->createStream(http_build_query($parameters)); + $requestHeaders['Content-Type'] = 'application/x-www-form-urlencoded'; + } elseif (!empty($files)) { + $builder = new MultipartStreamBuilder($this->streamFactory); + + foreach ($parameters as $name => $value) { + $builder->addResource($name, $value); + } + + foreach ($files as $name => $file) { + $builder->addResource($name, fopen($file, 'r'), [ + 'headers' => [ + 'Content-Type' => $this->guessContentType($file), + ], + 'filename' => basename($file), + ]); + } + + $body = $builder->build(); + $requestHeaders['Content-Type'] = 'multipart/form-data; boundary='.$builder->getBoundary(); + } + + $response = $this->client->getHttpClient()->post($path, $requestHeaders, $body); + + return ResponseMediator::getContent($response); } /** @@ -75,9 +114,13 @@ protected function post($path, array $parameters = array(), $requestHeaders = ar */ protected function patch($path, array $parameters = array(), $requestHeaders = array()) { - $response = $this->client->getHttpClient()->patch($path, $parameters, $requestHeaders); + $path = $this->preparePath($path); + + $body = empty($parameters) ? null : $this->streamFactory->createStream(http_build_query($parameters)); - return $response->getContent(); + $response = $this->client->getHttpClient()->patch($path, $requestHeaders, $body); + + return ResponseMediator::getContent($response); } /** @@ -88,9 +131,13 @@ protected function patch($path, array $parameters = array(), $requestHeaders = a */ protected function put($path, array $parameters = array(), $requestHeaders = array()) { - $response = $this->client->getHttpClient()->put($path, $parameters, $requestHeaders); + $path = $this->preparePath($path); + + $body = empty($parameters) ? null : $this->streamFactory->createStream(http_build_query($parameters)); + + $response = $this->client->getHttpClient()->put($path, $requestHeaders, $body); - return $response->getContent(); + return ResponseMediator::getContent($response); } /** @@ -101,9 +148,13 @@ protected function put($path, array $parameters = array(), $requestHeaders = arr */ protected function delete($path, array $parameters = array(), $requestHeaders = array()) { - $response = $this->client->getHttpClient()->delete($path, $parameters, $requestHeaders); + $path = $this->preparePath($path); - return $response->getContent(); + $body = empty($parameters) ? null : $this->streamFactory->createStream(http_build_query($parameters)); + + $response = $this->client->getHttpClient()->delete($path, $requestHeaders, $body); + + return ResponseMediator::getContent($response); } /** @@ -126,4 +177,28 @@ protected function encodePath($path) return str_replace('.', '%2E', $path); } + + private function preparePath($path, array $parameters = []) + { + if (count($parameters) > 0) { + $path .= '?'.http_build_query($parameters); + } + + return $path; + } + + /** + * @param $file + * + * @return string + */ + private function guessContentType($file) + { + if (!class_exists(\finfo::class, false)) { + return 'application/octet-stream'; + } + $finfo = new \finfo(FILEINFO_MIME_TYPE); + + return $finfo->file($file); + } } diff --git a/lib/Gitlab/Client.php b/lib/Gitlab/Client.php index 5f0fd3950..b2cefa372 100644 --- a/lib/Gitlab/Client.php +++ b/lib/Gitlab/Client.php @@ -1,14 +1,18 @@ 'php-gitlab-api (http://github.com/m4tthumphrey/php-gitlab-api)', - 'timeout' => 60 - ); + private $responseHistory; - private $baseUrl; + /** + * @var Builder + */ + private $httpClientBuilder; /** - * The Buzz instance used to communicate with Gitlab + * Instantiate a new Gitlab client * - * @var HttpClient + * @param Builder $httpClientBuilder */ - private $httpClient; + public function __construct(Builder $httpClientBuilder = null) + { + $this->responseHistory = new History(); + $this->httpClientBuilder = $httpClientBuilder ?: new Builder(); + + $this->httpClientBuilder->addPlugin(new GitlabExceptionThrower()); + $this->httpClientBuilder->addPlugin(new HistoryPlugin($this->responseHistory)); + $this->httpClientBuilder->addPlugin(new ApiVersion()); + $this->httpClientBuilder->addPlugin(new HeaderDefaultsPlugin([ + 'User-Agent' => 'php-gitlab-api (http://github.com/m4tthumphrey/php-gitlab-api)', + ])); + + $this->setUrl('https://gitlab.com'); + } /** - * Instantiate a new Gitlab client + * Create a Gitlab\Client using an url. * - * @param string $baseUrl - * @param null|ClientInterface $httpClient Buzz client - * @param array $options + * @param string $url + * + * @return Client */ - public function __construct($baseUrl, ClientInterface $httpClient = null, array $options = array()) + public static function create($url) { - foreach ($options as $name => $value) { - $this->setOption($name, $value); - } + $client = new self(); + $client->setUrl($url); - $httpClient = $httpClient ?: new Curl(); - $httpClient->setTimeout($this->options['timeout']); - $httpClient->setVerifyPeer(false); + return $client; + } - $this->baseUrl = $baseUrl; - $this->httpClient = new HttpClient($this->baseUrl, $this->options, $httpClient); + /** + * Create a Gitlab\Client using an HttpClient. + * + * @param HttpClient $httpClient + * + * @return Client + */ + public static function createWithHttpClient(HttpClient $httpClient) + { + $builder = new Builder($httpClient); - /** - * a Pagination listener on Response - */ - $this->httpClient->addListener( - new PaginationListener() - ); + return new self($builder); } /** @@ -183,117 +201,47 @@ public function api($name) */ public function authenticate($token, $authMethod = self::AUTH_URL_TOKEN, $sudo = null) { - $this->httpClient->addListener( - new AuthListener( - $authMethod, - $token, - $sudo - ) - ); - - return $this; - } - - /** - * @return HttpClient - */ - public function getHttpClient() - { - return $this->httpClient; - } - - /** - * @param HttpClientInterface $httpClient - * @return $this - */ - public function setHttpClient(HttpClientInterface $httpClient) - { - $this->httpClient = $httpClient; + $this->httpClientBuilder->removePlugin(Authentication::class); + $this->httpClientBuilder->addPlugin(new Authentication($authMethod, $token, $sudo)); return $this; } /** * @param string $url - * @return $this - */ - public function setBaseUrl($url) - { - $this->baseUrl = $url; - - return $this; - } - - /** - * @return string - */ - public function getBaseUrl() - { - return $this->baseUrl; - } - - /** - * Clears used headers * * @return $this */ - public function clearHeaders() + public function setUrl($url) { - $this->httpClient->clearHeaders(); + $this->httpClientBuilder->removePlugin(AddHostPlugin::class); + $this->httpClientBuilder->addPlugin(new AddHostPlugin(UriFactoryDiscovery::find()->createUri($url))); return $this; } /** - * @param array $headers - * @return $this - */ - public function setHeaders(array $headers) - { - $this->httpClient->setHeaders($headers); - - return $this; - } - - /** - * @param string $name - * - * @return mixed - * - * @throws InvalidArgumentException + * @param string $api + * @return AbstractApi */ - public function getOption($name) + public function __get($api) { - if (!array_key_exists($name, $this->options)) { - throw new InvalidArgumentException(sprintf('Undefined option called: "%s"', $name)); - } - - return $this->options[$name]; + return $this->api($api); } /** - * @param string $name - * @param mixed $value - * @throws InvalidArgumentException - * @return $this + * @return HttpMethodsClient */ - public function setOption($name, $value) + public function getHttpClient() { - if (!array_key_exists($name, $this->options)) { - throw new InvalidArgumentException(sprintf('Undefined option called: "%s"', $name)); - } - - $this->options[$name] = $value; - - return $this; + return $this->httpClientBuilder->getHttpClient(); } /** - * @param string $api - * @return AbstractApi + * @return History */ - public function __get($api) + public function getResponseHistory() { - return $this->api($api); + return $this->responseHistory; } } diff --git a/lib/Gitlab/HttpClient/Builder.php b/lib/Gitlab/HttpClient/Builder.php new file mode 100644 index 000000000..133091111 --- /dev/null +++ b/lib/Gitlab/HttpClient/Builder.php @@ -0,0 +1,117 @@ + + */ +class Builder +{ + /** + * The object that sends HTTP messages. + * + * @var HttpClient + */ + private $httpClient; + + /** + * A HTTP client with all our plugins. + * + * @var PluginClient + */ + private $pluginClient; + + /** + * @var MessageFactory + */ + private $requestFactory; + + /** + * @var StreamFactory + */ + private $streamFactory; + + /** + * True if we should create a new Plugin client at next request. + * + * @var bool + */ + private $httpClientModified = true; + + /** + * @var Plugin[] + */ + private $plugins = []; + + /** + * @param HttpClient $httpClient + * @param RequestFactory $requestFactory + * @param StreamFactory $streamFactory + */ + public function __construct( + HttpClient $httpClient = null, + RequestFactory $requestFactory = null, + StreamFactory $streamFactory = null + ) { + $this->httpClient = $httpClient ?: HttpClientDiscovery::find(); + $this->requestFactory = $requestFactory ?: MessageFactoryDiscovery::find(); + $this->streamFactory = $streamFactory ?: StreamFactoryDiscovery::find(); + } + + /** + * @return HttpMethodsClient + */ + public function getHttpClient() + { + if ($this->httpClientModified) { + $this->httpClientModified = false; + + $this->pluginClient = new HttpMethodsClient( + new PluginClient($this->httpClient, $this->plugins), + $this->requestFactory + ); + } + + return $this->pluginClient; + } + + /** + * Add a new plugin to the end of the plugin chain. + * + * @param Plugin $plugin + */ + public function addPlugin(Plugin $plugin) + { + $this->plugins[] = $plugin; + $this->httpClientModified = true; + } + + /** + * Remove a plugin by its fully qualified class name (FQCN). + * + * @param string $fqcn + */ + public function removePlugin($fqcn) + { + foreach ($this->plugins as $idx => $plugin) { + if ($plugin instanceof $fqcn) { + unset($this->plugins[$idx]); + $this->httpClientModified = true; + } + } + } +} diff --git a/lib/Gitlab/HttpClient/HttpClient.php b/lib/Gitlab/HttpClient/HttpClient.php deleted file mode 100644 index 7a84bfb43..000000000 --- a/lib/Gitlab/HttpClient/HttpClient.php +++ /dev/null @@ -1,231 +0,0 @@ - - * @author Matt Humphrey - */ -class HttpClient implements HttpClientInterface -{ - /** - * @var array - */ - protected $options = array( - 'user_agent' => 'php-gitlab-api (http://github.com/m4tthumphrey/php-gitlab-api)', - 'timeout' => 10, - ); - - /** - * @var string - */ - protected $baseUrl; - - /** - * @var ListenerInterface[] - */ - protected $listeners = array(); - /** - * @var array - */ - protected $headers = array(); - - /** - * @var Response - */ - private $lastResponse; - - /** - * @var Request - */ - private $lastRequest; - - /** - * @param string $baseUrl - * @param array $options - * @param ClientInterface $client - */ - public function __construct($baseUrl, array $options, ClientInterface $client) - { - $this->baseUrl = $baseUrl; - $this->options = array_merge($this->options, $options); - $this->client = $client; - - $this->addListener(new ErrorListener($this->options)); - - $this->clearHeaders(); - } - - /** - * {@inheritDoc} - */ - public function setOption($name, $value) - { - $this->options[$name] = $value; - } - - /** - * {@inheritDoc} - */ - public function setHeaders(array $headers) - { - $this->headers = array_merge($this->headers, $headers); - } - - /** - * Clears used headers - */ - public function clearHeaders() - { - $this->headers = array(); - } - - /** - * @param ListenerInterface $listener - */ - public function addListener(ListenerInterface $listener) - { - $this->listeners[get_class($listener)] = $listener; - } - - /** - * {@inheritDoc} - */ - public function get($path, array $parameters = array(), array $headers = array()) - { - if (0 < count($parameters)) { - $path .= (false === strpos($path, '?') ? '?' : '&').http_build_query($parameters, '', '&'); - } - - return $this->request($path, array(), 'GET', $headers); - } - - /** - * {@inheritDoc} - */ - public function post($path, array $parameters = array(), array $headers = array(), array $files = array()) - { - return $this->request($path, $parameters, 'POST', $headers, $files); - } - - /** - * {@inheritDoc} - */ - public function patch($path, array $parameters = array(), array $headers = array()) - { - return $this->request($path, $parameters, 'PATCH', $headers); - } - - /** - * {@inheritDoc} - */ - public function delete($path, array $parameters = array(), array $headers = array()) - { - return $this->request($path, $parameters, 'DELETE', $headers); - } - - /** - * {@inheritDoc} - */ - public function put($path, array $parameters = array(), array $headers = array()) - { - return $this->request($path, $parameters, 'PUT', $headers); - } - - /** - * {@inheritDoc} - */ - public function request($path, array $parameters = array(), $httpMethod = 'GET', array $headers = array(), array $files = array()) - { - $path = trim($this->baseUrl.$path, '/'); - - $request = $this->createRequest($httpMethod, $path, $parameters, $headers, $files); - - $hasListeners = 0 < count($this->listeners); - if ($hasListeners) { - foreach ($this->listeners as $listener) { - $listener->preSend($request); - } - } - - $response = new Response(); - - try { - $this->client->send($request, $response); - } catch (\LogicException $e) { - throw new ErrorException($e->getMessage()); - } catch (\RuntimeException $e) { - throw new RuntimeException($e->getMessage()); - } - - $this->lastRequest = $request; - $this->lastResponse = $response; - - if ($hasListeners) { - foreach ($this->listeners as $listener) { - $listener->postSend($request, $response); - } - } - - return $response; - } - - /** - * @return Request - */ - public function getLastRequest() - { - return $this->lastRequest; - } - - /** - * @return Response - */ - public function getLastResponse() - { - return $this->lastResponse; - } - - /** - * @param string $httpMethod - * @param string $url - * @param array $parameters - * @param array $headers - * @param array $files - * - * @return FormRequest|Request - */ - private function createRequest($httpMethod, $url, array $parameters, array $headers, array $files) - { - if (empty($files)) { - $request = new Request($httpMethod); - $request->setContent(http_build_query($parameters)); - } else { - $request = new FormRequest($httpMethod); - foreach ($parameters as $name => $value) { - $request->setField($name, $value); - } - - foreach ($files as $name => $file) { - $upload = new FormUpload($file); - $request->setField($name, $upload); - } - } - $request->setHeaders($this->headers); - $request->fromUrl($url); - $request->addHeaders($headers); - - return $request; - } -} diff --git a/lib/Gitlab/HttpClient/HttpClientInterface.php b/lib/Gitlab/HttpClient/HttpClientInterface.php deleted file mode 100644 index 674987bec..000000000 --- a/lib/Gitlab/HttpClient/HttpClientInterface.php +++ /dev/null @@ -1,98 +0,0 @@ - - * @author Matt Humphrey - */ -interface HttpClientInterface -{ - /** - * Send a GET request - * - * @param string $path Request path - * @param array $parameters GET Parameters - * @param array $headers Reconfigure the request headers for this call only - * - * @return array Data - */ - public function get($path, array $parameters = array(), array $headers = array()); - - /** - * Send a POST request - * - * @param string $path Request path - * @param array $parameters POST Parameters - * @param array $headers Reconfigure the request headers for this call only - * @param array $files Files paths of files to upload - * - * @return array Data - */ - public function post($path, array $parameters = array(), array $headers = array(), array $files = array()); - - /** - * Send a PATCH request - * - * @param string $path Request path - * @param array $parameters PATCH Parameters - * @param array $headers Reconfigure the request headers for this call only - * - * @return array Data - */ - public function patch($path, array $parameters = array(), array $headers = array()); - - /** - * Send a PUT request - * - * @param string $path Request path - * @param array $parameters PUT Parameters - * @param array $headers Reconfigure the request headers for this call only - * - * @return array Data - */ - public function put($path, array $parameters = array(), array $headers = array()); - - /** - * Send a DELETE request - * - * @param string $path Request path - * @param array $parameters DELETE Parameters - * @param array $headers Reconfigure the request headers for this call only - * - * @return array Data - */ - public function delete($path, array $parameters = array(), array $headers = array()); - - /** - * Send a request to the server, receive a response, - * decode the response and returns an associative array - * - * @param string $path Request API path - * @param array $parameters Parameters - * @param string $httpMethod HTTP method to use - * @param array $headers Request headers - * - * @return array Data - */ - public function request($path, array $parameters = array(), $httpMethod = 'GET', array $headers = array()); - - /** - * Change an option value. - * - * @param string $name The option name - * @param mixed $value The value - * - * @throws InvalidArgumentException - */ - public function setOption($name, $value); - - /** - * Set HTTP headers - * - * @param array $headers - */ - public function setHeaders(array $headers); -} diff --git a/lib/Gitlab/HttpClient/Listener/AuthListener.php b/lib/Gitlab/HttpClient/Listener/AuthListener.php deleted file mode 100644 index 271641122..000000000 --- a/lib/Gitlab/HttpClient/Listener/AuthListener.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @author Matt Humphrey - */ -class AuthListener implements ListenerInterface -{ - /** - * @var string - */ - private $method; - - /** - * @var string - */ - private $token; - - /** - * @var string|null - */ - private $sudo; - - /** - * @param string $method - * @param string $token - * @param string|null $sudo - */ - public function __construct($method, $token, $sudo = null) - { - $this->method = $method; - $this->token = $token; - $this->sudo = $sudo; - } - - /** - * {@inheritDoc} - * - * @throws InvalidArgumentException - */ - public function preSend(RequestInterface $request) - { - // Skip by default - if (null === $this->method) { - return; - } - - switch ($this->method) { - case Client::AUTH_HTTP_TOKEN: - $request->addHeader('PRIVATE-TOKEN: '.$this->token); - if (!is_null($this->sudo)) { - $request->addHeader('SUDO: '.$this->sudo); - } - break; - - case Client::AUTH_URL_TOKEN: - $url = $request->getUrl(); - - $query = array( - 'private_token' => $this->token - ); - - if (!is_null($this->sudo)) { - $query['sudo'] = $this->sudo; - } - - $url .= (false === strpos($url, '?') ? '?' : '&').utf8_encode(http_build_query($query, '', '&')); - - $request->fromUrl(new Url($url)); - break; - - case Client::AUTH_OAUTH_TOKEN: - $request->addHeader('Authorization: Bearer '.$this->token); - if (!is_null($this->sudo)) { - $request->addHeader('SUDO: '.$this->sudo); - } - break; - } - } - - /** - * {@inheritDoc} - */ - public function postSend(RequestInterface $request, MessageInterface $response) - { - } -} diff --git a/lib/Gitlab/HttpClient/Listener/ErrorListener.php b/lib/Gitlab/HttpClient/Listener/ErrorListener.php deleted file mode 100644 index cb2acc68b..000000000 --- a/lib/Gitlab/HttpClient/Listener/ErrorListener.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @author Matt Humphrey - */ -class ErrorListener implements ListenerInterface -{ - /** - * @var array - */ - private $options; - - /** - * @param array $options - */ - public function __construct(array $options) - { - $this->options = $options; - } - - /** - * {@inheritDoc} - */ - public function preSend(RequestInterface $request) - { - } - - /** - * {@inheritDoc} - */ - public function postSend(RequestInterface $request, MessageInterface $response) - { - /** @var $response \Gitlab\HttpClient\Message\Response */ - if ($response->isClientError() || $response->isServerError()) { - $content = $response->getContent(); - if (is_array($content) && isset($content['message'])) { - if (400 == $response->getStatusCode()) { - $message = $this->parseMessage($content['message']); - - throw new ErrorException($message, 400); - } - } - - $errorMessage = null; - if (isset($content['error'])) { - $errorMessage = $content['error']; - if (is_array($content['error'])) { - $errorMessage = implode("\n", $content['error']); - } - } elseif (isset($content['message'])) { - $errorMessage = $this->parseMessage($content['message']); - } else { - $errorMessage = $content; - } - - throw new RuntimeException($errorMessage, $response->getStatusCode()); - } - } - - /** - * @param mixed $message - * @return string - */ - protected function parseMessage($message) - { - $string = $message; - - if (is_array($message)) { - $format = '"%s" %s'; - $errors = array(); - - foreach ($message as $field => $messages) { - if (is_array($messages)) { - $messages = array_unique($messages); - foreach ($messages as $error) { - $errors[] = sprintf($format, $field, $error); - } - } elseif (is_integer($field)) { - $errors[] = $messages; - } else { - $errors[] = sprintf($format, $field, $messages); - } - } - - $string = implode(', ', $errors); - } - - return $string; - } -} diff --git a/lib/Gitlab/HttpClient/Listener/PaginationListener.php b/lib/Gitlab/HttpClient/Listener/PaginationListener.php deleted file mode 100644 index 80ba39ea9..000000000 --- a/lib/Gitlab/HttpClient/Listener/PaginationListener.php +++ /dev/null @@ -1,38 +0,0 @@ -getHeader('Link'); - - if (empty($header)) { - return null; - } - - $pagination = array(); - foreach (explode(',', $header) as $link) { - preg_match('/<(.*)>; rel="(.*)"/i', trim($link, ','), $match); - - if (3 === count($match)) { - $pagination[$match[2]] = $match[1]; - } - } - - $response->setPagination($pagination); - } -} diff --git a/lib/Gitlab/HttpClient/Message/FormRequest.php b/lib/Gitlab/HttpClient/Message/FormRequest.php deleted file mode 100644 index ecd05e17d..000000000 --- a/lib/Gitlab/HttpClient/Message/FormRequest.php +++ /dev/null @@ -1,8 +0,0 @@ -pagination; - } - - /** - * @param array $pagination - */ - public function setPagination(array $pagination) - { - $this->pagination = $pagination; - } - - /** - * {@inheritDoc} - */ - public function getContent() - { - $response = parent::getContent(); - - if ($this->getHeader('Content-Type') === 'application/json') { - $content = json_decode($response, true); - - if (JSON_ERROR_NONE !== json_last_error()) { - return $response; - } - - return $content; - } - - return $response; - } -} diff --git a/lib/Gitlab/HttpClient/Message/ResponseMediator.php b/lib/Gitlab/HttpClient/Message/ResponseMediator.php new file mode 100644 index 000000000..16bd781f0 --- /dev/null +++ b/lib/Gitlab/HttpClient/Message/ResponseMediator.php @@ -0,0 +1,73 @@ +getBody()->__toString(); + if (strpos($response->getHeaderLine('Content-Type'), 'application/json') === 0) { + $content = json_decode($body, true); + if (JSON_ERROR_NONE === json_last_error()) { + return $content; + } + } + + return $body; + } + + /** + * Extract pagination URIs from Link header. + * + * @param ResponseInterface $response + * + * @return array|null + */ + public static function getPagination(ResponseInterface $response) + { + if (!$response->hasHeader('Link')) { + return null; + } + + $header = self::getHeader($response, 'Link'); + $pagination = array(); + foreach (explode(',', $header) as $link) { + preg_match('/<(.*)>; rel="(.*)"/i', trim($link, ','), $match); + + if (3 === count($match)) { + $pagination[$match[2]] = $match[1]; + } + } + + return $pagination; + } + + + /** + * Get the value for a single header. + * + * @param ResponseInterface $response + * @param string $name + * + * @return string|null + */ + private static function getHeader(ResponseInterface $response, $name) + { + $headers = $response->getHeader($name); + + return array_shift($headers); + } +} diff --git a/lib/Gitlab/HttpClient/Plugin/ApiVersion.php b/lib/Gitlab/HttpClient/Plugin/ApiVersion.php new file mode 100644 index 000000000..3e196ea78 --- /dev/null +++ b/lib/Gitlab/HttpClient/Plugin/ApiVersion.php @@ -0,0 +1,29 @@ + + */ +class ApiVersion implements Plugin +{ + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + $uri = $request->getUri(); + + if (substr($uri->getPath(), 0, 8) !== '/api/v3/') { + $request = $request->withUri($uri->withPath('/api/v3/'.$uri->getPath())); + } + + return $next($request); + } +} diff --git a/lib/Gitlab/HttpClient/Plugin/Authentication.php b/lib/Gitlab/HttpClient/Plugin/Authentication.php new file mode 100644 index 000000000..aac0acc4a --- /dev/null +++ b/lib/Gitlab/HttpClient/Plugin/Authentication.php @@ -0,0 +1,86 @@ + + * @author Fabien Bourigault + */ +class Authentication implements Plugin +{ + /** + * @var string + */ + private $method; + + /** + * @var string + */ + private $token; + + /** + * @var string|null + */ + private $sudo; + + /** + * @param string $method + * @param string $token + * @param string|null $sudo + */ + public function __construct($method, $token, $sudo = null) + { + $this->method = $method; + $this->token = $token; + $this->sudo = $sudo; + } + + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + switch ($this->method) { + case Client::AUTH_HTTP_TOKEN: + $request = $request->withHeader('PRIVATE-TOKEN', $this->token); + if (!is_null($this->sudo)) { + $request = $request->withHeader('SUDO', $this->sudo); + } + break; + + case Client::AUTH_URL_TOKEN: + $uri = $request->getUri(); + $query = $uri->getQuery(); + + $parameters = [ + 'private_token' => $this->token, + ]; + + if (!is_null($this->sudo)) { + $parameters['sudo'] = $this->sudo; + } + + $query .= empty($query) ? '' : '&'; + $query .= utf8_encode(http_build_query($parameters, '', '&')); + + $uri = $uri->withQuery($query); + $request = $request->withUri($uri); + break; + + case Client::AUTH_OAUTH_TOKEN: + $request = $request->withHeader('Authorization', 'Bearer '.$this->token); + if (!is_null($this->sudo)) { + $request = $request->withHeader('SUDO', $this->sudo); + } + break; + } + + return $next($request); + } +} diff --git a/lib/Gitlab/HttpClient/Plugin/GitlabExceptionThrower.php b/lib/Gitlab/HttpClient/Plugin/GitlabExceptionThrower.php new file mode 100644 index 000000000..bb61e3121 --- /dev/null +++ b/lib/Gitlab/HttpClient/Plugin/GitlabExceptionThrower.php @@ -0,0 +1,86 @@ + + * @author Fabien Bourigault + */ +class GitlabExceptionThrower implements Plugin +{ + /** + * {@inheritdoc} + */ + public function handleRequest(RequestInterface $request, callable $next, callable $first) + { + return $next($request)->then(function (ResponseInterface $response) { + if ($response->getStatusCode() >= 400 && $response->getStatusCode() < 600) { + $content = ResponseMediator::getContent($response); + if (is_array($content) && isset($content['message'])) { + if (400 == $response->getStatusCode()) { + $message = $this->parseMessage($content['message']); + + throw new ErrorException($message, 400); + } + } + + $errorMessage = null; + if (isset($content['error'])) { + $errorMessage = $content['error']; + if (is_array($content['error'])) { + $errorMessage = implode("\n", $content['error']); + } + } elseif (isset($content['message'])) { + $errorMessage = $this->parseMessage($content['message']); + } else { + $errorMessage = $content; + } + + throw new RuntimeException($errorMessage, $response->getStatusCode()); + } + + return $response; + }); + } + + /** + * @param mixed $message + * + * @return string + */ + private function parseMessage($message) + { + $string = $message; + + if (is_array($message)) { + $format = '"%s" %s'; + $errors = array(); + + foreach ($message as $field => $messages) { + if (is_array($messages)) { + $messages = array_unique($messages); + foreach ($messages as $error) { + $errors[] = sprintf($format, $field, $error); + } + } elseif (is_integer($field)) { + $errors[] = $messages; + } else { + $errors[] = sprintf($format, $field, $messages); + } + } + + $string = implode(', ', $errors); + } + + return $string; + } +} diff --git a/lib/Gitlab/HttpClient/Plugin/History.php b/lib/Gitlab/HttpClient/Plugin/History.php new file mode 100644 index 000000000..8412356fd --- /dev/null +++ b/lib/Gitlab/HttpClient/Plugin/History.php @@ -0,0 +1,44 @@ + + */ +class History implements Journal +{ + /** + * @var ResponseInterface + */ + private $lastResponse; + + /** + * @return ResponseInterface|null + */ + public function getLastResponse() + { + return $this->lastResponse; + } + + /** + * {@inheritdoc} + */ + public function addSuccess(RequestInterface $request, ResponseInterface $response) + { + $this->lastResponse = $response; + } + + /** + * {@inheritdoc} + */ + public function addFailure(RequestInterface $request, Exception $exception) + { + } +} diff --git a/lib/Gitlab/ResultPager.php b/lib/Gitlab/ResultPager.php index 3cfb44d13..b436305b1 100644 --- a/lib/Gitlab/ResultPager.php +++ b/lib/Gitlab/ResultPager.php @@ -1,6 +1,7 @@ hasNext()) { $result = array_merge($result, $this->fetchNext()); } @@ -105,7 +103,17 @@ public function fetchLast() */ protected function has($key) { - return !empty($this->client->getHttpClient()->getLastResponse()->getPagination()) && isset($this->client->getHttpClient()->getLastResponse()->getPagination()[$key]); + $lastResponse = $this->client->getResponseHistory()->getLastResponse(); + if ($lastResponse == null) { + return false; + } + + $pagination = ResponseMediator::getPagination($lastResponse); + if ($pagination == null) { + return false; + } + + return isset($pagination[$key]); } /** @@ -113,9 +121,12 @@ protected function has($key) */ protected function get($key) { - if ($this->has($key)) { - $result = $this->client->getHttpClient()->get(strtr($this->client->getHttpClient()->getLastResponse()->getPagination()[$key], array($this->client->getBaseUrl() => '')))->getContent(); - return $result; + if (!$this->has($key)) { + return []; } + + $pagination = ResponseMediator::getPagination($this->client->getResponseHistory()->getLastResponse()); + + return ResponseMediator::getContent($this->client->getHttpClient()->get($pagination[$key])); } } diff --git a/test/Gitlab/Tests/Api/AbstractApiTest.php b/test/Gitlab/Tests/Api/AbstractApiTest.php deleted file mode 100644 index aa1eeaea2..000000000 --- a/test/Gitlab/Tests/Api/AbstractApiTest.php +++ /dev/null @@ -1,177 +0,0 @@ -getResponse('value'); - - $httpClient = $this->getHttpMock(); - $httpClient - ->expects($this->any()) - ->method('get') - ->with('/path', array('param1' => 'param1value'), array('header1' => 'header1value')) - ->will($this->returnValue($response)); - - $client = $this->getClientMock(); - $client->setHttpClient($httpClient); - - $api = $this->getAbstractApiObject($client); - $this->assertEquals('value', $api->get('/path', array('param1' => 'param1value'), array('header1' => 'header1value'))); - } - - /** - * @test - */ - public function shouldPassPOSTRequestToClient() - { - $response = $this->getResponse('value'); - - $httpClient = $this->getHttpMock(); - $httpClient - ->expects($this->any()) - ->method('post') - ->with('/path', array('param1' => 'param1value'), array('header1' => 'header1value')) - ->will($this->returnValue($response)); - - $client = $this->getClientMock(); - $client->setHttpClient($httpClient); - - $api = $this->getAbstractApiObject($client); - $this->assertEquals('value', $api->post('/path', array('param1' => 'param1value'), array('header1' => 'header1value'))); - } - - /** - * @test - */ - public function shouldPassPUTRequestToClient() - { - $response = $this->getResponse('value'); - - $httpClient = $this->getHttpMock(); - $httpClient - ->expects($this->any()) - ->method('put') - ->with('/path', array('param1' => 'param1value'), array('header1' => 'header1value')) - ->will($this->returnValue($response)); - - $client = $this->getClientMock(); - $client->setHttpClient($httpClient); - - $api = $this->getAbstractApiObject($client); - $this->assertEquals('value', $api->put('/path', array('param1' => 'param1value'), array('header1' => 'header1value'))); - } - - /** - * @test - */ - public function shouldPassDELETERequestToClient() - { - $response = $this->getResponse('value'); - - $httpClient = $this->getHttpMock(); - $httpClient - ->expects($this->any()) - ->method('delete') - ->with('/path', array('param1' => 'param1value'), array('header1' => 'header1value')) - ->will($this->returnValue($response)); - - $client = $this->getClientMock(); - $client->setHttpClient($httpClient); - - $api = $this->getAbstractApiObject($client); - $this->assertEquals('value', $api->delete('/path', array('param1' => 'param1value'), array('header1' => 'header1value'))); - } - - /** - * @test - */ - public function shouldPassPATCHRequestToClient() - { - $response = $this->getResponse('value'); - - $httpClient = $this->getHttpMock(); - $httpClient - ->expects($this->any()) - ->method('patch') - ->with('/path', array('param1' => 'param1value'), array('header1' => 'header1value')) - ->will($this->returnValue($response)); - - $client = $this->getClientMock(); - $client->setHttpClient($httpClient); - - $api = $this->getAbstractApiObject($client); - $this->assertEquals('value', $api->patch('/path', array('param1' => 'param1value'), array('header1' => 'header1value'))); - } - - /** - * @param mixed $value - * @return Response - */ - protected function getResponse($value) - { - $response = new Response(); - $response->setContent($value); - - return $response; - } - - /** - * @param Client $client - * @return AbstractApiTestInstance - */ - protected function getAbstractApiObject(Client $client) - { - return new AbstractApiTestInstance($client); - } -} - -class AbstractApiTestInstance extends AbstractApi -{ - /** - * {@inheritDoc} - */ - public function get($path, array $parameters = array(), $requestHeaders = array()) - { - return parent::get($path, $parameters, $requestHeaders); - } - - /** - * {@inheritDoc} - */ - public function post($path, array $parameters = array(), $requestHeaders = array(), array $files = array()) - { - return parent::post($path, $parameters, $requestHeaders, $files); - } - - /** - * {@inheritDoc} - */ - public function patch($path, array $parameters = array(), $requestHeaders = array()) - { - return parent::patch($path, $parameters, $requestHeaders); - } - - /** - * {@inheritDoc} - */ - public function put($path, array $parameters = array(), $requestHeaders = array()) - { - return parent::put($path, $parameters, $requestHeaders); - } - - /** - * {@inheritDoc} - */ - public function delete($path, array $parameters = array(), $requestHeaders = array()) - { - return parent::delete($path, $parameters, $requestHeaders); - } -} diff --git a/test/Gitlab/Tests/Api/ApiTestCase.php b/test/Gitlab/Tests/Api/ApiTestCase.php deleted file mode 100644 index a695d97cb..000000000 --- a/test/Gitlab/Tests/Api/ApiTestCase.php +++ /dev/null @@ -1,23 +0,0 @@ -getClientMock(); - - $methods = array_merge(array('get', 'post', 'postRaw', 'patch', 'delete', 'put', 'head'), $methods); - - return $this->getMockBuilder($this->getApiClass()) - ->setMethods($methods) - ->setConstructorArgs(array($client)) - ->getMock() - ; - } -} diff --git a/test/Gitlab/Tests/Api/DeployKeysTest.php b/test/Gitlab/Tests/Api/DeployKeysTest.php index a17dd312c..9ea069487 100644 --- a/test/Gitlab/Tests/Api/DeployKeysTest.php +++ b/test/Gitlab/Tests/Api/DeployKeysTest.php @@ -1,6 +1,6 @@ getHttpMock()); - } + abstract protected function getApiClass(); - /** - * @return \PHPUnit_Framework_MockObject_MockObject|HttpClientInterface - */ - protected function getHttpMock() - { - return $this->getMock('Gitlab\HttpClient\HttpClient', array(), array(null, array(), $this->getHttpClientMock())); - } /** - * @return \PHPUnit_Framework_MockObject_MockObject|Curl + * @param array $methods + * + * @return \PHPUnit_Framework_MockObject_MockObject */ - protected function getHttpClientMock() + protected function getApiMock(array $methods = []) { - $httpClient = $this->getMock('Buzz\Client\Curl', array('send')); + $httpClient = $this->getMockBuilder(HttpClient::class) + ->setMethods(array('sendRequest')) + ->getMock(); $httpClient ->expects($this->any()) - ->method('send'); + ->method('sendRequest'); + + $client = Client::createWithHttpClient($httpClient); - return $httpClient; + return $this->getMockBuilder($this->getApiClass()) + ->setMethods(array_merge(array('get', 'post', 'postRaw', 'patch', 'delete', 'put', 'head'), $methods)) + ->setConstructorArgs(array($client)) + ->getMock(); } } diff --git a/test/Gitlab/Tests/Api/UsersTest.php b/test/Gitlab/Tests/Api/UsersTest.php index a1441da00..de2932396 100644 --- a/test/Gitlab/Tests/Api/UsersTest.php +++ b/test/Gitlab/Tests/Api/UsersTest.php @@ -2,7 +2,7 @@ use Gitlab\Api\AbstractApi; -class UsersTest extends ApiTestCase +class UsersTest extends TestCase { /** * @test diff --git a/test/Gitlab/Tests/HttpClient/BuilderTest.php b/test/Gitlab/Tests/HttpClient/BuilderTest.php new file mode 100644 index 000000000..fa51bdd2f --- /dev/null +++ b/test/Gitlab/Tests/HttpClient/BuilderTest.php @@ -0,0 +1,54 @@ + + */ +class BuilderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Builder + */ + private $subject; + + public function setUp() + { + $this->subject = new Builder( + $this->getMock(HttpClient::class), + $this->getMock(RequestFactory::class), + $this->getMock(StreamFactory::class) + ); + } + + public function testAddPluginShouldInvalidateHttpClient() + { + $client = $this->subject->getHttpClient(); + + $this->subject->addPlugin($this->getMock(Plugin::class)); + + $this->assertNotSame($client, $this->subject->getHttpClient()); + } + + public function testRemovePluginShouldInvalidateHttpClient() + { + $this->subject->addPlugin($this->getMock(Plugin::class)); + + $client = $this->subject->getHttpClient(); + + $this->subject->removePlugin(Plugin::class); + + $this->assertNotSame($client, $this->subject->getHttpClient()); + } + + public function testHttpClientShouldBeAnHttpMethodsClient() + { + $this->assertInstanceOf(HttpMethodsClient::class, $this->subject->getHttpClient()); + } +} diff --git a/test/Gitlab/Tests/HttpClient/Message/ResponseMediatorTest.php b/test/Gitlab/Tests/HttpClient/Message/ResponseMediatorTest.php new file mode 100644 index 000000000..661e6ad6a --- /dev/null +++ b/test/Gitlab/Tests/HttpClient/Message/ResponseMediatorTest.php @@ -0,0 +1,77 @@ + + */ +class ResponseMediatorTest extends \PHPUnit_Framework_TestCase +{ + public function testGetContent() + { + $body = array('foo' => 'bar'); + $response = new Response( + 200, + array('Content-Type'=>'application/json'), + \GuzzleHttp\Psr7\stream_for(json_encode($body)) + ); + + $this->assertEquals($body, ResponseMediator::getContent($response)); + } + + /** + * If content-type is not json we should get the raw body. + */ + public function testGetContentNotJson() + { + $body = 'foobar'; + $response = new Response( + 200, + array(), + \GuzzleHttp\Psr7\stream_for($body) + ); + + $this->assertEquals($body, ResponseMediator::getContent($response)); + } + + /** + * Make sure we return the body if we have invalid json + */ + public function testGetContentInvalidJson() + { + $body = 'foobar'; + $response = new Response( + 200, + array('Content-Type'=>'application/json'), + \GuzzleHttp\Psr7\stream_for($body) + ); + + $this->assertEquals($body, ResponseMediator::getContent($response)); + } + + public function testGetPagination() + { + $header = <<; rel="first", +; rel="next", +; rel="prev", +; rel="last", +TEXT; + + $pagination = array( + 'first' => 'https://example.gitlab.com', + 'next' => 'https://example.gitlab.com', + 'prev' => 'https://example.gitlab.com', + 'last' => 'https://example.gitlab.com' + ); + + // response mock + $response = new Response(200, array('link'=>$header)); + $result = ResponseMediator::getPagination($response); + + $this->assertEquals($pagination, $result); + } +} diff --git a/test/Gitlab/Tests/HttpClient/Plugin/ApiVersionTest.php b/test/Gitlab/Tests/HttpClient/Plugin/ApiVersionTest.php new file mode 100644 index 000000000..805151d2c --- /dev/null +++ b/test/Gitlab/Tests/HttpClient/Plugin/ApiVersionTest.php @@ -0,0 +1,67 @@ +getMockBuilder(\stdClass::class) + ->setMethods(['next']) + ->getMock() + ; + $callback->expects($this->once()) + ->method('next') + ->with($this->isInstanceOf(RequestInterface::class)) + ->willReturn($promise) + ; + + $this->assertEquals($promise, $plugin->handleRequest($request, [$callback, 'next'], function () {})); + } + + public function testPrefixRequestPath() + { + $request = new Request('GET', 'projects'); + $expected = new Request('GET', '/api/v3/projects'); + $plugin = new ApiVersion(); + + $callback = $this->getMockBuilder(\stdClass::class) + ->setMethods(['next']) + ->getMock() + ; + $callback->expects($this->once()) + ->method('next') + ->with($expected) + ; + + $plugin->handleRequest($request, [$callback, 'next'], function () {}); + } + + public function testNoPrefixingRequired() + { + $request = new Request('GET', '/api/v3/projects'); + $plugin = new ApiVersion(); + + $callback = $this->getMockBuilder(\stdClass::class) + ->setMethods(['next']) + ->getMock() + ; + $callback->expects($this->once()) + ->method('next') + ->with($request) + ; + + $plugin->handleRequest($request, [$callback, 'next'], function () {}); + } +} diff --git a/test/Gitlab/Tests/ResultPagerTest.php b/test/Gitlab/Tests/ResultPagerTest.php new file mode 100644 index 000000000..b411b0704 --- /dev/null +++ b/test/Gitlab/Tests/ResultPagerTest.php @@ -0,0 +1,113 @@ +getMockBuilder(Client::class) + ->disableOriginalConstructor() + ->getMock() + ; + + $api = $this->getMockBuilder(ApiInterface::class) + ->setMethods(['__construct', 'all']) + ->getMock() + ; + $api->expects($this->once()) + ->method('all') + ->willReturn(['project1', 'project2']) + ; + + $pager = new ResultPager($client); + + $result = $pager->fetch($api, 'all'); + + $this->assertEquals(['project1', 'project2'], $result); + } + + public function testFetchAll() + { + $client = $this->getMockBuilder(Client::class) + ->disableOriginalConstructor() + ->getMock() + ; + + $history = $this->getMockBuilder(History::class) + ->disableOriginalConstructor() + ->getMock() + ; + + $response1 = (new Response)->withHeader('Link', '; rel="next",'); + $response2 = (new Response)->withHeader('Link', '; rel="next",') + ->withHeader('Content-Type', 'application/json') + ->withBody(stream_for('["project3", "project4"]')) + ; + $response3 = (new Response)->withHeader('Content-Type', 'application/json') + ->withBody(stream_for('["project5", "project6"]')) + ; + + $history + ->method('getLastResponse') + ->will($this->onConsecutiveCalls( + $response1, + $response1, + $response1, + $response2, + $response2, + $response2, + $response3 + )) + ; + + $httpClient = $this->getMockBuilder(HttpMethodsClient::class) + ->disableOriginalConstructor() + ->getMock() + ; + + $httpClient->expects($this->exactly(2)) + ->method('get') + ->withConsecutive( + ['https://example.gitlab.com/projects?page=2'], + ['https://example.gitlab.com/projects?page=3'] + ) + ->will($this->onConsecutiveCalls( + $response2, + $response3 + )) + ; + + $client + ->method('getResponseHistory') + ->willReturn($history) + ; + $client + ->method('getHttpClient') + ->willReturn($httpClient) + ; + + $api = $this->getMockBuilder(ApiInterface::class) + ->setMethods(['__construct', 'all']) + ->getMock(); + $api->expects($this->exactly(1)) + ->method('all') + ->willReturn(['project1', 'project2']) + ; + + $pager = new ResultPager($client); + + $result = $pager->fetchAll($api, 'all'); + + $this->assertEquals(['project1', 'project2', 'project3', 'project4', 'project5', 'project6'], $result); + } +} From 866532d5701bc06a12a122b4b5ca79444a5cf741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=83=C2=83=C3=82=C2=A9grier?= Date: Mon, 19 Jun 2017 15:55:32 +0200 Subject: [PATCH 13/83] Adding the Jobs API --- lib/Gitlab/Api/Jobs.php | 131 ++++++++++++++++++ lib/Gitlab/Client.php | 5 + lib/Gitlab/Model/Job.php | 83 ++++++++++++ lib/Gitlab/Model/Pipeline.php | 49 +++++++ lib/Gitlab/Model/Project.php | 45 +++++++ test/Gitlab/Tests/Api/JobsTest.php | 210 +++++++++++++++++++++++++++++ 6 files changed, 523 insertions(+) create mode 100644 lib/Gitlab/Api/Jobs.php create mode 100644 lib/Gitlab/Model/Job.php create mode 100644 lib/Gitlab/Model/Pipeline.php create mode 100644 test/Gitlab/Tests/Api/JobsTest.php diff --git a/lib/Gitlab/Api/Jobs.php b/lib/Gitlab/Api/Jobs.php new file mode 100644 index 000000000..03d2f63cb --- /dev/null +++ b/lib/Gitlab/Api/Jobs.php @@ -0,0 +1,131 @@ +get("projects/".$this->encodePath($project_id)."/jobs", array( + 'scope' => $scope + )); + } + + /** + * @param int|string $project_id + * @param int $pipeline_id + * @param array $scope + * @return mixed + */ + public function pipelineJobs($project_id, $pipeline_id, array $scope = []) + { + return $this->get("projects/".$this->encodePath($project_id)."/pipelines/".$this->encodePath($pipeline_id)."/jobs", array( + 'scope' => $scope + )); + } + + /** + * @param int|string $project_id + * @param int $job_id + * @return mixed + */ + public function show($project_id, $job_id) + { + return $this->get("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)); + } + + /** + * @param int|string $project_id + * @param int $job_id + * @return string + */ + public function artifacts($project_id, $job_id) + { + return $this->get("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/artifacts"); + } + + /** + * @param int|string $project_id + * @param string $ref_name + * @param string $job_name + * @return string + */ + public function artifactsByRefName($project_id, $ref_name, $job_name) + { + return $this->get("projects/".$this->encodePath($project_id)."/jobs/artifacts/".$this->encodePath($ref_name)."/download", array( + 'job' => $job_name + )); + } + + /** + * @param int|string $project_id + * @param int $job_id + * @return string + */ + public function trace($project_id, $job_id) + { + return $this->get("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/trace"); + } + + /** + * @param int|string $project_id + * @param int $job_id + * @return mixed + */ + public function cancel($project_id, $job_id) + { + return $this->post("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/cancel"); + } + + /** + * @param int|string $project_id + * @param int $job_id + * @return mixed + */ + public function retry($project_id, $job_id) + { + return $this->post("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/retry"); + } + + /** + * @param int|string $project_id + * @param int $job_id + * @return mixed + */ + public function erase($project_id, $job_id) + { + return $this->post("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/erase"); + } + + /** + * @param int|string $project_id + * @param int $job_id + * @return mixed + */ + public function keepArtifacts($project_id, $job_id) + { + return $this->post("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/artifacts/keep"); + } + + /** + * @param int|string $project_id + * @param int $job_id + * @return mixed + */ + public function play($project_id, $job_id) + { + return $this->post("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/play"); + } +} diff --git a/lib/Gitlab/Client.php b/lib/Gitlab/Client.php index b2cefa372..2cb2e4e49 100644 --- a/lib/Gitlab/Client.php +++ b/lib/Gitlab/Client.php @@ -21,6 +21,7 @@ * * @property-read \Gitlab\Api\Groups $groups * @property-read \Gitlab\Api\Issues $issues + * @property-read \Gitlab\Api\Jobs $jobs * @property-read \Gitlab\Api\MergeRequests $merge_requests * @property-read \Gitlab\Api\MergeRequests $mr * @property-read \Gitlab\Api\Milestones $milestones @@ -138,6 +139,10 @@ public function api($name) $api = new Api\Issues($this); break; + case 'jobs': + $api = new Api\Jobs($this); + break; + case 'mr': case 'merge_requests': $api = new Api\MergeRequests($this); diff --git a/lib/Gitlab/Model/Job.php b/lib/Gitlab/Model/Job.php new file mode 100644 index 000000000..586e3a311 --- /dev/null +++ b/lib/Gitlab/Model/Job.php @@ -0,0 +1,83 @@ +hydrate($data); + } + + /** + * @param Project $project + * @param int $id + * @param Client $client + */ + public function __construct(Project $project, $id = null, Client $client = null) + { + $this->setClient($client); + $this->setData('project', $project); + $this->setData('id', $id); + } +} diff --git a/lib/Gitlab/Model/Pipeline.php b/lib/Gitlab/Model/Pipeline.php new file mode 100644 index 000000000..58ec521bd --- /dev/null +++ b/lib/Gitlab/Model/Pipeline.php @@ -0,0 +1,49 @@ +hydrate($data); + } + + /** + * @param Project $project + * @param int $id + * @param Client $client + */ + public function __construct(Project $project, $id = null, Client $client = null) + { + $this->setClient($client); + $this->setData('project', $project); + $this->setData('id', $id); + } +} diff --git a/lib/Gitlab/Model/Project.php b/lib/Gitlab/Model/Project.php index 44fa9a7ee..031cb9def 100644 --- a/lib/Gitlab/Model/Project.php +++ b/lib/Gitlab/Model/Project.php @@ -1092,4 +1092,49 @@ public function contributors() return $contributors; } + + /** + * @param array $scopes + * @return Job[] + */ + public function jobs(array $scopes) + { + $data = $this->api('jobs')->jobs($this->id, $scopes); + + $jobs = array(); + foreach ($data as $job) { + $jobs[] = Job::fromArray($this->getClient(), $this, $job); + } + + return $jobs; + } + + /** + * @param int $pipeline_id + * @param array $scopes + * @return Job[] + */ + public function pipelineJobs($pipeline_id, array $scopes = []) + { + $data = $this->api('jobs')->pipelineJobs($this->id, $pipeline_id, $scopes); + + $jobs = array(); + foreach ($data as $job) { + $jobs[] = Job::fromArray($this->getClient(), $this, $job); + } + + return $jobs; + } + + /** + * @param int $job_id + * @return Job + */ + public function job($job_id) + { + $data = $this->api('jobs')->show($this->id, $job_id); + + return Job::fromArray($this->getClient(), $this, $data); + } + } diff --git a/test/Gitlab/Tests/Api/JobsTest.php b/test/Gitlab/Tests/Api/JobsTest.php new file mode 100644 index 000000000..d13880664 --- /dev/null +++ b/test/Gitlab/Tests/Api/JobsTest.php @@ -0,0 +1,210 @@ + 1, 'name' => 'A job'), + array('id' => 2, 'name' => 'Another job'), + ); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/jobs', array( + 'scope' => ['pending'] + )) + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->jobs(1, [Jobs::SCOPE_PENDING])); + } + + /** + * @test + */ + public function shouldGetPipelineJobs() + { + $expectedArray = array( + array('id' => 1, 'name' => 'A job'), + array('id' => 2, 'name' => 'Another job'), + ); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/pipelines/2/jobs', array( + 'scope' => ['pending'] + )) + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->pipelineJobs(1, 2, [Jobs::SCOPE_PENDING])); + } + + /** + * @test + */ + public function shouldGetJob() + { + $expectedArray = array('id' => 3, 'name' => 'A job'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/jobs/3') + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->show(1, 3)); + } + + /** + * @test + */ + public function shouldGetArtifacts() + { + $expectedString = "some file content"; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/jobs/3/artifacts') + ->will($this->returnValue($expectedString)) + ; + + $this->assertEquals($expectedString, $api->artifacts(1, 3)); + } + + /** + * @test + */ + public function shouldGetArtifactsByRefName() + { + $expectedString = "some file content"; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/jobs/artifacts/master/download', array( + 'job' => 'job_name' + )) + ->will($this->returnValue($expectedString)) + ; + + $this->assertEquals($expectedString, $api->artifactsByRefName(1, 'master', 'job_name')); + } + + /** + * @test + */ + public function shouldGetTrace() + { + $expectedString = "some trace"; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/jobs/3/trace') + ->will($this->returnValue($expectedString)) + ; + + $this->assertEquals($expectedString, $api->trace(1, 3)); + } + + /** + * @test + */ + public function shouldCancel() + { + $expectedArray = array('id' => 3, 'name' => 'A job'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/jobs/3/cancel') + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->cancel(1, 3)); + } + + /** + * @test + */ + public function shouldRetry() + { + $expectedArray = array('id' => 3, 'name' => 'A job'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/jobs/3/retry') + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->retry(1, 3)); + } + + /** + * @test + */ + public function shouldErase() + { + $expectedArray = array('id' => 3, 'name' => 'A job'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/jobs/3/erase') + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->erase(1, 3)); + } + + /** + * @test + */ + public function shouldKeepArtifacts() + { + $expectedArray = array('id' => 3, 'name' => 'A job'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/jobs/3/artifacts/keep') + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->keepArtifacts(1, 3)); + } + + /** + * @test + */ + public function shouldPlay() + { + $expectedArray = array('id' => 3, 'name' => 'A job'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/jobs/3/play') + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->play(1, 3)); + } + + protected function getApiClass() + { + return 'Gitlab\Api\Jobs'; + } +} From a1174d700a6d513dabb70b3ca04e4849f01ee2ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Fri, 7 Jul 2017 11:33:53 +0200 Subject: [PATCH 14/83] Migrating JobsAPI to use new HTTPlug. Now returning a StreamInterface instead of a string for artifact files. --- lib/Gitlab/Api/AbstractApi.php | 20 ++++++++++++++++---- lib/Gitlab/Api/Jobs.php | 12 +++++++----- test/Gitlab/Tests/Api/JobsTest.php | 19 ++++++++++--------- test/Gitlab/Tests/Api/TestCase.php | 2 +- 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/lib/Gitlab/Api/AbstractApi.php b/lib/Gitlab/Api/AbstractApi.php index e08996973..7aab58d0e 100644 --- a/lib/Gitlab/Api/AbstractApi.php +++ b/lib/Gitlab/Api/AbstractApi.php @@ -5,6 +5,7 @@ use Http\Discovery\StreamFactoryDiscovery; use Http\Message\MultipartStream\MultipartStreamBuilder; use Http\Message\StreamFactory; +use Psr\Http\Message\ResponseInterface; /** * Abstract class for Api classes @@ -52,18 +53,29 @@ public function configure() } /** + * Performs a GET query and returns the response as a PSR-7 response object. + * * @param string $path * @param array $parameters * @param array $requestHeaders - * @return mixed + * @return ResponseInterface */ - protected function get($path, array $parameters = array(), $requestHeaders = array()) + protected function getAsResponse($path, array $parameters = array(), $requestHeaders = array()) { $path = $this->preparePath($path, $parameters); - $response = $this->client->getHttpClient()->get($path, $requestHeaders); + return $this->client->getHttpClient()->get($path, $requestHeaders); + } - return ResponseMediator::getContent($response); + /** + * @param string $path + * @param array $parameters + * @param array $requestHeaders + * @return mixed + */ + protected function get($path, array $parameters = array(), $requestHeaders = array()) + { + return ResponseMediator::getContent($this->getAsResponse($path, $parameters, $requestHeaders)); } /** diff --git a/lib/Gitlab/Api/Jobs.php b/lib/Gitlab/Api/Jobs.php index 03d2f63cb..580a69f14 100644 --- a/lib/Gitlab/Api/Jobs.php +++ b/lib/Gitlab/Api/Jobs.php @@ -1,5 +1,7 @@ get("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/artifacts"); + return $this->getAsResponse("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/artifacts")->getBody(); } /** * @param int|string $project_id * @param string $ref_name * @param string $job_name - * @return string + * @return StreamInterface */ public function artifactsByRefName($project_id, $ref_name, $job_name) { - return $this->get("projects/".$this->encodePath($project_id)."/jobs/artifacts/".$this->encodePath($ref_name)."/download", array( + return $this->getAsResponse("projects/".$this->encodePath($project_id)."/jobs/artifacts/".$this->encodePath($ref_name)."/download", array( 'job' => $job_name - )); + ))->getBody(); } /** diff --git a/test/Gitlab/Tests/Api/JobsTest.php b/test/Gitlab/Tests/Api/JobsTest.php index d13880664..556856a8e 100644 --- a/test/Gitlab/Tests/Api/JobsTest.php +++ b/test/Gitlab/Tests/Api/JobsTest.php @@ -1,8 +1,9 @@ getApiMock(); $api->expects($this->once()) - ->method('get') + ->method('getAsResponse') ->with('projects/1/jobs/3/artifacts') - ->will($this->returnValue($expectedString)) + ->will($this->returnValue($returnedStream)) ; - $this->assertEquals($expectedString, $api->artifacts(1, 3)); + $this->assertEquals('foobar', $api->artifacts(1, 3)->getContents()); } /** @@ -87,18 +88,18 @@ public function shouldGetArtifacts() */ public function shouldGetArtifactsByRefName() { - $expectedString = "some file content"; + $returnedStream = new Response(200, [], 'foobar'); $api = $this->getApiMock(); $api->expects($this->once()) - ->method('get') + ->method('getAsResponse') ->with('projects/1/jobs/artifacts/master/download', array( 'job' => 'job_name' )) - ->will($this->returnValue($expectedString)) + ->will($this->returnValue($returnedStream)) ; - $this->assertEquals($expectedString, $api->artifactsByRefName(1, 'master', 'job_name')); + $this->assertEquals('foobar', $api->artifactsByRefName(1, 'master', 'job_name')->getContents()); } /** diff --git a/test/Gitlab/Tests/Api/TestCase.php b/test/Gitlab/Tests/Api/TestCase.php index b3dadeb6f..a48c1a01a 100644 --- a/test/Gitlab/Tests/Api/TestCase.php +++ b/test/Gitlab/Tests/Api/TestCase.php @@ -28,7 +28,7 @@ protected function getApiMock(array $methods = []) $client = Client::createWithHttpClient($httpClient); return $this->getMockBuilder($this->getApiClass()) - ->setMethods(array_merge(array('get', 'post', 'postRaw', 'patch', 'delete', 'put', 'head'), $methods)) + ->setMethods(array_merge(array('getAsResponse', 'get', 'post', 'postRaw', 'patch', 'delete', 'put', 'head'), $methods)) ->setConstructorArgs(array($client)) ->getMock(); } From 28c82569f72e27c5dd81fb308c00c80795359dee Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Fri, 7 Jul 2017 13:58:17 +0200 Subject: [PATCH 15/83] set api endpoint to /api/v4 --- lib/Gitlab/HttpClient/Plugin/ApiVersion.php | 6 +++--- test/Gitlab/Tests/HttpClient/Plugin/ApiVersionTest.php | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/Gitlab/HttpClient/Plugin/ApiVersion.php b/lib/Gitlab/HttpClient/Plugin/ApiVersion.php index 3e196ea78..46b20e402 100644 --- a/lib/Gitlab/HttpClient/Plugin/ApiVersion.php +++ b/lib/Gitlab/HttpClient/Plugin/ApiVersion.php @@ -7,7 +7,7 @@ use Psr\Http\Message\RequestInterface; /** - * Prefix requests path with /api/v3/ if required. + * Prefix requests path with /api/v4/ if required. * * @author Fabien Bourigault */ @@ -20,8 +20,8 @@ public function handleRequest(RequestInterface $request, callable $next, callabl { $uri = $request->getUri(); - if (substr($uri->getPath(), 0, 8) !== '/api/v3/') { - $request = $request->withUri($uri->withPath('/api/v3/'.$uri->getPath())); + if (substr($uri->getPath(), 0, 8) !== '/api/v4/') { + $request = $request->withUri($uri->withPath('/api/v4/'.$uri->getPath())); } return $next($request); diff --git a/test/Gitlab/Tests/HttpClient/Plugin/ApiVersionTest.php b/test/Gitlab/Tests/HttpClient/Plugin/ApiVersionTest.php index 805151d2c..0ef35ff5d 100644 --- a/test/Gitlab/Tests/HttpClient/Plugin/ApiVersionTest.php +++ b/test/Gitlab/Tests/HttpClient/Plugin/ApiVersionTest.php @@ -33,7 +33,7 @@ public function testCallNextCallback() public function testPrefixRequestPath() { $request = new Request('GET', 'projects'); - $expected = new Request('GET', '/api/v3/projects'); + $expected = new Request('GET', '/api/v4/projects'); $plugin = new ApiVersion(); $callback = $this->getMockBuilder(\stdClass::class) @@ -50,7 +50,7 @@ public function testPrefixRequestPath() public function testNoPrefixingRequired() { - $request = new Request('GET', '/api/v3/projects'); + $request = new Request('GET', '/api/v4/projects'); $plugin = new ApiVersion(); $callback = $this->getMockBuilder(\stdClass::class) From 0bd3cd4a35f0cf992ebe90b96a6eefde70eab3dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=83=C2=A9grier?= Date: Sat, 8 Jul 2017 18:44:37 +0200 Subject: [PATCH 16/83] Changing method name from "jobs" to "all" --- lib/Gitlab/Api/Jobs.php | 2 +- test/Gitlab/Tests/Api/JobsTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Gitlab/Api/Jobs.php b/lib/Gitlab/Api/Jobs.php index 580a69f14..246f8f148 100644 --- a/lib/Gitlab/Api/Jobs.php +++ b/lib/Gitlab/Api/Jobs.php @@ -18,7 +18,7 @@ class Jobs extends AbstractApi * @param array $scope * @return mixed */ - public function jobs($project_id, array $scope = []) + public function all($project_id, array $scope = []) { return $this->get("projects/".$this->encodePath($project_id)."/jobs", array( 'scope' => $scope diff --git a/test/Gitlab/Tests/Api/JobsTest.php b/test/Gitlab/Tests/Api/JobsTest.php index 556856a8e..c002437dc 100644 --- a/test/Gitlab/Tests/Api/JobsTest.php +++ b/test/Gitlab/Tests/Api/JobsTest.php @@ -24,7 +24,7 @@ public function shouldGetAllJobs() ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->jobs(1, [Jobs::SCOPE_PENDING])); + $this->assertEquals($expectedArray, $api->all(1, [Jobs::SCOPE_PENDING])); } /** From 52f2b20caad4b4a2daaed2840d44a07f4c1f3ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Sat, 8 Jul 2017 18:45:28 +0200 Subject: [PATCH 17/83] Default value for jobs method and fixing bug in pipeline class --- lib/Gitlab/Model/Pipeline.php | 2 +- lib/Gitlab/Model/Project.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Gitlab/Model/Pipeline.php b/lib/Gitlab/Model/Pipeline.php index 58ec521bd..b2129c8de 100644 --- a/lib/Gitlab/Model/Pipeline.php +++ b/lib/Gitlab/Model/Pipeline.php @@ -32,7 +32,7 @@ public static function fromArray(Client $client, Project $project, array $data) { $pipeline = new static($project, $data['id'], $client); - return $job->hydrate($data); + return $pipeline->hydrate($data); } /** diff --git a/lib/Gitlab/Model/Project.php b/lib/Gitlab/Model/Project.php index 031cb9def..60d470318 100644 --- a/lib/Gitlab/Model/Project.php +++ b/lib/Gitlab/Model/Project.php @@ -1097,7 +1097,7 @@ public function contributors() * @param array $scopes * @return Job[] */ - public function jobs(array $scopes) + public function jobs(array $scopes = []) { $data = $this->api('jobs')->jobs($this->id, $scopes); From 16c6de6498cb646e0b036c55ae76a3405d9d45a4 Mon Sep 17 00:00:00 2001 From: Michael COULLERET Date: Mon, 10 Jul 2017 12:02:59 +0200 Subject: [PATCH 18/83] Add approvals, approve & unapprove API's --- lib/Gitlab/Api/MergeRequests.php | 33 +++++++++++++ test/Gitlab/Tests/Api/MergeRequestsTest.php | 52 +++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/lib/Gitlab/Api/MergeRequests.php b/lib/Gitlab/Api/MergeRequests.php index 2d6dc6184..a4f1e2522 100644 --- a/lib/Gitlab/Api/MergeRequests.php +++ b/lib/Gitlab/Api/MergeRequests.php @@ -218,4 +218,37 @@ public function commits($project_id, $mr_id) { return $this->get($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/commits')); } + + /** + * @param int $project_id + * @param int $mr_id + * + * @return mixed + */ + public function approvals($project_id, $mr_id) + { + return $this->get($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/approvals')); + } + + /** + * @param int $project_id + * @param int $mr_id + * + * @return mixed + */ + public function approve($project_id, $mr_id) + { + return $this->post($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/approve')); + } + + /** + * @param int $project_id + * @param int $mr_id + * + * @return mixed + */ + public function unApprove($project_id, $mr_id) + { + return $this->post($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/unapprove')); + } } diff --git a/test/Gitlab/Tests/Api/MergeRequestsTest.php b/test/Gitlab/Tests/Api/MergeRequestsTest.php index bd6e6eb2b..c1e2181ea 100644 --- a/test/Gitlab/Tests/Api/MergeRequestsTest.php +++ b/test/Gitlab/Tests/Api/MergeRequestsTest.php @@ -353,6 +353,58 @@ public function shouldGetMergeRequestByIid() $this->assertEquals($expectedArray, $api->getByIid(1, 2)); } + /** + * @test + */ + public function shouldApproveMergeRequest() + { + $expectedArray = array('id' => 1, 'title' => 'Approvals API'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/merge_requests/2/approve') + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->approve(1, 2)); + } + + /** + * @test + */ + public function shouldUnApproveMergeRequest() + { + $expectedArray = array('id' => 1, 'title' => 'Approvals API'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/merge_requests/2/unapprove') + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->unapprove(1, 2)); + } + + /** + * @test + */ + public function shouldGetMergeRequestApprovals() + { + $expectedArray = array('id' => 1, 'title' => 'Approvals API'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/merge_requests', array('iid' => 2)) + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->getByIid(1, 2)); + } + + protected function getMultipleMergeRequestsData() { return array( From 63ba9d833ec761f19cc787772e24f53289330f1e Mon Sep 17 00:00:00 2001 From: Miguel Piedrafita Date: Mon, 17 Jul 2017 14:02:55 +0200 Subject: [PATCH 19/83] Apply suggested fixes --- lib/Gitlab/Api/MergeRequests.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Gitlab/Api/MergeRequests.php b/lib/Gitlab/Api/MergeRequests.php index a4f1e2522..19addd580 100644 --- a/lib/Gitlab/Api/MergeRequests.php +++ b/lib/Gitlab/Api/MergeRequests.php @@ -225,7 +225,7 @@ public function commits($project_id, $mr_id) * * @return mixed */ - public function approvals($project_id, $mr_id) + public function approvals($project_id, $merge_request_iid) { return $this->get($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/approvals')); } @@ -236,7 +236,7 @@ public function approvals($project_id, $mr_id) * * @return mixed */ - public function approve($project_id, $mr_id) + public function approve($project_id, $merge_request_iid) { return $this->post($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/approve')); } @@ -247,7 +247,7 @@ public function approve($project_id, $mr_id) * * @return mixed */ - public function unApprove($project_id, $mr_id) + public function unapprove($project_id, $merge_request_iid) { return $this->post($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/unapprove')); } From 0d3edb1b4ab4f117d4c3be4c3e2c14681b5c6c21 Mon Sep 17 00:00:00 2001 From: Miguel Piedrafita Date: Mon, 17 Jul 2017 15:14:01 +0200 Subject: [PATCH 20/83] Fix Travis --- test/Gitlab/Tests/Api/IssueBoardsTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Gitlab/Tests/Api/IssueBoardsTest.php b/test/Gitlab/Tests/Api/IssueBoardsTest.php index 1bd42832a..0cce48dbc 100644 --- a/test/Gitlab/Tests/Api/IssueBoardsTest.php +++ b/test/Gitlab/Tests/Api/IssueBoardsTest.php @@ -2,7 +2,7 @@ use Gitlab\Api\AbstractApi; -class IssueBoardsTest extends ApiTestCase +class IssueBoardsTest extends TestCase { /** * @test From 6a62720e17dbd4b2e00f69ae6d3b5ff202586fae Mon Sep 17 00:00:00 2001 From: Miguel Piedrafita Date: Mon, 17 Jul 2017 15:24:39 +0200 Subject: [PATCH 21/83] Fix tests --- lib/Gitlab/Api/MergeRequests.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Gitlab/Api/MergeRequests.php b/lib/Gitlab/Api/MergeRequests.php index 19addd580..525d75d5f 100644 --- a/lib/Gitlab/Api/MergeRequests.php +++ b/lib/Gitlab/Api/MergeRequests.php @@ -227,7 +227,7 @@ public function commits($project_id, $mr_id) */ public function approvals($project_id, $merge_request_iid) { - return $this->get($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/approvals')); + return $this->get($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($merge_request_iid).'/approvals')); } /** @@ -238,7 +238,7 @@ public function approvals($project_id, $merge_request_iid) */ public function approve($project_id, $merge_request_iid) { - return $this->post($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/approve')); + return $this->post($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($merge_request_iid).'/approve')); } /** @@ -249,6 +249,6 @@ public function approve($project_id, $merge_request_iid) */ public function unapprove($project_id, $merge_request_iid) { - return $this->post($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/unapprove')); + return $this->post($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($merge_request_iid).'/unapprove')); } } From f8dadc697dccdcb2d58a735013c516488be1d0a8 Mon Sep 17 00:00:00 2001 From: Christian Daguerre Date: Tue, 18 Jul 2017 12:20:09 +0200 Subject: [PATCH 22/83] Fixed tests --- lib/Gitlab/Api/MergeRequests.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/Gitlab/Api/MergeRequests.php b/lib/Gitlab/Api/MergeRequests.php index 3590064fd..abe7cc4ec 100644 --- a/lib/Gitlab/Api/MergeRequests.php +++ b/lib/Gitlab/Api/MergeRequests.php @@ -227,6 +227,11 @@ public function commits($project_id, $mr_id) public function closesIssues($project_id, $mr_id) { return $this->get($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/closes_issues')); + } + + /** + * @param int $project_id + * @param int $mr_id * * @return mixed */ From d455f75b1bec3caaebe58829c039d65b6c2c0c3e Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 18 Jul 2017 13:22:05 +0200 Subject: [PATCH 23/83] rename branch_name to branch --- lib/Gitlab/Api/Repositories.php | 30 +++++++++++----------- test/Gitlab/Tests/Api/RepositoriesTest.php | 18 ++++++------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/Gitlab/Api/Repositories.php b/lib/Gitlab/Api/Repositories.php index bb6e842e8..9bcce03da 100644 --- a/lib/Gitlab/Api/Repositories.php +++ b/lib/Gitlab/Api/Repositories.php @@ -23,26 +23,26 @@ public function branch($project_id, $branch_id) /** * @param int $project_id - * @param string $branch_name + * @param string $branch * @param string $ref * @return mixed */ - public function createBranch($project_id, $branch_name, $ref) + public function createBranch($project_id, $branch, $ref) { return $this->post($this->getProjectPath($project_id, 'repository/branches'), array( - 'branch_name' => $branch_name, + 'branch' => $branch, 'ref' => $ref )); } /** * @param int $project_id - * @param string $branch_name + * @param string $branch * @return mixed */ - public function deleteBranch($project_id, $branch_name) + public function deleteBranch($project_id, $branch) { - return $this->delete($this->getProjectPath($project_id, 'repository/branches/'.$this->encodeBranch($branch_name))); + return $this->delete($this->getProjectPath($project_id, 'repository/branches/'.$this->encodeBranch($branch))); } /** @@ -263,18 +263,18 @@ public function getFile($project_id, $file_path, $ref) * @param int $project_id * @param string $file_path * @param string $content - * @param string $branch_name + * @param string $branch * @param string $commit_message * @param string $encoding * @param string $author_email * @param string $author_name * @return mixed */ - public function createFile($project_id, $file_path, $content, $branch_name, $commit_message, $encoding = null, $author_email = null, $author_name = null) + public function createFile($project_id, $file_path, $content, $branch, $commit_message, $encoding = null, $author_email = null, $author_name = null) { return $this->post($this->getProjectPath($project_id, 'repository/files'), array( 'file_path' => $file_path, - 'branch_name' => $branch_name, + 'branch' => $branch, 'content' => $content, 'commit_message' => $commit_message, 'encoding' => $encoding, @@ -287,18 +287,18 @@ public function createFile($project_id, $file_path, $content, $branch_name, $com * @param int $project_id * @param string $file_path * @param string $content - * @param string $branch_name + * @param string $branch * @param string $commit_message * @param string $encoding * @param string $author_email * @param string $author_name * @return mixed */ - public function updateFile($project_id, $file_path, $content, $branch_name, $commit_message, $encoding = null, $author_email = null, $author_name = null) + public function updateFile($project_id, $file_path, $content, $branch, $commit_message, $encoding = null, $author_email = null, $author_name = null) { return $this->put($this->getProjectPath($project_id, 'repository/files'), array( 'file_path' => $file_path, - 'branch_name' => $branch_name, + 'branch' => $branch, 'content' => $content, 'commit_message' => $commit_message, 'encoding' => $encoding, @@ -310,17 +310,17 @@ public function updateFile($project_id, $file_path, $content, $branch_name, $com /** * @param int $project_id * @param string $file_path - * @param string $branch_name + * @param string $branch * @param string $commit_message * @param string $author_email * @param string $author_name * @return mixed */ - public function deleteFile($project_id, $file_path, $branch_name, $commit_message, $author_email = null, $author_name = null) + public function deleteFile($project_id, $file_path, $branch, $commit_message, $author_email = null, $author_name = null) { return $this->delete($this->getProjectPath($project_id, 'repository/files'), array( 'file_path' => $file_path, - 'branch_name' => $branch_name, + 'branch' => $branch, 'commit_message' => $commit_message, 'author_email' => $author_email, 'author_name' => $author_name, diff --git a/test/Gitlab/Tests/Api/RepositoriesTest.php b/test/Gitlab/Tests/Api/RepositoriesTest.php index 3de0f0b60..8abbeea0d 100644 --- a/test/Gitlab/Tests/Api/RepositoriesTest.php +++ b/test/Gitlab/Tests/Api/RepositoriesTest.php @@ -51,7 +51,7 @@ public function shouldCreateBranch() $api = $this->getApiMock(); $api->expects($this->once()) ->method('post') - ->with('projects/1/repository/branches', array('branch_name' => 'feature', 'ref' => 'master')) + ->with('projects/1/repository/branches', array('branch' => 'feature', 'ref' => 'master')) ->will($this->returnValue($expectedArray)) ; @@ -497,7 +497,7 @@ public function shouldCreateFile() ->method('post') ->with('projects/1/repository/files', array( 'file_path' => 'dir/file1.txt', - 'branch_name' => 'master', + 'branch' => 'master', 'encoding' => null, 'content' => 'some contents', 'commit_message' => 'Added new file', @@ -522,7 +522,7 @@ public function shouldCreateFileWithEncoding() ->method('post') ->with('projects/1/repository/files', array( 'file_path' => 'dir/file1.txt', - 'branch_name' => 'master', + 'branch' => 'master', 'encoding' => 'text', 'content' => 'some contents', 'commit_message' => 'Added new file', @@ -547,7 +547,7 @@ public function shouldCreateFileWithAuthor() ->method('post') ->with('projects/1/repository/files', array( 'file_path' => 'dir/file1.txt', - 'branch_name' => 'master', + 'branch' => 'master', 'encoding' => null, 'content' => 'some contents', 'commit_message' => 'Added new file', @@ -572,7 +572,7 @@ public function shouldUpdateFile() ->method('put') ->with('projects/1/repository/files', array( 'file_path' => 'dir/file1.txt', - 'branch_name' => 'master', + 'branch' => 'master', 'encoding' => null, 'content' => 'some new contents', 'commit_message' => 'Updated new file', @@ -597,7 +597,7 @@ public function shouldUpdateFileWithEncoding() ->method('put') ->with('projects/1/repository/files', array( 'file_path' => 'dir/file1.txt', - 'branch_name' => 'master', + 'branch' => 'master', 'encoding' => 'base64', 'content' => 'some new contents', 'commit_message' => 'Updated file', @@ -622,7 +622,7 @@ public function shouldUpdateFileWithAuthor() ->method('put') ->with('projects/1/repository/files', array( 'file_path' => 'dir/file1.txt', - 'branch_name' => 'master', + 'branch' => 'master', 'encoding' => null, 'content' => 'some new contents', 'commit_message' => 'Updated file', @@ -647,7 +647,7 @@ public function shouldDeleteFile() ->method('delete') ->with('projects/1/repository/files', array( 'file_path' => 'dir/file1.txt', - 'branch_name' => 'master', + 'branch' => 'master', 'commit_message' => 'Deleted file', 'author_email' => null, 'author_name' => null, @@ -670,7 +670,7 @@ public function shouldDeleteFileWithAuthor() ->method('delete') ->with('projects/1/repository/files', array( 'file_path' => 'dir/file1.txt', - 'branch_name' => 'master', + 'branch' => 'master', 'commit_message' => 'Deleted file', 'author_email' => 'gitlab@example.com', 'author_name' => 'GitLab User', From 0974a3d13a8b33db635e58ba6a434505b4288b2d Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 18 Jul 2017 13:50:26 +0200 Subject: [PATCH 24/83] project fork v4 compatibility --- lib/Gitlab/Api/Projects.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Gitlab/Api/Projects.php b/lib/Gitlab/Api/Projects.php index 65781babc..d08b4449c 100644 --- a/lib/Gitlab/Api/Projects.php +++ b/lib/Gitlab/Api/Projects.php @@ -480,7 +480,7 @@ public function removeLabel($project_id, $name) */ public function fork($project_id) { - return $this->post('projects/fork/'.$this->encodePath($project_id)); + return $this->post('projects/'.$this->encodePath($project_id).'/fork'); } /** From bd2a65ffa21c3a15c2e0377ddc53818e57a5e9a2 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 18 Jul 2017 14:01:36 +0200 Subject: [PATCH 25/83] compatibility with v4 api for Users::block and Users::unblock --- lib/Gitlab/Api/Users.php | 4 ++-- test/Gitlab/Tests/Api/UsersTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Gitlab/Api/Users.php b/lib/Gitlab/Api/Users.php index a3e31ff5c..e72f96596 100644 --- a/lib/Gitlab/Api/Users.php +++ b/lib/Gitlab/Api/Users.php @@ -93,7 +93,7 @@ public function remove($id) */ public function block($id) { - return $this->put('users/'.$this->encodePath($id).'/block'); + return $this->post('users/'.$this->encodePath($id).'/block'); } /** @@ -102,7 +102,7 @@ public function block($id) */ public function unblock($id) { - return $this->put('users/'.$this->encodePath($id).'/unblock'); + return $this->post('users/'.$this->encodePath($id).'/unblock'); } /** diff --git a/test/Gitlab/Tests/Api/UsersTest.php b/test/Gitlab/Tests/Api/UsersTest.php index de2932396..ff76c5590 100644 --- a/test/Gitlab/Tests/Api/UsersTest.php +++ b/test/Gitlab/Tests/Api/UsersTest.php @@ -215,7 +215,7 @@ public function shouldBlockUser() $api = $this->getApiMock(); $api->expects($this->once()) - ->method('put') + ->method('post') ->with('users/1/block') ->will($this->returnValue($expectedBool)) ; @@ -232,7 +232,7 @@ public function shouldUnblockUser() $api = $this->getApiMock(); $api->expects($this->once()) - ->method('put') + ->method('post') ->with('users/1/unblock') ->will($this->returnValue($expectedBool)) ; From 7ebed95fe98b9d1dc4b74918d4a9e3ada953a887 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Wed, 19 Jul 2017 14:05:19 +0200 Subject: [PATCH 26/83] remove deprecated keys project endpoints --- UPGRADE.md | 10 ++++++ lib/Gitlab/Api/Projects.php | 39 ++++++---------------- lib/Gitlab/Model/Project.php | 31 ++++++------------ test/Gitlab/Tests/Api/ProjectsTest.php | 45 ++++++++------------------ 4 files changed, 44 insertions(+), 81 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index b777e0e97..3469ff626 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -12,3 +12,13 @@ See [documentation](doc/customize.md) to know how to customize the client timeou * The `clearHeaders` and `setHeaders` methods have been removed. See [documentation](doc/customize.md) to know how use custom headers. * The `setHttpClient` method have been removed. Use a `Gitlab\HttpClient\Builder` instead. * The `getHttpClient` method return type is changed to `Http\Client\Common\HttpMethodsClient`. + +## `Gitlab\Api\Projects` changes + +* The `keys`, `key`, `addKey`, `removeKey`, `disableKey` and `enableKey` methods have been removed. +Use the `deployKeys`, `deployKey`, `addDeployKey`, `deleteDeployKey`, `removeDeployKey` and `enableDeployKey` instead. + +## `Gitlab\Model\Project` changes + +* The `keys`, `key`, `addKey`, `removeKey`, `disableKey` and `enableKey` methods have been removed. +Use the `deployKeys`, `deployKey`, `addDeployKey`, `deleteDeployKey`, `removeDeployKey` and `enableDeployKey` instead. diff --git a/lib/Gitlab/Api/Projects.php b/lib/Gitlab/Api/Projects.php index 65781babc..2c046a3bb 100644 --- a/lib/Gitlab/Api/Projects.php +++ b/lib/Gitlab/Api/Projects.php @@ -285,15 +285,6 @@ public function removeMember($project_id, $user_id) return $this->delete($this->getProjectPath($project_id, 'members/'.urldecode($user_id))); } - /** - * @param int $project_id - * @return mixed - */ - public function deployKeys($project_id) - { - return $this->get($this->getProjectPath($project_id, 'deploy_keys')); - } - /** * @param int $project_id * @param int $page @@ -360,9 +351,9 @@ public function removeHook($project_id, $hook_id) * @param int $project_id * @return mixed */ - public function keys($project_id) + public function deployKeys($project_id) { - return $this->get($this->getProjectPath($project_id, 'keys')); + return $this->get($this->getProjectPath($project_id, 'deploy_keys')); } /** @@ -370,9 +361,9 @@ public function keys($project_id) * @param int $key_id * @return mixed */ - public function key($project_id, $key_id) + public function deployKey($project_id, $key_id) { - return $this->get($this->getProjectPath($project_id, 'keys/'.$this->encodePath($key_id))); + return $this->get($this->getProjectPath($project_id, 'deploy_keys/'.$this->encodePath($key_id))); } /** @@ -381,9 +372,9 @@ public function key($project_id, $key_id) * @param string $key * @return mixed */ - public function addKey($project_id, $title, $key) + public function addDeployKey($project_id, $title, $key) { - return $this->post($this->getProjectPath($project_id, 'keys'), array( + return $this->post($this->getProjectPath($project_id, 'deploy_keys'), array( 'title' => $title, 'key' => $key )); @@ -394,19 +385,9 @@ public function addKey($project_id, $title, $key) * @param int $key_id * @return mixed */ - public function removeKey($project_id, $key_id) - { - return $this->delete($this->getProjectPath($project_id, 'keys/'.$this->encodePath($key_id))); - } - - /** - * @param int $project_id - * @param int $key_id - * @return mixed - */ - public function enableKey($project_id, $key_id) + public function deleteDeployKey($project_id, $key_id) { - return $this->post($this->getProjectPath($project_id, 'keys/'.$this->encodePath($key_id).'/enable')); + return $this->delete($this->getProjectPath($project_id, 'deploy_keys/'.$this->encodePath($key_id))); } /** @@ -414,9 +395,9 @@ public function enableKey($project_id, $key_id) * @param int $key_id * @return mixed */ - public function disableKey($project_id, $key_id) + public function enableDeployKey($project_id, $key_id) { - return $this->delete($this->getProjectPath($project_id, 'keys/'.$this->encodePath($key_id).'/disable')); + return $this->post($this->getProjectPath($project_id, 'deploy_keys/'.$this->encodePath($key_id).'/enable')); } /** diff --git a/lib/Gitlab/Model/Project.php b/lib/Gitlab/Model/Project.php index 60d470318..887967e5f 100644 --- a/lib/Gitlab/Model/Project.php +++ b/lib/Gitlab/Model/Project.php @@ -300,9 +300,9 @@ public function removeHook($hook_id) /** * @return Key[] */ - public function keys() + public function deployKeys() { - $data = $this->api('projects')->keys($this->id); + $data = $this->api('projects')->deployKeys($this->id); $keys = array(); foreach ($data as $key) { @@ -316,9 +316,9 @@ public function keys() * @param int $key_id * @return Key */ - public function key($key_id) + public function deployKey($key_id) { - $data = $this->api('projects')->key($this->id, $key_id); + $data = $this->api('projects')->deployKey($this->id, $key_id); return Key::fromArray($this->getClient(), $data); } @@ -328,9 +328,9 @@ public function key($key_id) * @param string $key * @return Key */ - public function addKey($title, $key) + public function addDeployKey($title, $key) { - $data = $this->api('projects')->addKey($this->id, $title, $key); + $data = $this->api('projects')->addDeployKey($this->id, $title, $key); return Key::fromArray($this->getClient(), $data); } @@ -339,9 +339,9 @@ public function addKey($title, $key) * @param string $key_id * @return bool */ - public function removeKey($key_id) + public function deleteDeployKey($key_id) { - $this->api('projects')->removeKey($this->id, $key_id); + $this->api('projects')->deleteDeployKey($this->id, $key_id); return true; } @@ -350,20 +350,9 @@ public function removeKey($key_id) * @param string $key_id * @return bool */ - public function enableKey($key_id) + public function enableDeployKey($key_id) { - $this->api('projects')->enableKey($this->id, $key_id); - - return true; - } - - /** - * @param string $key_id - * @return bool - */ - public function disableKey($key_id) - { - $this->api('projects')->disableKey($this->id, $key_id); + $this->api('projects')->enableDeployKey($this->id, $key_id); return true; } diff --git a/test/Gitlab/Tests/Api/ProjectsTest.php b/test/Gitlab/Tests/Api/ProjectsTest.php index ff0467421..5c44b3835 100644 --- a/test/Gitlab/Tests/Api/ProjectsTest.php +++ b/test/Gitlab/Tests/Api/ProjectsTest.php @@ -638,7 +638,7 @@ public function shouldRemoveHook() /** * @test */ - public function shouldGetKeys() + public function shouldGetDeployKeys() { $expectedArray = array( array('id' => 1, 'title' => 'test-key'), @@ -648,28 +648,28 @@ public function shouldGetKeys() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/keys') + ->with('projects/1/deploy_keys') ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->keys(1)); + $this->assertEquals($expectedArray, $api->deployKeys(1)); } /** * @test */ - public function shouldGetKey() + public function shouldGetDeployKey() { $expectedArray = array('id' => 2, 'title' => 'another-key'); $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/keys/2') + ->with('projects/1/deploy_keys/2') ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->key(1, 2)); + $this->assertEquals($expectedArray, $api->deployKey(1, 2)); } /** @@ -682,62 +682,45 @@ public function shouldAddKey() $api = $this->getApiMock(); $api->expects($this->once()) ->method('post') - ->with('projects/1/keys', array('title' => 'new-key', 'key' => '...')) + ->with('projects/1/deploy_keys', array('title' => 'new-key', 'key' => '...')) ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->addKey(1, 'new-key', '...')); + $this->assertEquals($expectedArray, $api->addDeployKey(1, 'new-key', '...')); } /** * @test */ - public function shouldRemoveKey() + public function shouldDeleteDeployKey() { $expectedBool = true; $api = $this->getApiMock(); $api->expects($this->once()) ->method('delete') - ->with('projects/1/keys/3') + ->with('projects/1/deploy_keys/3') ->will($this->returnValue($expectedBool)) ; - $this->assertEquals($expectedBool, $api->removeKey(1, 3)); + $this->assertEquals($expectedBool, $api->deleteDeployKey(1, 3)); } /** * @test */ - public function shoudEnableKey() + public function shoudEnableDeployKey() { $expectedBool = true; $api = $this->getApiMock(); $api->expects($this->once()) ->method('post') - ->with('projects/1/keys/3/enable') + ->with('projects/1/deploy_keys/3/enable') ->will($this->returnValue($expectedBool)) ; - $this->assertEquals($expectedBool, $api->enableKey(1, 3)); - } - - /** - * @test - */ - public function shoudDisableKey() - { - $expectedBool = true; - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('delete') - ->with('projects/1/keys/3/disable') - ->will($this->returnValue($expectedBool)) - ; - - $this->assertEquals($expectedBool, $api->disableKey(1, 3)); + $this->assertEquals($expectedBool, $api->enableDeployKey(1, 3)); } /** From 100ced240b3b74fdcb7cc1986e16219035bddb5c Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Wed, 19 Jul 2017 21:49:34 +0200 Subject: [PATCH 27/83] remove expires_at snippet property --- UPGRADE.md | 4 ++++ lib/Gitlab/Model/Snippet.php | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 3469ff626..3ac17720e 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -22,3 +22,7 @@ Use the `deployKeys`, `deployKey`, `addDeployKey`, `deleteDeployKey`, `removeDep * The `keys`, `key`, `addKey`, `removeKey`, `disableKey` and `enableKey` methods have been removed. Use the `deployKeys`, `deployKey`, `addDeployKey`, `deleteDeployKey`, `removeDeployKey` and `enableDeployKey` instead. + +## `Gitlab\Model\Snippet` changes + +The `expires_at` property have been removed.` diff --git a/lib/Gitlab/Model/Snippet.php b/lib/Gitlab/Model/Snippet.php index 5d20e0dbf..7f039a9ea 100644 --- a/lib/Gitlab/Model/Snippet.php +++ b/lib/Gitlab/Model/Snippet.php @@ -8,7 +8,6 @@ * @property-read int $id * @property-read string $title * @property-read string $file_name - * @property-read string $expires_at * @property-read string $updated_at * @property-read string $created_at * @property-read Project $project @@ -24,7 +23,6 @@ class Snippet extends AbstractModel 'title', 'file_name', 'author', - 'expires_at', 'updated_at', 'created_at', 'project' From f10591de149ade3624f0936a03a13e4f91ef7c25 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Mon, 24 Jul 2017 13:23:46 +0200 Subject: [PATCH 28/83] update files repository endpoint for v4 --- lib/Gitlab/Api/Repositories.php | 7 +++---- test/Gitlab/Tests/Api/RepositoriesTest.php | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/Gitlab/Api/Repositories.php b/lib/Gitlab/Api/Repositories.php index 9bcce03da..3778d638a 100644 --- a/lib/Gitlab/Api/Repositories.php +++ b/lib/Gitlab/Api/Repositories.php @@ -240,8 +240,8 @@ public function tree($project_id, array $params = array()) */ public function blob($project_id, $sha, $filepath) { - return $this->get($this->getProjectPath($project_id, 'repository/commits/'.$this->encodePath($sha).'/blob'), array( - 'filepath' => $filepath + return $this->get($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($filepath).'/raw'), array( + 'ref' => $sha, )); } @@ -253,8 +253,7 @@ public function blob($project_id, $sha, $filepath) */ public function getFile($project_id, $file_path, $ref) { - return $this->get($this->getProjectPath($project_id, 'repository/files'), array( - 'file_path' => $file_path, + return $this->get($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($file_path)), array( 'ref' => $ref )); } diff --git a/test/Gitlab/Tests/Api/RepositoriesTest.php b/test/Gitlab/Tests/Api/RepositoriesTest.php index 8abbeea0d..7da871ff5 100644 --- a/test/Gitlab/Tests/Api/RepositoriesTest.php +++ b/test/Gitlab/Tests/Api/RepositoriesTest.php @@ -461,7 +461,7 @@ public function shouldGetBlob() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/repository/commits/abcd1234/blob', array('filepath' => 'dir/file1.txt')) + ->with('projects/1/repository/files/dir%2Ffile1%2Etxt/raw', array('ref' => 'abcd1234')) ->will($this->returnValue($expectedString)) ; @@ -478,7 +478,7 @@ public function shouldGetFile() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/repository/files', array('file_path' => 'dir/file1.txt', 'ref' => 'abcd1234')) + ->with('projects/1/repository/files/dir%2Ffile1%2Etxt', array('ref' => 'abcd1234')) ->will($this->returnValue($expectedArray)) ; From c2e2aa0356193f399abde6f8195e48c769212983 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Mon, 24 Jul 2017 13:28:14 +0200 Subject: [PATCH 29/83] commits repository v4 api changes --- UPGRADE.md | 4 ++++ lib/Gitlab/Api/Repositories.php | 2 +- test/Gitlab/Tests/Api/RepositoriesTest.php | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 3ac17720e..6203310c5 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -18,6 +18,10 @@ See [documentation](doc/customize.md) to know how to customize the client timeou * The `keys`, `key`, `addKey`, `removeKey`, `disableKey` and `enableKey` methods have been removed. Use the `deployKeys`, `deployKey`, `addDeployKey`, `deleteDeployKey`, `removeDeployKey` and `enableDeployKey` instead. +## `Gitlab\Api\Repositories` changes + +* The `commits` page argument now start from 1 instead of 0. + ## `Gitlab\Model\Project` changes * The `keys`, `key`, `addKey`, `removeKey`, `disableKey` and `enableKey` methods have been removed. diff --git a/lib/Gitlab/Api/Repositories.php b/lib/Gitlab/Api/Repositories.php index 9bcce03da..6c5c8b430 100644 --- a/lib/Gitlab/Api/Repositories.php +++ b/lib/Gitlab/Api/Repositories.php @@ -150,7 +150,7 @@ public function commitBuilds($project_id, $sha, $scope = null, $page = 0, $per_p * @param null $ref_name * @return mixed */ - public function commits($project_id, $page = 0, $per_page = self::PER_PAGE, $ref_name = null) + public function commits($project_id, $page = 1, $per_page = self::PER_PAGE, $ref_name = null) { return $this->get($this->getProjectPath($project_id, 'repository/commits'), array( 'page' => $page, diff --git a/test/Gitlab/Tests/Api/RepositoriesTest.php b/test/Gitlab/Tests/Api/RepositoriesTest.php index 8abbeea0d..ee6b73e0f 100644 --- a/test/Gitlab/Tests/Api/RepositoriesTest.php +++ b/test/Gitlab/Tests/Api/RepositoriesTest.php @@ -228,7 +228,7 @@ public function shouldGetCommits() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/repository/commits', array('page' => 0, 'per_page' => AbstractApi::PER_PAGE, 'ref_name' => null)) + ->with('projects/1/repository/commits', array('page' => 1, 'per_page' => AbstractApi::PER_PAGE, 'ref_name' => null)) ->will($this->returnValue($expectedArray)) ; From 6b86cf044daec8099e908de046c33914fa214a21 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Mon, 24 Jul 2017 14:01:00 +0200 Subject: [PATCH 30/83] update show issue for v4 --- lib/Gitlab/Api/Issues.php | 6 +++--- test/Gitlab/Tests/Api/IssuesTest.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Gitlab/Api/Issues.php b/lib/Gitlab/Api/Issues.php index 661ea7ac1..c82bde656 100644 --- a/lib/Gitlab/Api/Issues.php +++ b/lib/Gitlab/Api/Issues.php @@ -24,12 +24,12 @@ public function all($project_id = null, $page = 1, $per_page = self::PER_PAGE, a /** * @param int $project_id - * @param int $issue_id + * @param int $issue_iid * @return mixed */ - public function show($project_id, $issue_id) + public function show($project_id, $issue_iid) { - return $this->get($this->getProjectPath($project_id, 'issues?iid='.$this->encodePath($issue_id))); + return $this->get($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_iid))); } /** diff --git a/test/Gitlab/Tests/Api/IssuesTest.php b/test/Gitlab/Tests/Api/IssuesTest.php index 79f8446fb..6b5bc3759 100644 --- a/test/Gitlab/Tests/Api/IssuesTest.php +++ b/test/Gitlab/Tests/Api/IssuesTest.php @@ -74,7 +74,7 @@ public function shouldShowIssue() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/issues?iid=2') + ->with('projects/1/issues/2') ->will($this->returnValue($expectedArray)) ; From d0b3a0771ccbcf5e4e49e35cae371d7dac5644d2 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 25 Jul 2017 13:06:28 +0200 Subject: [PATCH 31/83] use issue iid --- UPGRADE.md | 5 +++ lib/Gitlab/Api/Issues.php | 66 +++++++++++++++++++-------------------- 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 3ac17720e..9100eaa1e 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -13,6 +13,11 @@ See [documentation](doc/customize.md) to know how to customize the client timeou * The `setHttpClient` method have been removed. Use a `Gitlab\HttpClient\Builder` instead. * The `getHttpClient` method return type is changed to `Http\Client\Common\HttpMethodsClient`. +## `Gitlab\Api\Issues` changes + +* The second argument of `update`, `remove`, `showComments`, `showComment`, `addComment`, `updateComment`, `removeComment`, + `setTimeEstimate`, `resetTimeEstimate`, `addSpentTime` and `resetSpentTime` methods is now a scoped issue id (iid). + ## `Gitlab\Api\Projects` changes * The `keys`, `key`, `addKey`, `removeKey`, `disableKey` and `enableKey` methods have been removed. diff --git a/lib/Gitlab/Api/Issues.php b/lib/Gitlab/Api/Issues.php index 661ea7ac1..db35145fc 100644 --- a/lib/Gitlab/Api/Issues.php +++ b/lib/Gitlab/Api/Issues.php @@ -44,53 +44,53 @@ public function create($project_id, array $params) /** * @param int $project_id - * @param int $issue_id + * @param int $issue_iid * @param array $params * @return mixed */ - public function update($project_id, $issue_id, array $params) + public function update($project_id, $issue_iid, array $params) { - return $this->put($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_id)), $params); + return $this->put($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_iid)), $params); } /** * @param int $project_id - * @param int $issue_id + * @param int $issue_iid * @return mixed */ - public function remove($project_id, $issue_id) + public function remove($project_id, $issue_iid) { - return $this->delete($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_id))); + return $this->delete($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_iid))); } /** * @param int $project_id - * @param int $issue_id + * @param int $issue_iid * @return mixed */ - public function showComments($project_id, $issue_id) + public function showComments($project_id, $issue_iid) { - return $this->get($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_id)).'/notes'); + return $this->get($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_iid)).'/notes'); } /** * @param int $project_id - * @param int $issue_id + * @param int $issue_iid * @param int $note_id * @return mixed */ - public function showComment($project_id, $issue_id, $note_id) + public function showComment($project_id, $issue_iid, $note_id) { - return $this->get($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_id)).'/notes/'.$this->encodePath($note_id)); + return $this->get($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_iid)).'/notes/'.$this->encodePath($note_id)); } /** * @param int $project_id - * @param int $issue_id + * @param int $issue_iid * @param string|array $body * @return mixed */ - public function addComment($project_id, $issue_id, $body) + public function addComment($project_id, $issue_iid, $body) { // backwards compatibility if (is_array($body)) { @@ -99,70 +99,70 @@ public function addComment($project_id, $issue_id, $body) $params = array('body' => $body); } - return $this->post($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_id).'/notes'), $params); + return $this->post($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_iid).'/notes'), $params); } /** * @param int $project_id - * @param int $issue_id + * @param int $issue_iid * @param int $note_id * @param string $body * @return mixed */ - public function updateComment($project_id, $issue_id, $note_id, $body) + public function updateComment($project_id, $issue_iid, $note_id, $body) { - return $this->put($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_id).'/notes/'.$this->encodePath($note_id)), array( + return $this->put($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_iid).'/notes/'.$this->encodePath($note_id)), array( 'body' => $body )); } /** * @param int $project_id - * @param int $issue_id + * @param int $issue_iid * @param int $note_id * @return mixed */ - public function removeComment($project_id, $issue_id, $note_id) + public function removeComment($project_id, $issue_iid, $note_id) { - return $this->delete($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_id).'/notes/'.$this->encodePath($note_id))); + return $this->delete($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_iid).'/notes/'.$this->encodePath($note_id))); } /** * @param int $project_id - * @param int $issue_id + * @param int $issue_iid * @param string $duration */ - public function setTimeEstimate($project_id, $issue_id, $duration) + public function setTimeEstimate($project_id, $issue_iid, $duration) { - return $this->post($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_id).'/time_estimate'), array('duration' => $duration)); + return $this->post($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_iid).'/time_estimate'), array('duration' => $duration)); } /** * @param int $project_id - * @param int $issue_id + * @param int $issue_iid */ - public function resetTimeEstimate($project_id, $issue_id) + public function resetTimeEstimate($project_id, $issue_iid) { - return $this->post($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_id).'/reset_time_estimate')); + return $this->post($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_iid).'/reset_time_estimate')); } /** * @param int $project_id - * @param int $issue_id + * @param int $issue_iid * @param string $duration */ - public function addSpentTime($project_id, $issue_id, $duration) + public function addSpentTime($project_id, $issue_iid, $duration) { - return $this->post($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_id).'/add_spent_time'), array('duration' => $duration)); + return $this->post($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_iid).'/add_spent_time'), array('duration' => $duration)); } /** * @param int $project_id - * @param int $issue_id + * @param int $issue_iid */ - public function resetSpentTime($project_id, $issue_id) + public function resetSpentTime($project_id, $issue_iid) { - return $this->post($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_id).'/reset_spent_time')); + return $this->post($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_iid).'/reset_spent_time')); } /** From 9b39f0ac7576de88bf7954e1de1f5dd52ea8c179 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 25 Jul 2017 13:31:34 +0200 Subject: [PATCH 32/83] replace visibility_level by visibility --- UPGRADE.md | 4 ++++ lib/Gitlab/Api/Groups.php | 5 +++-- test/Gitlab/Tests/Api/GroupsTest.php | 8 ++++---- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 3ac17720e..c88215b6f 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -13,6 +13,10 @@ See [documentation](doc/customize.md) to know how to customize the client timeou * The `setHttpClient` method have been removed. Use a `Gitlab\HttpClient\Builder` instead. * The `getHttpClient` method return type is changed to `Http\Client\Common\HttpMethodsClient`. +## `Gitlab\Api\Groups` changes + +* The `visibility_level` parameter have been removed from `create` method. Use `visibility` instead. + ## `Gitlab\Api\Projects` changes * The `keys`, `key`, `addKey`, `removeKey`, `disableKey` and `enableKey` methods have been removed. diff --git a/lib/Gitlab/Api/Groups.php b/lib/Gitlab/Api/Groups.php index 4ec574d64..ef98265e7 100644 --- a/lib/Gitlab/Api/Groups.php +++ b/lib/Gitlab/Api/Groups.php @@ -42,15 +42,16 @@ public function show($id) * @param string $name * @param string $path * @param string $description + * @param string $visibility * @return mixed */ - public function create($name, $path, $description = null, $visibility_level = 0) + public function create($name, $path, $description = null, $visibility = 'private') { return $this->post('groups', array( 'name' => $name, 'path' => $path, 'description' => $description, - 'visibility_level' => $visibility_level + 'visibility' => $visibility, )); } diff --git a/test/Gitlab/Tests/Api/GroupsTest.php b/test/Gitlab/Tests/Api/GroupsTest.php index a5fb478d2..00afe60eb 100644 --- a/test/Gitlab/Tests/Api/GroupsTest.php +++ b/test/Gitlab/Tests/Api/GroupsTest.php @@ -111,7 +111,7 @@ public function shouldCreateGroup() $api = $this->getApiMock(); $api->expects($this->once()) ->method('post') - ->with('groups', array('name' => 'A new group', 'path' => 'a-new-group', 'description' => null, 'visibility_level' => 0)) + ->with('groups', array('name' => 'A new group', 'path' => 'a-new-group', 'description' => null, 'visibility' => 'private')) ->will($this->returnValue($expectedArray)) ; @@ -121,18 +121,18 @@ public function shouldCreateGroup() /** * @test */ - public function shouldCreateGroupWithDescriptionAndVisLevel() + public function shouldCreateGroupWithDescriptionAndVisibility() { $expectedArray = array('id' => 1, 'name' => 'A new group', 'visibility_level' => 2); $api = $this->getApiMock(); $api->expects($this->once()) ->method('post') - ->with('groups', array('name' => 'A new group', 'path' => 'a-new-group', 'description' => 'Description', 'visibility_level' => 2)) + ->with('groups', array('name' => 'A new group', 'path' => 'a-new-group', 'description' => 'Description', 'visibility' => 'public')) ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->create('A new group', 'a-new-group', 'Description', 2)); + $this->assertEquals($expectedArray, $api->create('A new group', 'a-new-group', 'Description', 'public')); } /** From 07ec09964c725c99a48ac6ae607274588c92db35 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Wed, 19 Jul 2017 23:31:22 +0200 Subject: [PATCH 33/83] projects collection consolidation --- UPGRADE.md | 3 + composer.json | 3 +- lib/Gitlab/Api/AbstractApi.php | 24 +++++ lib/Gitlab/Api/Projects.php | 143 +++++++++++++------------ test/Gitlab/Tests/Api/ProjectsTest.php | 31 +++--- 5 files changed, 114 insertions(+), 90 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 3b9b13c8a..9382f44e9 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -27,6 +27,9 @@ See [documentation](doc/customize.md) to know how to customize the client timeou * The `keys`, `key`, `addKey`, `removeKey`, `disableKey` and `enableKey` methods have been removed. Use the `deployKeys`, `deployKey`, `addDeployKey`, `deleteDeployKey`, `removeDeployKey` and `enableDeployKey` instead. +* The `ORDER_BY` and `SORT` class constants have been removed. +* The `accessible`, `owned` and `search` methods have been removed. Use `all` method instead. +* The `all` method now take a single argument which is an associative array of query string parameters. ## `Gitlab\Api\Repositories` changes diff --git a/composer.json b/composer.json index ffb501948..fb4822b95 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,8 @@ "php-http/client-implementation": "^1.0", "php-http/discovery": "^1.2", "php-http/httplug": "^1.1", - "php-http/multipart-stream-builder": "^1.0" + "php-http/multipart-stream-builder": "^1.0", + "symfony/options-resolver": "^2.6 || ^3.0" }, "require-dev": { "guzzlehttp/psr7": "^1.2", diff --git a/lib/Gitlab/Api/AbstractApi.php b/lib/Gitlab/Api/AbstractApi.php index 7aab58d0e..b43a305b6 100644 --- a/lib/Gitlab/Api/AbstractApi.php +++ b/lib/Gitlab/Api/AbstractApi.php @@ -6,6 +6,7 @@ use Http\Message\MultipartStream\MultipartStreamBuilder; use Http\Message\StreamFactory; use Psr\Http\Message\ResponseInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; /** * Abstract class for Api classes @@ -190,6 +191,29 @@ protected function encodePath($path) return str_replace('.', '%2E', $path); } + /** + * Create a new OptionsResolver with page, per_page and sort options. + * + * @return OptionsResolver + */ + protected function createOptionsResolver() + { + $resolver = new OptionsResolver(); + $resolver->setDefined('page') + ->setAllowedTypes('page', 'int') + ->setAllowedValues('page', function ($value) { return $value > 0; }) + ; + $resolver->setDefined('per_page') + ->setAllowedTypes('per_page', 'int') + ->setAllowedValues('per_page', function ($value) { return $value > 0 && $value <= 100; }) + ; + $resolver->setDefined('sort') + ->setAllowedValues('sort', ['asc', 'desc']) + ; + + return $resolver; + } + private function preparePath($path, array $parameters = []) { if (count($parameters) > 0) { diff --git a/lib/Gitlab/Api/Projects.php b/lib/Gitlab/Api/Projects.php index d840d9a48..cafe8df5d 100644 --- a/lib/Gitlab/Api/Projects.php +++ b/lib/Gitlab/Api/Projects.php @@ -1,78 +1,81 @@ get('projects/all', array( - 'page' => $page, - 'per_page' => $per_page, - 'order_by' => $order_by, - 'sort' => $sort - )); - } - /** - * @param int $page - * @param int $per_page - * @param string $order_by - * @param string $sort - * @return mixed - */ - public function accessible($page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT) - { - return $this->get('projects', array( - 'page' => $page, - 'per_page' => $per_page, - 'order_by' => $order_by, - 'sort' => $sort - )); - } - - /** - * Get projects owned by the current user - * @param int $page - * @param int $per_page - * @param string $order_by - * @param string $sort - * @return mixed - */ - public function owned($page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT) - { - return $this->get('projects?owned=1', array( - 'page' => $page, - 'per_page' => $per_page, - 'order_by' => $order_by, - 'sort' => $sort - )); - } - - /** - * @param string $query - * @param int $page - * @param int $per_page - * @param string $order_by - * @param string $sort - * @return mixed - */ - public function search($query, $page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT) - { - return $this->get('projects/search/'.$this->encodePath($query), array( - 'page' => $page, - 'per_page' => $per_page, - 'order_by' => $order_by, - 'sort' => $sort - )); + * @param array $parameters { + * + * @var bool $archived Limit by archived status. + * @var string $visibility Limit by visibility public, internal, or private. + * @var string $order_by Return projects ordered by id, name, path, created_at, updated_at, + * or last_activity_at fields. Default is created_at. + * @var string $sort Return projects sorted in asc or desc order. Default is desc. + * @var string $search Return list of projects matching the search criteria. + * @var bool $simple Return only the ID, URL, name, and path of each project. + * @var bool $owned Limit by projects owned by the current user. + * @var bool $membership Limit by projects that the current user is a member of. + * @var bool $starred Limit by projects starred by the current user. + * @var bool $statistics Include project statistics. + * @var bool $with_issues_enabled Limit by enabled issues feature. + * @var bool $with_merge_requests_enabled Limit by enabled merge requests feature. + * } + * + * @throws UndefinedOptionsException If an option name is undefined + * @throws InvalidOptionsException If an option doesn't fulfill the + * specified validation rules + * + * @return mixed + */ + public function all(array $parameters = []) + { + $resolver = $this->createOptionsResolver(); + $booleanNormalizer = function ($value) { + return $value ? 'true' : 'false'; + }; + $resolver->setDefined('archived') + ->setAllowedTypes('archived', 'bool') + ->setNormalizer('archived', $booleanNormalizer) + ; + $resolver->setDefined('visibility') + ->setAllowedValues('visibility', ['public', 'internal', 'private']) + ; + $resolver->setDefined('order_by') + ->setAllowedValues('order_by', ['id', 'name', 'path', 'created_at', 'updated_at', 'last_activity_at']) + ; + $resolver->setDefined('search'); + $resolver->setDefined('simple') + ->setAllowedTypes('simple', 'bool') + ->setNormalizer('simple', $booleanNormalizer) + ; + $resolver->setDefined('owned') + ->setAllowedTypes('owned', 'bool') + ->setNormalizer('owned', $booleanNormalizer) + ; + $resolver->setDefined('membership') + ->setAllowedTypes('membership', 'bool') + ->setNormalizer('membership', $booleanNormalizer) + ; + $resolver->setDefined('starred') + ->setAllowedTypes('starred', 'bool') + ->setNormalizer('starred', $booleanNormalizer) + ; + $resolver->setDefined('statistics') + ->setAllowedTypes('statistics', 'bool') + ->setNormalizer('statistics', $booleanNormalizer) + ; + $resolver->setDefined('with_issues_enabled') + ->setAllowedTypes('with_issues_enabled', 'bool') + ->setNormalizer('with_issues_enabled', $booleanNormalizer) + ; + $resolver->setDefined('with_merge_requests_enabled') + ->setAllowedTypes('with_merge_requests_enabled', 'bool') + ->setNormalizer('with_merge_requests_enabled', $booleanNormalizer) + ; + + return $this->get('projects', $resolver->resolve($parameters)); } /** diff --git a/test/Gitlab/Tests/Api/ProjectsTest.php b/test/Gitlab/Tests/Api/ProjectsTest.php index 5c44b3835..85fb54084 100644 --- a/test/Gitlab/Tests/Api/ProjectsTest.php +++ b/test/Gitlab/Tests/Api/ProjectsTest.php @@ -12,7 +12,7 @@ public function shouldGetAllProjects() { $expectedArray = $this->getMultipleProjectsData(); - $api = $this->getMultipleProjectsRequestMock('projects/all', $expectedArray); + $api = $this->getMultipleProjectsRequestMock('projects', $expectedArray); $this->assertEquals($expectedArray, $api->all()); } @@ -24,9 +24,9 @@ public function shouldGetAllProjectsSortedByName() { $expectedArray = $this->getMultipleProjectsData(); - $api = $this->getMultipleProjectsRequestMock('projects/all', $expectedArray, 1, 5, 'name', 'asc'); + $api = $this->getMultipleProjectsRequestMock('projects', $expectedArray, ['page' => 1, 'per_page' => 5, 'order_by' => 'name', 'sort' => 'asc']); - $this->assertEquals($expectedArray, $api->all(1, 5, 'name')); + $this->assertEquals($expectedArray, $api->all(['page' => 1, 'per_page' => 5, 'order_by' => 'name', 'sort' => 'asc'])); } /** @@ -39,7 +39,7 @@ public function shouldNotNeedPaginationWhenGettingProjects() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/all', array('page' => 1, 'per_page' => AbstractApi::PER_PAGE, 'order_by' => Projects::ORDER_BY, 'sort' => Projects::SORT)) + ->with('projects') ->will($this->returnValue($expectedArray)) ; @@ -53,9 +53,9 @@ public function shouldGetAccessibleProjects() { $expectedArray = $this->getMultipleProjectsData(); - $api = $this->getMultipleProjectsRequestMock('projects', $expectedArray, 2, 7); + $api = $this->getMultipleProjectsRequestMock('projects', $expectedArray); - $this->assertEquals($expectedArray, $api->accessible(2, 7)); + $this->assertEquals($expectedArray, $api->all()); } /** @@ -65,12 +65,11 @@ public function shouldGetOwnedProjects() { $expectedArray = $this->getMultipleProjectsData(); - $api = $this->getMultipleProjectsRequestMock('projects?owned=1', $expectedArray, 3, 50); + $api = $this->getMultipleProjectsRequestMock('projects', $expectedArray, ['owned' => 'true']); - $this->assertEquals($expectedArray, $api->owned(3, 50)); + $this->assertEquals($expectedArray, $api->all(['owned' => true])); } - /** * @test */ @@ -78,14 +77,8 @@ public function shouldSearchProjects() { $expectedArray = $this->getMultipleProjectsData(); - $api = $this->getMultipleProjectsRequestMock('projects/search/a%20project', $expectedArray); - $this->assertEquals($expectedArray, $api->search('a project')); - - $api = $this->getMultipleProjectsRequestMock('projects/search/a%2Eproject', $expectedArray); - $this->assertEquals($expectedArray, $api->search('a.project')); - - $api = $this->getMultipleProjectsRequestMock('projects/search/a%2Fproject', $expectedArray); - $this->assertEquals($expectedArray, $api->search('a/project')); + $api = $this->getMultipleProjectsRequestMock('projects', $expectedArray, ['search' => 'a project']); + $this->assertEquals($expectedArray, $api->all(['search' => 'a project'])); } /** @@ -1008,12 +1001,12 @@ public function shouldRemoveVariable() $this->assertEquals($expectedBool, $api->removeVariable(1, 'ftp_password')); } - protected function getMultipleProjectsRequestMock($path, $expectedArray = array(), $page = 1, $per_page = 20, $order_by = 'created_at', $sort = 'asc') + protected function getMultipleProjectsRequestMock($path, $expectedArray = array(), $expectedParameters = array()) { $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with($path, array('page' => $page, 'per_page' => $per_page, 'order_by' => $order_by, 'sort' => $sort)) + ->with($path, $expectedParameters) ->will($this->returnValue($expectedArray)) ; From c267c413f4f7f58d851bfe568de469d0f569feee Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 25 Jul 2017 13:40:07 +0200 Subject: [PATCH 34/83] replace merge_request endpoint by merge_requests --- lib/Gitlab/Api/MergeRequests.php | 16 ++++++++-------- test/Gitlab/Tests/Api/MergeRequestsTest.php | 14 +++++++------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/Gitlab/Api/MergeRequests.php b/lib/Gitlab/Api/MergeRequests.php index ce3e08390..abe842fdb 100644 --- a/lib/Gitlab/Api/MergeRequests.php +++ b/lib/Gitlab/Api/MergeRequests.php @@ -90,7 +90,7 @@ public function closed($project_id, $page = 1, $per_page = self::PER_PAGE, $orde */ public function show($project_id, $mr_id) { - return $this->get($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id))); + return $this->get($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id))); } /** @@ -123,7 +123,7 @@ public function create($project_id, $source, $target, $title, $assignee = null, */ public function update($project_id, $mr_id, array $params) { - return $this->put($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id)), $params); + return $this->put($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id)), $params); } /** @@ -140,7 +140,7 @@ public function merge($project_id, $mr_id, $message = null) $params = array('merge_commit_message' => $message); } - return $this->put($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/merge'), $params); + return $this->put($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/merge'), $params); } /** @@ -173,7 +173,7 @@ public function addNote($project_id, $mr_id, $note) */ public function showComments($project_id, $mr_id) { - return $this->get($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/comments')); + return $this->get($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/comments')); } /** @@ -184,7 +184,7 @@ public function showComments($project_id, $mr_id) */ public function addComment($project_id, $mr_id, $note) { - return $this->post($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/comments'), array( + return $this->post($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/comments'), array( 'note' => $note )); } @@ -196,7 +196,7 @@ public function addComment($project_id, $mr_id, $note) */ public function changes($project_id, $mr_id) { - return $this->get($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/changes')); + return $this->get($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/changes')); } /** @@ -216,7 +216,7 @@ public function getByIid($project_id, $mr_iid) */ public function commits($project_id, $mr_id) { - return $this->get($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/commits')); + return $this->get($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/commits')); } /** @@ -226,7 +226,7 @@ public function commits($project_id, $mr_id) */ public function closesIssues($project_id, $mr_id) { - return $this->get($this->getProjectPath($project_id, 'merge_request/'.$this->encodePath($mr_id).'/closes_issues')); + return $this->get($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/closes_issues')); } /** diff --git a/test/Gitlab/Tests/Api/MergeRequestsTest.php b/test/Gitlab/Tests/Api/MergeRequestsTest.php index 8901f0de2..8ae41450c 100644 --- a/test/Gitlab/Tests/Api/MergeRequestsTest.php +++ b/test/Gitlab/Tests/Api/MergeRequestsTest.php @@ -168,7 +168,7 @@ public function shouldShowMergeRequest() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/merge_request/2') + ->with('projects/1/merge_requests/2') ->will($this->returnValue($expectedArray)) ; @@ -233,7 +233,7 @@ public function shouldUpdateMergeRequest() $api = $this->getApiMock(); $api->expects($this->once()) ->method('put') - ->with('projects/1/merge_request/2', array('title' => 'Updated title', 'description' => 'No so many changes now', 'state_event' => 'close')) + ->with('projects/1/merge_requests/2', array('title' => 'Updated title', 'description' => 'No so many changes now', 'state_event' => 'close')) ->will($this->returnValue($expectedArray)) ; @@ -254,7 +254,7 @@ public function shouldMergeMergeRequest() $api = $this->getApiMock(); $api->expects($this->exactly(2)) ->method('put') - ->with('projects/1/merge_request/2/merge', array('merge_commit_message' => 'Accepted')) + ->with('projects/1/merge_requests/2/merge', array('merge_commit_message' => 'Accepted')) ->will($this->returnValue($expectedArray)) ; @@ -295,7 +295,7 @@ public function shouldGetMergeRequestComments() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/merge_request/2/comments') + ->with('projects/1/merge_requests/2/comments') ->will($this->returnValue($expectedArray)) ; @@ -312,7 +312,7 @@ public function shouldAddMergeRequestComment() $api = $this->getApiMock(); $api->expects($this->once()) ->method('post') - ->with('projects/1/merge_request/2/comments', array('note' => 'A comment')) + ->with('projects/1/merge_requests/2/comments', array('note' => 'A comment')) ->will($this->returnValue($expectedArray)) ; @@ -329,7 +329,7 @@ public function shouldGetMergeRequestChanges() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/merge_request/2/changes') + ->with('projects/1/merge_requests/2/changes') ->will($this->returnValue($expectedArray)) ; @@ -347,7 +347,7 @@ public function shouldGetIssuesClosedByMergeRequest() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/merge_request/2/closes_issues') + ->with('projects/1/merge_requests/2/closes_issues') ->will($this->returnValue($expectedArray)) ; From dcbc960d33d01c3e40ef05f79b22071512174428 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Wed, 26 Jul 2017 23:28:42 +0200 Subject: [PATCH 35/83] remove getList method for MergeRequests api --- UPGRADE.md | 4 ++++ lib/Gitlab/Api/MergeRequests.php | 21 --------------------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 9382f44e9..e8d81da00 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -23,6 +23,10 @@ See [documentation](doc/customize.md) to know how to customize the client timeou * The second argument of `update`, `remove`, `showComments`, `showComment`, `addComment`, `updateComment`, `removeComment`, `setTimeEstimate`, `resetTimeEstimate`, `addSpentTime` and `resetSpentTime` methods is now a scoped issue id (iid). +## `Gitlab\Api\MergeRequests` changes + +* The `getList` method have been removed. Use `all` instead. + ## `Gitlab\Api\Projects` changes * The `keys`, `key`, `addKey`, `removeKey`, `disableKey` and `enableKey` methods have been removed. diff --git a/lib/Gitlab/Api/MergeRequests.php b/lib/Gitlab/Api/MergeRequests.php index abe842fdb..470019860 100644 --- a/lib/Gitlab/Api/MergeRequests.php +++ b/lib/Gitlab/Api/MergeRequests.php @@ -10,27 +10,6 @@ class MergeRequests extends AbstractApi const ORDER_BY = 'created_at'; const SORT = 'asc'; - /** - * @param int $project_id - * @param string $state - * @param int $page - * @param int $per_page - * @param string $order_by - * @param string $sort - * @param string $object - * @return mixed - */ - public function getList($project_id, $state = self::STATE_ALL, $page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT, $object = 'merge_requests') - { - return $this->get($this->getProjectPath($project_id, $object), array( - 'page' => $page, - 'per_page' => $per_page, - 'state' => $state, - 'order_by' => $order_by, - 'sort' => $sort - )); - } - /** * @param int $project_id * @param int $page From e6311d89e778e7ffb4375be75c523e95877c8b6c Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Mon, 31 Jul 2017 13:24:32 +0200 Subject: [PATCH 36/83] update merge requests api for v4 api --- UPGRADE.md | 5 +- lib/Gitlab/Api/AbstractApi.php | 5 +- lib/Gitlab/Api/MergeRequests.php | 125 ++++++++-------- .../HttpClient/Message/QueryStringBuilder.php | 60 ++++++++ test/Gitlab/Tests/Api/MergeRequestsTest.php | 139 ++---------------- .../Message/QueryStringBuilderTest.php | 89 +++++++++++ 6 files changed, 228 insertions(+), 195 deletions(-) create mode 100644 lib/Gitlab/HttpClient/Message/QueryStringBuilder.php create mode 100644 test/Gitlab/Tests/HttpClient/Message/QueryStringBuilderTest.php diff --git a/UPGRADE.md b/UPGRADE.md index e8d81da00..8cd93652d 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -25,7 +25,10 @@ See [documentation](doc/customize.md) to know how to customize the client timeou ## `Gitlab\Api\MergeRequests` changes -* The `getList` method have been removed. Use `all` instead. +* The `getList`, `getByIid`, `merged`, `opened` and `closed` methods have been removed. Use `all` method instead. +* The `ORDER_BY` and `SORT` class constants have been removed. +* The `all` method now take a single argument which is an associative array of query string parameters. +* The `getNotes` method now take only two arguments, the project id and the merge request iid. ## `Gitlab\Api\Projects` changes diff --git a/lib/Gitlab/Api/AbstractApi.php b/lib/Gitlab/Api/AbstractApi.php index b43a305b6..60681a529 100644 --- a/lib/Gitlab/Api/AbstractApi.php +++ b/lib/Gitlab/Api/AbstractApi.php @@ -1,7 +1,9 @@ 0) { - $path .= '?'.http_build_query($parameters); + $path .= '?'.QueryStringBuilder::build($parameters); } return $path; diff --git a/lib/Gitlab/Api/MergeRequests.php b/lib/Gitlab/Api/MergeRequests.php index 470019860..b7e857dce 100644 --- a/lib/Gitlab/Api/MergeRequests.php +++ b/lib/Gitlab/Api/MergeRequests.php @@ -1,5 +1,8 @@ getList($project_id, self::STATE_ALL, $page, $per_page, $order_by, $sort); - } - /** - * @param int $project_id - * @param int $page - * @param int $per_page - * @param string $order_by - * @param string $sort - * @return mixed - */ - public function merged($project_id, $page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT) - { - return $this->getList($project_id, self::STATE_MERGED, $page, $per_page, $order_by, $sort); - } - - /** - * @param int $project_id - * @param int $page - * @param int $per_page - * @param string $order_by - * @param string $sort - * @return mixed - */ - public function opened($project_id, $page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT) - { - return $this->getList($project_id, self::STATE_OPENED, $page, $per_page, $order_by, $sort); - } - - /** - * @param int $project_id - * @param int $page - * @param int $per_page - * @param string $order_by - * @param string $sort + * @param int $project_id + * @param array $parameters { + * + * @var int[] $iids Return the request having the given iid. + * @var string $state Return all merge requests or just those that are opened, closed, or + * merged. + * @var string $order_by Return requests ordered by created_at or updated_at fields. Default + * is created_at. + * @var string $sort Return requests sorted in asc or desc order. Default is desc. + * @var string $milestone Return merge requests for a specific milestone. + * @var string $view If simple, returns the iid, URL, title, description, and basic state + * of merge request. + * @var string $labels Return merge requests matching a comma separated list of labels. + * @var \DateTimeInterface $created_after Return merge requests created after the given time (inclusive). + * @var \DateTimeInterface $created_before Return merge requests created before the given time (inclusive). + * } + * + * @throws UndefinedOptionsException If an option name is undefined. + * @throws InvalidOptionsException If an option doesn't fulfill the specified validation rules. + * * @return mixed */ - public function closed($project_id, $page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT) - { - return $this->getList($project_id, self::STATE_CLOSED, $page, $per_page, $order_by, $sort); + public function all($project_id, array $parameters = []) + { + $resolver = $this->createOptionsResolver(); + $datetimeNormalizer = function (\DateTimeInterface $value) { + return $value->format('c'); + }; + $resolver->setDefined('iids') + ->setAllowedTypes('iids', 'array') + ->setAllowedValues('iids', function (array $value) { + return count($value) == count(array_filter($value, 'is_int')); + }) + ; + $resolver->setDefined('state') + ->setAllowedValues('state', ['all', 'opened', 'merged', 'closed']) + ; + $resolver->setDefined('order_by') + ->setAllowedValues('order_by', ['created_at', 'updated_at']) + ; + $resolver->setDefined('milestone'); + $resolver->setDefined('view') + ->setAllowedValues('view', ['simple']) + ; + $resolver->setDefined('labels'); + $resolver->setDefined('created_after') + ->setAllowedTypes('created_after', \DateTimeInterface::class) + ->setNormalizer('created_after', $datetimeNormalizer) + ; + $resolver->setDefined('created_before') + ->setAllowedTypes('created_before', \DateTimeInterface::class) + ->setNormalizer('created_before', $datetimeNormalizer) + ; + + return $this->get($this->getProjectPath($project_id, 'merge_requests'), $resolver->resolve($parameters)); } /** @@ -123,13 +129,14 @@ public function merge($project_id, $mr_id, $message = null) } /** - * @param int $project_id - * @param int $mr_id + * @param int $project_id + * @param int $mr_id + * * @return mixed */ - public function showNotes($project_id, $mr_id, $page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = 'desc') + public function showNotes($project_id, $mr_id) { - return $this->getList($project_id, null, $page, $per_page, $order_by, $sort, 'merge_requests/'.$this->encodePath($mr_id).'/notes'); + return $this->get($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/notes')); } /** @@ -178,16 +185,6 @@ public function changes($project_id, $mr_id) return $this->get($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/changes')); } - /** - * @param $project_id - * @param $mr_iid - * @return mixed - */ - public function getByIid($project_id, $mr_iid) - { - return $this->get($this->getProjectPath($project_id, 'merge_requests'), array('iid' => $mr_iid)); - } - /** * @param int $project_id * @param int $mr_id diff --git a/lib/Gitlab/HttpClient/Message/QueryStringBuilder.php b/lib/Gitlab/HttpClient/Message/QueryStringBuilder.php new file mode 100644 index 000000000..b916d29d5 --- /dev/null +++ b/lib/Gitlab/HttpClient/Message/QueryStringBuilder.php @@ -0,0 +1,60 @@ +getMultipleMergeRequestsData(); $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/merge_requests', array('page' => 1, 'per_page' => AbstractApi::PER_PAGE, 'state' => MergeRequests::STATE_ALL, 'order_by' => MergeRequests::ORDER_BY, 'sort' => MergeRequests::SORT)) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->getList(1)); - } - - /** - * @test - */ - public function shouldGetAll() - { - $expectedArray = $this->getMultipleMergeRequestsData(); - - $api = $this->getApiMock(array('getList')); - $api->expects($this->once()) - ->method('getList') - ->with(1, MergeRequests::STATE_ALL, 1, AbstractApi::PER_PAGE, MergeRequests::ORDER_BY, MergeRequests::SORT) + ->with('projects/1/merge_requests', array()) ->will($this->returnValue($expectedArray)) ; @@ -46,116 +29,14 @@ public function shouldGetAllWithParams() { $expectedArray = $this->getMultipleMergeRequestsData(); - $api = $this->getApiMock(array('getList')); - $api->expects($this->once()) - ->method('getList') - ->with(1, MergeRequests::STATE_ALL, 2, 5, 'title', 'desc') - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->all(1, 2, 5, 'title', 'desc')); - } - - /** - * @test - */ - public function shouldGetMerged() - { - $expectedArray = $this->getMultipleMergeRequestsData(); - - $api = $this->getApiMock(array('getList')); - $api->expects($this->once()) - ->method('getList') - ->with(1, MergeRequests::STATE_MERGED, 1, AbstractApi::PER_PAGE, MergeRequests::ORDER_BY, MergeRequests::SORT) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->merged(1)); - } - - /** - * @test - */ - public function shouldGetMergedWithParams() - { - $expectedArray = $this->getMultipleMergeRequestsData(); - - $api = $this->getApiMock(array('getList')); - $api->expects($this->once()) - ->method('getList') - ->with(1, MergeRequests::STATE_MERGED, 3, 15, 'updated_at', 'asc') - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->merged(1, 3, 15, 'updated_at', 'asc')); - } - - /** - * @test - */ - public function shouldGetOpened() - { - $expectedArray = $this->getMultipleMergeRequestsData(); - - $api = $this->getApiMock(array('getList')); - $api->expects($this->once()) - ->method('getList') - ->with(1, MergeRequests::STATE_OPENED, 1, AbstractApi::PER_PAGE, MergeRequests::ORDER_BY, MergeRequests::SORT) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->opened(1)); - } - - /** - * @test - */ - public function shouldGetOpenedWithParams() - { - $expectedArray = $this->getMultipleMergeRequestsData(); - - $api = $this->getApiMock(array('getList')); - $api->expects($this->once()) - ->method('getList') - ->with(1, MergeRequests::STATE_OPENED, 2, 4, 'title', 'desc') - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->opened(1, 2, 4, 'title', 'desc')); - } - - /** - * @test - */ - public function shouldGetClosed() - { - $expectedArray = $this->getMultipleMergeRequestsData(); - - $api = $this->getApiMock(array('getList')); - $api->expects($this->once()) - ->method('getList') - ->with(1, MergeRequests::STATE_CLOSED, 1, AbstractApi::PER_PAGE, MergeRequests::ORDER_BY, MergeRequests::SORT) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->closed(1)); - } - - /** - * @test - */ - public function shouldGetClosedWithParams() - { - $expectedArray = $this->getMultipleMergeRequestsData(); - - $api = $this->getApiMock(array('getList')); + $api = $this->getApiMock(); $api->expects($this->once()) - ->method('getList') - ->with(1, MergeRequests::STATE_CLOSED, 2, 4, 'title', 'desc') + ->method('get') + ->with('projects/1/merge_requests', ['page' => 2, 'per_page' => 5, 'order_by' => 'updated_at', 'sort' => 'desc']) ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->closed(1, 2, 4, 'title', 'desc')); + $this->assertEquals($expectedArray, $api->all(1, ['page' => 2, 'per_page' => 5, 'order_by' => 'updated_at', 'sort' => 'desc'])); } /** @@ -364,11 +245,11 @@ public function shouldGetMergeRequestByIid() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/merge_requests', array('iid' => 2)) + ->with('projects/1/merge_requests', array('iids' => [2])) ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->getByIid(1, 2)); + $this->assertEquals($expectedArray, $api->all(1, ['iids' => [2]])); } /** @@ -415,11 +296,11 @@ public function shouldGetMergeRequestApprovals() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/merge_requests', array('iid' => 2)) + ->with('projects/1/merge_requests', array('iids' => [2])) ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->getByIid(1, 2)); + $this->assertEquals($expectedArray, $api->all(1, ['iids' => [2]])); } diff --git a/test/Gitlab/Tests/HttpClient/Message/QueryStringBuilderTest.php b/test/Gitlab/Tests/HttpClient/Message/QueryStringBuilderTest.php new file mode 100644 index 000000000..db563cdce --- /dev/null +++ b/test/Gitlab/Tests/HttpClient/Message/QueryStringBuilderTest.php @@ -0,0 +1,89 @@ +assertEquals($expected, QueryStringBuilder::build($query)); + } + + public function queryStringProvider() + { + //Scalar value. + yield [ + 'a project', + 'a%20project', + ]; + + //Indexed array. + yield [ + ['iids' => [88, 86]], + //iids[]=88&iids[]=86 + 'iids%5B%5D=88&iids%5B%5D=86', + ]; + + //Non indexed array with only numeric keys. + yield [ + ['iids' => [0 => 88, 2 => 86]], + //iids[0]=88&iids[2]=86 + 'iids%5B0%5D=88&iids%5B2%5D=86' + ]; + + //A deeply nested array. + yield [ + [ + 'search' => 'a project', + 'owned' => 'true', + 'iids' => [88, 86], + 'assoc' => [ + 'a' => 'b', + 'c' => [ + 'd' => 'e', + 'f' => 'g', + ], + ], + 'nested' => [ + 'a' => [ + [ + 'b' => 'c', + ], + [ + 'd' => 'e', + 'f' => [ + 'g' => 'h', + 'i' => 'j', + 'k' => [87, 89], + ], + ], + ], + ], + ], + //search=a project + //&owned=true + //&iids[]=88&iids[]=86 + //&assoc[a]=b&assoc[c][d]=e&assoc[c][f]=g + //&nested[a][][b]=c&nested[a][][d]=e + //&nested[a][][f][g]=h&nested[a][][f][i]=j + //&nested[a][][f][k][]=87&nested[a][][f][k][]=89 + 'search=a%20project'. + '&owned=true'. + '&iids%5B%5D=88&iids%5B%5D=86'. + '&assoc%5Ba%5D=b&assoc%5Bc%5D%5Bd%5D=e&assoc%5Bc%5D%5Bf%5D=g'. + '&nested%5Ba%5D%5B%5D%5Bb%5D=c&nested%5Ba%5D%5B%5D%5Bd%5D=e'. + '&nested%5Ba%5D%5B%5D%5Bf%5D%5Bg%5D=h&nested%5Ba%5D%5B%5D%5Bf%5D%5Bi%5D=j'. + '&nested%5Ba%5D%5B%5D%5Bf%5D%5Bk%5D%5B%5D=87&nested%5Ba%5D%5B%5D%5Bf%5D%5Bk%5D%5B%5D=89' + , + ]; + } +} From f317387d6e287ac836e5cd2df24a5c68c0ff8fef Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Mon, 31 Jul 2017 17:02:29 +0200 Subject: [PATCH 37/83] remove build related methods in projects api --- UPGRADE.md | 3 + lib/Gitlab/Api/Projects.php | 32 --------- test/Gitlab/Tests/Api/ProjectsTest.php | 93 -------------------------- 3 files changed, 3 insertions(+), 125 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 9382f44e9..27321767a 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -30,6 +30,9 @@ Use the `deployKeys`, `deployKey`, `addDeployKey`, `deleteDeployKey`, `removeDep * The `ORDER_BY` and `SORT` class constants have been removed. * The `accessible`, `owned` and `search` methods have been removed. Use `all` method instead. * The `all` method now take a single argument which is an associative array of query string parameters. +* The `trace` method have been removed. Use `Gitlab\Api\Jobs::trace` instead. +* The `builds` method have been removed. Use `Gitlab\Api\Jobs::all` instead. +* The `build` method have been removed. Use `Gitlab\Api\Jobs::show` instead. ## `Gitlab\Api\Repositories` changes diff --git a/lib/Gitlab/Api/Projects.php b/lib/Gitlab/Api/Projects.php index cafe8df5d..292960cc9 100644 --- a/lib/Gitlab/Api/Projects.php +++ b/lib/Gitlab/Api/Projects.php @@ -147,38 +147,6 @@ public function unarchive($project_id){ return $this->post("projects/".$this->encodePath($project_id)."/unarchive"); } - /** - * @param int $project_id - * @param array $scope - * @return mixed - */ - public function builds($project_id, $scope = null) - { - return $this->get($this->getProjectPath($project_id, 'builds'), array( - 'scope' => $scope - )); - } - - /** - * @param int $project_id - * @param int $build_id - * @return mixed - */ - public function build($project_id, $build_id) - { - return $this->get($this->getProjectPath($project_id, 'builds/'.$this->encodePath($build_id))); - } - - /** - * @param int $project_id - * @param int $build_id - * @return mixed - */ - public function trace($project_id, $build_id) - { - return $this->get($this->getProjectPath($project_id, 'builds/'.$this->encodePath($build_id).'/trace')); - } - /** * @param int $project_id * @return mixed diff --git a/test/Gitlab/Tests/Api/ProjectsTest.php b/test/Gitlab/Tests/Api/ProjectsTest.php index 85fb54084..66d09b837 100644 --- a/test/Gitlab/Tests/Api/ProjectsTest.php +++ b/test/Gitlab/Tests/Api/ProjectsTest.php @@ -207,99 +207,6 @@ public function shouldRemoveProject() $this->assertEquals($expectedBool, $api->remove(1)); } - /** - * @test - */ - public function shouldGetBuilds() - { - $expectedArray = array( - array('id' => 1, 'status' => 'success'), - array('id' => 2, 'status' => 'failed') - ); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('projects/1/builds') - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->builds(1)); - } - - /** - * @test - */ - public function shouldGetBuildsWithScope() - { - $expectedArray = array( - array('id' => 1, 'status' => 'success'), - ); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('projects/1/builds', array('scope' => 'success')) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->builds(1, 'success')); - } - - /** - * @test - */ - public function shouldGetBuildsWithMultipleScopes() - { - $expectedArray = array( - array('id' => 1, 'status' => 'success'), - array('id' => 1, 'status' => 'failed'), - ); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('projects/1/builds', array('scope' => array('success', 'failed'))) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->builds(1, array('success', 'failed'))); - } - - /** - * @test - */ - public function shouldGetBuild() - { - $expectedArray = array('id' => 2); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('projects/1/builds/2') - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->build(1, 2)); - } - - /** - * @test - */ - public function shouldGetTrace() - { - $expectedString = 'runner trace of a specific build'; - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('projects/1/builds/2/trace') - ->will($this->returnValue($expectedString)) - ; - - $this->assertEquals($expectedString, $api->trace(1, 2)); - } - /** * @test */ From d7db5ab8529894de58802e0114a9d939bfa532bd Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Mon, 31 Jul 2017 17:08:22 +0200 Subject: [PATCH 38/83] remove remaining build references --- UPGRADE.md | 1 + lib/Gitlab/Api/Projects.php | 39 +++++++++++++++++++-- lib/Gitlab/Api/Repositories.php | 18 ---------- lib/Gitlab/Model/ProjectHook.php | 4 +-- test/Gitlab/Tests/Api/RepositoriesTest.php | 40 ---------------------- 5 files changed, 39 insertions(+), 63 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 27321767a..566f972b4 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -37,6 +37,7 @@ Use the `deployKeys`, `deployKey`, `addDeployKey`, `deleteDeployKey`, `removeDep ## `Gitlab\Api\Repositories` changes * The `commits` page argument now start from 1 instead of 0. +* The `commitBuilds` method have been removed. Use `Gitlab\Api\Projects::pipelines` instead. ## `Gitlab\Model\Project` changes diff --git a/lib/Gitlab/Api/Projects.php b/lib/Gitlab/Api/Projects.php index 292960cc9..6dd422c59 100644 --- a/lib/Gitlab/Api/Projects.php +++ b/lib/Gitlab/Api/Projects.php @@ -148,12 +148,45 @@ public function unarchive($project_id){ } /** - * @param int $project_id + * @param int $project_id + * @param array $parameters ( + * + * @var string $scope The scope of pipelines, one of: running, pending, finished, branches, tags. + * @var string $status The status of pipelines, one of: running, pending, success, failed, canceled, skipped. + * @var string $ref The ref of pipelines. + * @var bool $yaml_errors Returns pipelines with invalid configurations. + * @var string $name The name of the user who triggered pipelines. + * @var string $username The username of the user who triggered pipelines. + * @var string $order_by Order pipelines by id, status, ref, or user_id (default: id). + * @var string $order Sort pipelines in asc or desc order (default: desc). + * ) * @return mixed */ - public function pipelines($project_id) + public function pipelines($project_id, array $parameters = []) { - return $this->get($this->getProjectPath($project_id, 'pipelines')); + $resolver = $this->createOptionsResolver(); + $booleanNormalizer = function ($value) { + return $value ? 'true' : 'false'; + }; + + $resolver->setDefined('scope') + ->setAllowedValues('scope', ['running', 'pending', 'finished', 'branches', 'tags']) + ; + $resolver->setDefined('status') + ->setAllowedValues('status', ['running', 'pending', 'success', 'failed', 'canceled', 'skipped']) + ; + $resolver->setDefined('ref'); + $resolver->setDefined('yaml_errors') + ->setAllowedTypes('yaml_errors', 'bool') + ->setNormalizer('yaml_errors', $booleanNormalizer) + ; + $resolver->setDefined('name'); + $resolver->setDefined('username'); + $resolver->setDefined('order_by') + ->setAllowedValues('order_by', ['id', 'status', 'ref', 'user_id']) + ; + + return $this->get($this->getProjectPath($project_id, 'pipelines'), $resolver->resolve($parameters)); } /** diff --git a/lib/Gitlab/Api/Repositories.php b/lib/Gitlab/Api/Repositories.php index b694ad1e9..312894ba3 100644 --- a/lib/Gitlab/Api/Repositories.php +++ b/lib/Gitlab/Api/Repositories.php @@ -125,24 +125,6 @@ public function updateRelease( $project_id, $tag_name, $description ) { ) ); } - /** - * @param int $project_id - * @param string $sha - * @param string $scope - * @param int $page - * @param int $per_page - * - * @return mixed - */ - public function commitBuilds($project_id, $sha, $scope = null, $page = 0, $per_page = self::PER_PAGE) - { - return $this->get($this->getProjectPath($project_id, 'repository/commits/'.$this->encodePath($sha).'/builds'), array( - 'page' => $page, - 'per_page' => $per_page, - 'scope' => $scope - )); - } - /** * @param int $project_id * @param int $page diff --git a/lib/Gitlab/Model/ProjectHook.php b/lib/Gitlab/Model/ProjectHook.php index 3da0a7c02..7805ac6a1 100644 --- a/lib/Gitlab/Model/ProjectHook.php +++ b/lib/Gitlab/Model/ProjectHook.php @@ -11,7 +11,7 @@ * @property-read bool $push_events * @property-read bool $issues_events * @property-read bool $merge_requests_events - * @property-read bool $build_events + * @property-read bool $job_events * @property-read bool $tag_push_events * @property-read string $created_at * @property-read Project $project @@ -29,7 +29,7 @@ class ProjectHook extends AbstractModel 'push_events', 'issues_events', 'merge_requests_events', - 'build_events', + 'job_events', 'tag_push_events', 'created_at' ); diff --git a/test/Gitlab/Tests/Api/RepositoriesTest.php b/test/Gitlab/Tests/Api/RepositoriesTest.php index f37316c29..95c52fab8 100644 --- a/test/Gitlab/Tests/Api/RepositoriesTest.php +++ b/test/Gitlab/Tests/Api/RepositoriesTest.php @@ -235,46 +235,6 @@ public function shouldGetCommits() $this->assertEquals($expectedArray, $api->commits(1)); } - /** - * @test - */ - public function shouldGetCommitBuilds() - { - $expectedArray = array( - array('id' => 'abcd1234', 'status' => 'failed'), - array('id' => 'efgh5678', 'status' => 'success') - ); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('projects/1/repository/commits/abcd12345/builds', array('page' => 0, 'per_page' => AbstractApi::PER_PAGE, 'scope' => null)) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->commitBuilds(1, 'abcd12345')); - } - - /** - * @test - */ - public function shouldGetCommitBuildsWithScope() - { - $expectedArray = array( - array('id' => 'abcd1234', 'status' => 'success'), - ); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('projects/1/repository/commits/abcd12345/builds', array('page' => 0, 'per_page' => AbstractApi::PER_PAGE, 'scope' => 'success')) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->commitBuilds(1, 'abcd12345', 'success')); - } - - /** * @test */ From d97fe4e65e3de6a1e350ff9e6aafaf95462b8379 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Wed, 2 Aug 2017 12:11:52 +0200 Subject: [PATCH 39/83] fix phpstan level 4 errors --- lib/Gitlab/Api/IssueBoards.php | 10 +- lib/Gitlab/Api/Users.php | 8 ++ lib/Gitlab/Client.php | 167 ++++++++++++++++++++++++------ lib/Gitlab/HttpClient/Builder.php | 2 +- lib/Gitlab/Model/Branch.php | 14 +-- lib/Gitlab/Model/Group.php | 14 +-- lib/Gitlab/Model/Hook.php | 6 +- lib/Gitlab/Model/Issue.php | 8 +- lib/Gitlab/Model/MergeRequest.php | 12 +-- lib/Gitlab/Model/Milestone.php | 6 +- lib/Gitlab/Model/Pipeline.php | 2 +- lib/Gitlab/Model/Project.php | 119 +++++++++++---------- lib/Gitlab/Model/ProjectHook.php | 6 +- lib/Gitlab/Model/Session.php | 6 +- lib/Gitlab/Model/Snippet.php | 8 +- lib/Gitlab/Model/User.php | 20 ++-- 16 files changed, 259 insertions(+), 149 deletions(-) diff --git a/lib/Gitlab/Api/IssueBoards.php b/lib/Gitlab/Api/IssueBoards.php index d00c5a369..1790f5d34 100644 --- a/lib/Gitlab/Api/IssueBoards.php +++ b/lib/Gitlab/Api/IssueBoards.php @@ -63,16 +63,16 @@ public function createList($project_id, $board_id, $label_id) /** * @param int $project_id * @param int $board_id - * @param int $label_id + * @param int $list_id * @param int $position * @return mixed */ - public function updateList($project_id, $board_id, $label_id, $position) + public function updateList($project_id, $board_id, $list_id, $position) { $params = array( 'id' => $project_id, 'board_id' => $board_id, - 'label_id' => $label_id, + 'list_id' => $list_id, 'position' => $position ); @@ -82,10 +82,10 @@ public function updateList($project_id, $board_id, $label_id, $position) /** * @param int $project_id * @param int $board_id - * @param int $label_id + * @param int $list_id * @return mixed */ - public function deleteList($project_id, $board_id, $label_id) + public function deleteList($project_id, $board_id, $list_id) { return $this->delete($this->getProjectPath($project_id, 'boards/'.$this->encodePath($board_id).'/lists/'.$this->encodePath($list_id))); } diff --git a/lib/Gitlab/Api/Users.php b/lib/Gitlab/Api/Users.php index e72f96596..87f0bec5c 100644 --- a/lib/Gitlab/Api/Users.php +++ b/lib/Gitlab/Api/Users.php @@ -54,6 +54,14 @@ public function show($id) return $this->get('users/'.$this->encodePath($id)); } + /** + * @return mixed + */ + public function user() + { + return $this->get('user'); + } + /** * @param string $email * @param string $password diff --git a/lib/Gitlab/Client.php b/lib/Gitlab/Client.php index bfb3e01c6..e0e10e651 100644 --- a/lib/Gitlab/Client.php +++ b/lib/Gitlab/Client.php @@ -117,6 +117,126 @@ public static function createWithHttpClient(HttpClient $httpClient) return new self($builder); } + /** + * @return Api\DeployKeys + */ + public function deployKeys() + { + return new Api\DeployKeys($this); + } + + /** + * @return Api\Groups + */ + public function groups() + { + return new Api\Groups($this); + } + + /** + * @return Api\Issues + */ + public function issues() + { + return new Api\Issues($this); + } + + /** + * @return Api\IssueBoards + */ + public function issueBoards() + { + return new Api\IssueBoards($this); + } + + /** + * @return Api\Jobs + */ + public function jobs() + { + return new Api\Jobs($this); + } + + /** + * @return Api\MergeRequests + */ + public function mergeRequests() + { + return new Api\MergeRequests($this); + } + + /** + * @return Api\Milestones + */ + public function milestones() + { + return new Api\Milestones($this); + } + + /** + * @return Api\ProjectNamespaces + */ + public function namespaces() + { + return new Api\ProjectNamespaces($this); + } + + /** + * @return Api\Projects + */ + public function projects() + { + return new Api\Projects($this); + } + + /** + * @return Api\Repositories + */ + public function repositories() + { + return new Api\Repositories($this); + } + + /** + * @return Api\Snippets + */ + public function snippets() + { + return new Api\Snippets($this); + } + + /** + * @return Api\SystemHooks + */ + public function systemHooks() + { + return new Api\SystemHooks($this); + } + + /** + * @return Api\Users + */ + public function users() + { + return new Api\Users($this); + } + + /** + * @return Api\Keys + */ + public function keys() + { + return new Api\Keys($this); + } + + /** + * @return Api\Tags + */ + public function tags() + { + return new Api\Tags($this); + } + /** * @param string $name * @@ -128,75 +248,58 @@ public function api($name) switch ($name) { case 'deploy_keys': - $api = new Api\DeployKeys($this); - break; + return $this->deployKeys(); case 'groups': - $api = new Api\Groups($this); - break; + return $this->groups(); case 'issues': - $api = new Api\Issues($this); - break; + return $this->issues(); case 'board': case 'issue_boards': - $api = new Api\IssueBoards($this); + return $this->issueBoards(); case 'jobs': - $api = new Api\Jobs($this); - break; + return $this->jobs(); case 'mr': case 'merge_requests': - $api = new Api\MergeRequests($this); - break; + return $this->mergeRequests(); case 'milestones': case 'ms': - $api = new Api\Milestones($this); - break; + return $this->milestones(); case 'namespaces': case 'ns': - $api = new Api\ProjectNamespaces($this); - break; + return $this->namespaces(); case 'projects': - $api = new Api\Projects($this); - break; + return $this->projects(); case 'repo': case 'repositories': - $api = new Api\Repositories($this); - break; + return $this->repositories(); case 'snippets': - $api = new Api\Snippets($this); - break; + return $this->snippets(); case 'hooks': case 'system_hooks': - $api = new Api\SystemHooks($this); - break; + return $this->systemHooks(); case 'users': - $api = new Api\Users($this); - break; + return $this->users(); case 'keys': - $api = new Api\Keys($this); - break; + return $this->keys(); case 'tags': - $api = new Api\Tags($this); - break; + return $this->tags(); default: throw new InvalidArgumentException('Invalid endpoint: "'.$name.'"'); - } - - return $api; } /** diff --git a/lib/Gitlab/HttpClient/Builder.php b/lib/Gitlab/HttpClient/Builder.php index 133091111..15be1ff12 100644 --- a/lib/Gitlab/HttpClient/Builder.php +++ b/lib/Gitlab/HttpClient/Builder.php @@ -31,7 +31,7 @@ class Builder /** * A HTTP client with all our plugins. * - * @var PluginClient + * @var HttpMethodsClient */ private $pluginClient; diff --git a/lib/Gitlab/Model/Branch.php b/lib/Gitlab/Model/Branch.php index 23afebcfe..30dfc17a5 100644 --- a/lib/Gitlab/Model/Branch.php +++ b/lib/Gitlab/Model/Branch.php @@ -57,7 +57,7 @@ public function __construct(Project $project, $name = null, Client $client = nul */ public function show() { - $data = $this->api('repositories')->branch($this->project->id, $this->name); + $data = $this->client->repositories()->branch($this->project->id, $this->name); return static::fromArray($this->getClient(), $this->project, $data); } @@ -69,7 +69,7 @@ public function show() */ public function protect($devPush = false, $devMerge = false) { - $data = $this->api('repositories')->protectBranch($this->project->id, $this->name, $devPush, $devMerge); + $data = $this->client->repositories()->protectBranch($this->project->id, $this->name, $devPush, $devMerge); return static::fromArray($this->getClient(), $this->project, $data); } @@ -79,7 +79,7 @@ public function protect($devPush = false, $devMerge = false) */ public function unprotect() { - $data = $this->api('repositories')->unprotectBranch($this->project->id, $this->name); + $data = $this->client->repositories()->unprotectBranch($this->project->id, $this->name); return static::fromArray($this->getClient(), $this->project, $data); } @@ -89,7 +89,7 @@ public function unprotect() */ public function delete() { - $this->api('repositories')->deleteBranch($this->project->id, $this->name); + $this->client->repositories()->deleteBranch($this->project->id, $this->name); return true; } @@ -112,7 +112,7 @@ public function commits($page = 1, $per_page = Api::PER_PAGE) */ public function createFile($file_path, $content, $commit_message) { - $data = $this->api('repositories')->createFile($this->project->id, $file_path, $content, $this->name, $commit_message); + $data = $this->client->repositories()->createFile($this->project->id, $file_path, $content, $this->name, $commit_message); return File::fromArray($this->getClient(), $this->project, $data); } @@ -125,7 +125,7 @@ public function createFile($file_path, $content, $commit_message) */ public function updateFile($file_path, $content, $commit_message) { - $data = $this->api('repositories')->updateFile($this->project->id, $file_path, $content, $this->name, $commit_message); + $data = $this->client->repositories()->updateFile($this->project->id, $file_path, $content, $this->name, $commit_message); return File::fromArray($this->getClient(), $this->project, $data); } @@ -137,7 +137,7 @@ public function updateFile($file_path, $content, $commit_message) */ public function deleteFile($file_path, $commit_message) { - $this->api('repositories')->deleteFile($this->project->id, $file_path, $this->name, $commit_message); + $this->client->repositories()->deleteFile($this->project->id, $file_path, $this->name, $commit_message); return true; } diff --git a/lib/Gitlab/Model/Group.php b/lib/Gitlab/Model/Group.php index 38891d6c1..6844877d9 100644 --- a/lib/Gitlab/Model/Group.php +++ b/lib/Gitlab/Model/Group.php @@ -52,7 +52,7 @@ public static function fromArray(Client $client, array $data) */ public static function create(Client $client, $name, $path) { - $data = $client->api('groups')->create($name, $path); + $data = $client->groups()->create($name, $path); return static::fromArray($client, $data); } @@ -72,7 +72,7 @@ public function __construct($id, Client $client = null) */ public function show() { - $data = $this->api('groups')->show($this->id); + $data = $this->client->groups()->show($this->id); return Group::fromArray($this->getClient(), $data); } @@ -83,7 +83,7 @@ public function show() */ public function transfer($project_id) { - $data = $this->api('groups')->transfer($this->id, $project_id); + $data = $this->client->groups()->transfer($this->id, $project_id); return Group::fromArray($this->getClient(), $data); } @@ -93,7 +93,7 @@ public function transfer($project_id) */ public function members() { - $data = $this->api('groups')->members($this->id); + $data = $this->client->groups()->members($this->id); $members = array(); foreach ($data as $member) { @@ -110,7 +110,7 @@ public function members() */ public function addMember($user_id, $access_level) { - $data = $this->api('groups')->addMember($this->id, $user_id, $access_level); + $data = $this->client->groups()->addMember($this->id, $user_id, $access_level); return User::fromArray($this->getClient(), $data); } @@ -121,7 +121,7 @@ public function addMember($user_id, $access_level) */ public function removeMember($user_id) { - $this->api('groups')->removeMember($this->id, $user_id); + $this->client->groups()->removeMember($this->id, $user_id); return true; } @@ -132,7 +132,7 @@ public function removeMember($user_id) public function projects() { - $data = $this->api('groups')->projects($this->id); + $data = $this->client->groups()->projects($this->id); return Group::fromArray($this->getClient(),$data); } diff --git a/lib/Gitlab/Model/Hook.php b/lib/Gitlab/Model/Hook.php index 15bda3992..d276982e2 100644 --- a/lib/Gitlab/Model/Hook.php +++ b/lib/Gitlab/Model/Hook.php @@ -39,7 +39,7 @@ public static function fromArray(Client $client, array $data) */ public static function create(Client $client, $url) { - $data = $client->api('system_hooks')->create($url); + $data = $client->systemHooks()->create($url); return static::fromArray($client, $data); } @@ -59,7 +59,7 @@ public function __construct($id, Client $client = null) */ public function test() { - $this->api('system_hooks')->test($this->id); + $this->client->systemHooks()->test($this->id); return true; } @@ -69,7 +69,7 @@ public function test() */ public function delete() { - $this->api('system_hooks')->remove($this->id); + $this->client->systemHooks()->remove($this->id); return true; } diff --git a/lib/Gitlab/Model/Issue.php b/lib/Gitlab/Model/Issue.php index 86c7e2add..0b5f1d77d 100644 --- a/lib/Gitlab/Model/Issue.php +++ b/lib/Gitlab/Model/Issue.php @@ -80,7 +80,7 @@ public function __construct(Project $project, $id = null, Client $client = null) */ public function show() { - $data = $this->api('issues')->show($this->project->id, $this->id); + $data = $this->client->issues()->show($this->project->id, $this->id); return static::fromArray($this->getClient(), $this->project, $data); } @@ -91,7 +91,7 @@ public function show() */ public function update(array $params) { - $data = $this->api('issues')->update($this->project->id, $this->id, $params); + $data = $this->client->issues()->update($this->project->id, $this->id, $params); return static::fromArray($this->getClient(), $this->project, $data); } @@ -135,7 +135,7 @@ public function reopen() */ public function addComment($comment) { - $data = $this->api('issues')->addComment($this->project->id, $this->id, array( + $data = $this->client->issues()->addComment($this->project->id, $this->id, array( 'body' => $comment )); @@ -148,7 +148,7 @@ public function addComment($comment) public function showComments() { $notes = array(); - $data = $this->api('issues')->showComments($this->project->id, $this->id); + $data = $this->client->issues()->showComments($this->project->id, $this->id); foreach ($data as $note) { $notes[] = Note::fromArray($this->getClient(), $this, $note); diff --git a/lib/Gitlab/Model/MergeRequest.php b/lib/Gitlab/Model/MergeRequest.php index 686b47a7d..49e88017b 100644 --- a/lib/Gitlab/Model/MergeRequest.php +++ b/lib/Gitlab/Model/MergeRequest.php @@ -105,7 +105,7 @@ public function __construct(Project $project, $id = null, Client $client = null) */ public function show() { - $data = $this->api('mr')->show($this->project->id, $this->id); + $data = $this->client->mergeRequests()->show($this->project->id, $this->id); return static::fromArray($this->getClient(), $this->project, $data); } @@ -116,7 +116,7 @@ public function show() */ public function update(array $params) { - $data = $this->api('mr')->update($this->project->id, $this->id, $params); + $data = $this->client->mergeRequests()->update($this->project->id, $this->id, $params); return static::fromArray($this->getClient(), $this->project, $data); } @@ -160,7 +160,7 @@ public function open() */ public function merge($message = null) { - $data = $this->api('mr')->merge($this->project->id, $this->id, array( + $data = $this->client->mergeRequests()->merge($this->project->id, $this->id, array( 'merge_commit_message' => $message )); @@ -183,7 +183,7 @@ public function merged() */ public function addComment($comment) { - $data = $this->api('mr')->addComment($this->project->id, $this->id, $comment); + $data = $this->client->mergeRequests()->addComment($this->project->id, $this->id, $comment); return Note::fromArray($this->getClient(), $this, $data); } @@ -194,7 +194,7 @@ public function addComment($comment) public function showComments() { $notes = array(); - $data = $this->api('mr')->showComments($this->project->id, $this->id); + $data = $this->client->mergeRequests()->showComments($this->project->id, $this->id); foreach ($data as $note) { $notes[] = Note::fromArray($this->getClient(), $this, $note); @@ -220,7 +220,7 @@ public function isClosed() */ public function changes() { - $data = $this->api('mr')->changes($this->project->id, $this->id); + $data = $this->client->mergeRequests()->changes($this->project->id, $this->id); return static::fromArray($this->getClient(), $this->project, $data); } diff --git a/lib/Gitlab/Model/Milestone.php b/lib/Gitlab/Model/Milestone.php index c59afca38..8f749417b 100644 --- a/lib/Gitlab/Model/Milestone.php +++ b/lib/Gitlab/Model/Milestone.php @@ -66,7 +66,7 @@ public function __construct(Project $project, $id, Client $client = null) */ public function show() { - $data = $this->api('milestones')->show($this->project->id, $this->id); + $data = $this->client->milestones()->show($this->project->id, $this->id); return static::fromArray($this->getClient(), $this->project, $data); } @@ -77,7 +77,7 @@ public function show() */ public function update(array $params) { - $data = $this->api('milestones')->update($this->project->id, $this->id, $params); + $data = $this->client->milestones()->update($this->project->id, $this->id, $params); return static::fromArray($this->getClient(), $this->project, $data); } @@ -103,7 +103,7 @@ public function incomplete() */ public function issues() { - $data = $this->api('milestones')->issues($this->project->id, $this->id); + $data = $this->client->milestones()->issues($this->project->id, $this->id); $issues = array(); foreach ($data as $issue) { diff --git a/lib/Gitlab/Model/Pipeline.php b/lib/Gitlab/Model/Pipeline.php index b2129c8de..efeccbc98 100644 --- a/lib/Gitlab/Model/Pipeline.php +++ b/lib/Gitlab/Model/Pipeline.php @@ -26,7 +26,7 @@ class Pipeline extends AbstractModel * @param Client $client * @param Project $project * @param array $data - * @return Commit + * @return Pipeline */ public static function fromArray(Client $client, Project $project, array $data) { diff --git a/lib/Gitlab/Model/Project.php b/lib/Gitlab/Model/Project.php index 887967e5f..5b35a21f0 100644 --- a/lib/Gitlab/Model/Project.php +++ b/lib/Gitlab/Model/Project.php @@ -93,7 +93,7 @@ public static function fromArray(Client $client, array $data) */ public static function create(Client $client, $name, array $params = array()) { - $data = $client->api('projects')->create($name, $params); + $data = $client->projects()->create($name, $params); return static::fromArray($client, $data); } @@ -107,7 +107,7 @@ public static function create(Client $client, $name, array $params = array()) */ public static function createForUser($user_id, Client $client, $name, array $params = array()) { - $data = $client->api('projects')->createForUser($user_id, $name, $params); + $data = $client->projects()->createForUser($user_id, $name, $params); return static::fromArray($client, $data); } @@ -126,7 +126,7 @@ public function __construct($id = null, Client $client = null) */ public function show() { - $data = $this->api('projects')->show($this->id); + $data = $this->client->projects()->show($this->id); return static::fromArray($this->getClient(), $data); } @@ -137,7 +137,7 @@ public function show() */ public function update(array $params) { - $data = $this->api('projects')->update($this->id, $params); + $data = $this->client->projects()->update($this->id, $params); return static::fromArray($this->getClient(), $data); } @@ -147,7 +147,7 @@ public function update(array $params) */ public function archive() { - $data = $this->api("projects")->archive($this->id); + $data = $this->client->projects()->archive($this->id); return static::fromArray($this->getClient(), $data); } @@ -157,7 +157,7 @@ public function archive() */ public function unarchive() { - $data = $this->api("projects")->unarchive($this->id); + $data = $this->client->projects()->unarchive($this->id); return static::fromArray($this->getClient(), $data); } @@ -167,7 +167,7 @@ public function unarchive() */ public function remove() { - $this->api('projects')->remove($this->id); + $this->client->projects()->remove($this->id); return true; } @@ -178,7 +178,7 @@ public function remove() */ public function members($username_query = null) { - $data = $this->api('projects')->members($this->id, $username_query); + $data = $this->client->projects()->members($this->id, $username_query); $members = array(); foreach ($data as $member) { @@ -194,7 +194,7 @@ public function members($username_query = null) */ public function member($user_id) { - $data = $this->api('projects')->member($this->id, $user_id); + $data = $this->client->projects()->member($this->id, $user_id); return User::fromArray($this->getClient(), $data); } @@ -206,7 +206,7 @@ public function member($user_id) */ public function addMember($user_id, $access_level) { - $data = $this->api('projects')->addMember($this->id, $user_id, $access_level); + $data = $this->client->projects()->addMember($this->id, $user_id, $access_level); return User::fromArray($this->getClient(), $data); } @@ -218,7 +218,7 @@ public function addMember($user_id, $access_level) */ public function saveMember($user_id, $access_level) { - $data = $this->api('projects')->saveMember($this->id, $user_id, $access_level); + $data = $this->client->projects()->saveMember($this->id, $user_id, $access_level); return User::fromArray($this->getClient(), $data); } @@ -229,7 +229,7 @@ public function saveMember($user_id, $access_level) */ public function removeMember($user_id) { - $this->api('projects')->removeMember($this->id, $user_id); + $this->client->projects()->removeMember($this->id, $user_id); return true; } @@ -241,7 +241,7 @@ public function removeMember($user_id) */ public function hooks($page = 1, $per_page = Api::PER_PAGE) { - $data = $this->api('projects')->hooks($this->id, $page, $per_page); + $data = $this->client->projects()->hooks($this->id, $page, $per_page); $hooks = array(); foreach ($data as $hook) { @@ -269,7 +269,7 @@ public function hook($id) */ public function addHook($url, array $events = array()) { - $data = $this->api('projects')->addHook($this->id, $url, $events); + $data = $this->client->projects()->addHook($this->id, $url, $events); return ProjectHook::fromArray($this->getClient(), $this, $data); } @@ -302,7 +302,7 @@ public function removeHook($hook_id) */ public function deployKeys() { - $data = $this->api('projects')->deployKeys($this->id); + $data = $this->client->projects()->deployKeys($this->id); $keys = array(); foreach ($data as $key) { @@ -318,7 +318,7 @@ public function deployKeys() */ public function deployKey($key_id) { - $data = $this->api('projects')->deployKey($this->id, $key_id); + $data = $this->client->projects()->deployKey($this->id, $key_id); return Key::fromArray($this->getClient(), $data); } @@ -330,7 +330,7 @@ public function deployKey($key_id) */ public function addDeployKey($title, $key) { - $data = $this->api('projects')->addDeployKey($this->id, $title, $key); + $data = $this->client->projects()->addDeployKey($this->id, $title, $key); return Key::fromArray($this->getClient(), $data); } @@ -341,7 +341,7 @@ public function addDeployKey($title, $key) */ public function deleteDeployKey($key_id) { - $this->api('projects')->deleteDeployKey($this->id, $key_id); + $this->client->projects()->deleteDeployKey($this->id, $key_id); return true; } @@ -352,7 +352,7 @@ public function deleteDeployKey($key_id) */ public function enableDeployKey($key_id) { - $this->api('projects')->enableDeployKey($this->id, $key_id); + $this->client->projects()->enableDeployKey($this->id, $key_id); return true; } @@ -364,7 +364,7 @@ public function enableDeployKey($key_id) */ public function createBranch($name, $ref) { - $data = $this->api('repositories')->createBranch($this->id, $name, $ref); + $data = $this->client->repositories()->createBranch($this->id, $name, $ref); return Branch::fromArray($this->getClient(), $this, $data); } @@ -375,7 +375,7 @@ public function createBranch($name, $ref) */ public function deleteBranch($name) { - $this->api('repositories')->deleteBranch($this->id, $name); + $this->client->repositories()->deleteBranch($this->id, $name); return true; } @@ -385,7 +385,7 @@ public function deleteBranch($name) */ public function branches() { - $data = $this->api('repo')->branches($this->id); + $data = $this->client->repositories()->branches($this->id); $branches = array(); foreach ($data as $branch) { @@ -438,7 +438,7 @@ public function unprotectBranch($branch_name) */ public function tags() { - $data = $this->api('repo')->tags($this->id); + $data = $this->client->repositories()->tags($this->id); $tags = array(); foreach ($data as $tag) { @@ -456,7 +456,7 @@ public function tags() */ public function commits($page = 0, $per_page = Api::PER_PAGE, $ref_name = null) { - $data = $this->api('repo')->commits($this->id, $page, $per_page, $ref_name); + $data = $this->client->repositories()->commits($this->id, $page, $per_page, $ref_name); $commits = array(); foreach ($data as $commit) { @@ -472,7 +472,7 @@ public function commits($page = 0, $per_page = Api::PER_PAGE, $ref_name = null) */ public function commit($sha) { - $data = $this->api('repo')->commit($this->id, $sha); + $data = $this->client->repositories()->commit($this->id, $sha); return Commit::fromArray($this->getClient(), $this, $data); } @@ -485,7 +485,7 @@ public function commit($sha) */ public function commitComments($ref, $page = 0, $per_page = Api::PER_PAGE) { - $data = $this->api('repo')->commitComments($this->id, $ref, $page, $per_page); + $data = $this->client->repositories()->commitComments($this->id, $ref, $page, $per_page); $comments = array(); foreach ($data as $comment) { @@ -503,7 +503,7 @@ public function commitComments($ref, $page = 0, $per_page = Api::PER_PAGE) */ public function createCommitComment($ref, $note, array $params = array()) { - $data = $this->api('repo')->createCommitComment($this->id, $ref, $note, $params); + $data = $this->client->repositories()->createCommitComment($this->id, $ref, $note, $params); return CommitNote::fromArray($this->getClient(), $data); } @@ -514,7 +514,7 @@ public function createCommitComment($ref, $note, array $params = array()) */ public function diff($sha) { - return $this->api('repo')->diff($this->id, $sha); + return $this->client->repositories()->diff($this->id, $sha); } /** @@ -524,7 +524,7 @@ public function diff($sha) */ public function compare($from, $to) { - $data = $this->api('repo')->compare($this->id, $from, $to); + $data = $this->client->repositories()->compare($this->id, $from, $to); return Comparison::fromArray($this->getClient(), $this, $data); } @@ -535,7 +535,7 @@ public function compare($from, $to) */ public function tree(array $params = array()) { - $data = $this->api('repo')->tree($this->id, $params); + $data = $this->client->repositories()->tree($this->id, $params); $tree = array(); foreach ($data as $node) { @@ -552,7 +552,7 @@ public function tree(array $params = array()) */ public function blob($sha, $filepath) { - return $this->api('repo')->blob($this->id, $sha, $filepath); + return $this->client->repositories()->blob($this->id, $sha, $filepath); } /** @@ -563,7 +563,7 @@ public function blob($sha, $filepath) */ public function getFile($sha, $filepath) { - return $this->api('repo')->getFile($this->id, $filepath, $sha); + return $this->client->repositories()->getFile($this->id, $filepath, $sha); } /** @@ -577,7 +577,7 @@ public function getFile($sha, $filepath) */ public function createFile($file_path, $content, $branch_name, $commit_message, $author_email = null, $author_name = null) { - $data = $this->api('repo')->createFile($this->id, $file_path, $content, $branch_name, $commit_message, null, $author_email, $author_name); + $data = $this->client->repositories()->createFile($this->id, $file_path, $content, $branch_name, $commit_message, null, $author_email, $author_name); return File::fromArray($this->getClient(), $this, $data); } @@ -593,7 +593,7 @@ public function createFile($file_path, $content, $branch_name, $commit_message, */ public function updateFile($file_path, $content, $branch_name, $commit_message, $author_email = null, $author_name = null) { - $data = $this->api('repo')->updateFile($this->id, $file_path, $content, $branch_name, $commit_message, null, $author_email, $author_name); + $data = $this->client->repositories()->updateFile($this->id, $file_path, $content, $branch_name, $commit_message, null, $author_email, $author_name); return File::fromArray($this->getClient(), $this, $data); } @@ -608,7 +608,7 @@ public function updateFile($file_path, $content, $branch_name, $commit_message, */ public function deleteFile($file_path, $branch_name, $commit_message, $author_email = null, $author_name = null) { - $this->api('repo')->deleteFile($this->id, $file_path, $branch_name, $commit_message, $author_email, $author_name); + $this->client->repositories()->deleteFile($this->id, $file_path, $branch_name, $commit_message, $author_email, $author_name); return true; } @@ -620,7 +620,7 @@ public function deleteFile($file_path, $branch_name, $commit_message, $author_em */ public function events($page = 1, $per_page = Api::PER_PAGE) { - $data = $this->api('projects')->events($this->id, $page, $per_page); + $data = $this->client->projects()->events($this->id, $page, $per_page); $events = array(); foreach ($data as $event) { @@ -638,7 +638,7 @@ public function events($page = 1, $per_page = Api::PER_PAGE) */ public function mergeRequests($page = 1, $per_page = Api::PER_PAGE, $state = MergeRequests::STATE_ALL) { - $data = $this->api('mr')->$state($this->id, $page, $per_page); + $data = $this->client->mergeRequests()->$state($this->id, $page, $per_page); $mrs = array(); foreach ($data as $mr) { @@ -669,7 +669,7 @@ public function mergeRequest($id) */ public function createMergeRequest($source, $target, $title, $assignee = null, $description = null) { - $data = $this->api('mr')->create($this->id, $source, $target, $title, $assignee, null, $description); + $data = $this->client->mergeRequests()->create($this->id, $source, $target, $title, $assignee, null, $description); return MergeRequest::fromArray($this->getClient(), $this, $data); } @@ -726,7 +726,7 @@ public function mergeMergeRequest($id) */ public function issues($page = 1, $per_page = Api::PER_PAGE) { - $data = $this->api('issues')->all($this->id, $page, $per_page); + $data = $this->client->issues()->all($this->id, $page, $per_page); $issues = array(); foreach ($data as $issue) { @@ -744,7 +744,7 @@ public function issues($page = 1, $per_page = Api::PER_PAGE) public function createIssue($title, array $params = array()) { $params['title'] = $title; - $data = $this->api('issues')->create($this->id, $params); + $data = $this->client->issues()->create($this->id, $params); return Issue::fromArray($this->getClient(), $this, $data); } @@ -802,7 +802,7 @@ public function openIssue($id) */ public function milestones($page = 1, $per_page = Api::PER_PAGE) { - $data = $this->api('milestones')->all($this->id, $page, $per_page); + $data = $this->client->milestones()->all($this->id, $page, $per_page); $milestones = array(); foreach ($data as $milestone) { @@ -820,7 +820,7 @@ public function milestones($page = 1, $per_page = Api::PER_PAGE) public function createMilestone($title, array $params = array()) { $params['title'] = $title; - $data = $this->api('milestones')->create($this->id, $params); + $data = $this->client->milestones()->create($this->id, $params); return Milestone::fromArray($this->getClient(), $this, $data); } @@ -864,7 +864,7 @@ public function milestoneIssues($id) */ public function snippets() { - $data = $this->api('snippets')->all($this->id); + $data = $this->client->snippets()->all($this->id); $snippets = array(); foreach ($data as $snippet) { @@ -878,12 +878,11 @@ public function snippets() * @param string $title * @param string $filename * @param string $code - * @param string $lifetime * @return Snippet */ - public function createSnippet($title, $filename, $code, $lifetime = null) + public function createSnippet($title, $filename, $code) { - $data = $this->api('snippets')->create($this->id, $title, $filename, $code, $lifetime); + $data = $this->client->snippets()->create($this->id, $title, $filename, $code); return Snippet::fromArray($this->getClient(), $this, $data); } @@ -901,7 +900,7 @@ public function snippet($id) /** * @param int $id - * @return Snippet + * @return string */ public function snippetContent($id) { @@ -950,7 +949,7 @@ public function transfer($group_id) */ public function forkTo($id) { - $data = $this->api('projects')->createForkRelation($id, $this->id); + $data = $this->client->projects()->createForkRelation($id, $this->id); return Project::fromArray($this->getClient(), $data); } @@ -970,7 +969,7 @@ public function forkFrom($id) */ public function createForkRelation($id) { - $data = $this->api('projects')->createForkRelation($this->id, $id); + $data = $this->client->projects()->createForkRelation($this->id, $id); return Project::fromArray($this->getClient(), $data); } @@ -980,7 +979,7 @@ public function createForkRelation($id) */ public function removeForkRelation() { - $this->api('projects')->removeForkRelation($this->id); + $this->client->projects()->removeForkRelation($this->id); return true; } @@ -992,7 +991,7 @@ public function removeForkRelation() */ public function setService($service_name, array $params = array()) { - $this->api('projects')->setService($this->id, $service_name, $params); + $this->client->projects()->setService($this->id, $service_name, $params); return true; } @@ -1003,7 +1002,7 @@ public function setService($service_name, array $params = array()) */ public function removeService($service_name) { - $this->api('projects')->removeService($this->id, $service_name); + $this->client->projects()->removeService($this->id, $service_name); return true; } @@ -1013,7 +1012,7 @@ public function removeService($service_name) */ public function labels() { - $data = $this->api('projects')->labels($this->id); + $data = $this->client->projects()->labels($this->id); $labels = array(); foreach ($data as $label) { @@ -1030,7 +1029,7 @@ public function labels() */ public function addLabel($name, $color) { - $data = $this->api('projects')->addLabel($this->id, array( + $data = $this->client->projects()->addLabel($this->id, array( 'name' => $name, 'color' => $color )); @@ -1051,7 +1050,7 @@ public function updateLabel($name, array $params) $params['name'] = $name; - $data = $this->api('projects')->updateLabel($this->id, $params); + $data = $this->client->projects()->updateLabel($this->id, $params); return Label::fromArray($this->getClient(), $this, $data); } @@ -1062,7 +1061,7 @@ public function updateLabel($name, array $params) */ public function removeLabel($name) { - $this->api('projects')->removeLabel($this->id, $name); + $this->client->projects()->removeLabel($this->id, $name); return true; } @@ -1072,7 +1071,7 @@ public function removeLabel($name) */ public function contributors() { - $data = $this->api('repo')->contributors($this->id); + $data = $this->client->repositories()->contributors($this->id); $contributors = array(); foreach ($data as $contributor) { @@ -1088,7 +1087,7 @@ public function contributors() */ public function jobs(array $scopes = []) { - $data = $this->api('jobs')->jobs($this->id, $scopes); + $data = $this->client->jobs()->all($this->id, $scopes); $jobs = array(); foreach ($data as $job) { @@ -1105,7 +1104,7 @@ public function jobs(array $scopes = []) */ public function pipelineJobs($pipeline_id, array $scopes = []) { - $data = $this->api('jobs')->pipelineJobs($this->id, $pipeline_id, $scopes); + $data = $this->client->jobs()->pipelineJobs($this->id, $pipeline_id, $scopes); $jobs = array(); foreach ($data as $job) { @@ -1121,7 +1120,7 @@ public function pipelineJobs($pipeline_id, array $scopes = []) */ public function job($job_id) { - $data = $this->api('jobs')->show($this->id, $job_id); + $data = $this->client->jobs()->show($this->id, $job_id); return Job::fromArray($this->getClient(), $this, $data); } diff --git a/lib/Gitlab/Model/ProjectHook.php b/lib/Gitlab/Model/ProjectHook.php index 7805ac6a1..7090e79eb 100644 --- a/lib/Gitlab/Model/ProjectHook.php +++ b/lib/Gitlab/Model/ProjectHook.php @@ -64,7 +64,7 @@ public function __construct(Project $project, $id, Client $client = null) */ public function show() { - $data = $this->api('projects')->hook($this->project->id, $this->id); + $data = $this->client->projects()->hook($this->project->id, $this->id); return static::fromArray($this->getClient(), $this->project, $data); } @@ -74,7 +74,7 @@ public function show() */ public function delete() { - $this->api('projects')->removeHook($this->project->id, $this->id); + $this->client->projects()->removeHook($this->project->id, $this->id); return true; } @@ -93,7 +93,7 @@ public function remove() */ public function update(array $params) { - $data = $this->api('projects')->updateHook($this->project->id, $this->id, $params); + $data = $this->client->projects()->updateHook($this->project->id, $this->id, $params); return static::fromArray($this->getClient(), $this->project, $data); } diff --git a/lib/Gitlab/Model/Session.php b/lib/Gitlab/Model/Session.php index f9b8177be..7cf4cfe79 100644 --- a/lib/Gitlab/Model/Session.php +++ b/lib/Gitlab/Model/Session.php @@ -51,7 +51,7 @@ public function __construct(Client $client = null) */ public function me() { - $data = $this->api('users')->show(); + $data = $this->client->users()->user(); return User::fromArray($this->getClient(), $data); } @@ -59,11 +59,11 @@ public function me() /** * @param string $email * @param string $password - * @return $this + * @return Session */ public function login($email, $password) { - $data = $this->api('users')->session($email, $password); + $data = $this->client->users()->session($email, $password); return $this->hydrate($data); } diff --git a/lib/Gitlab/Model/Snippet.php b/lib/Gitlab/Model/Snippet.php index 7f039a9ea..1f021bcb4 100644 --- a/lib/Gitlab/Model/Snippet.php +++ b/lib/Gitlab/Model/Snippet.php @@ -62,7 +62,7 @@ public function __construct(Project $project, $id = null, Client $client = null) */ public function show() { - $data = $this->api('snippets')->show($this->project->id, $this->id); + $data = $this->client->snippets()->show($this->project->id, $this->id); return static::fromArray($this->getClient(), $this->project, $data); } @@ -73,7 +73,7 @@ public function show() */ public function update(array $params) { - $data = $this->api('snippets')->update($this->project->id, $this->id, $params); + $data = $this->client->snippets()->update($this->project->id, $this->id, $params); return static::fromArray($this->getClient(), $this->project, $data); } @@ -83,7 +83,7 @@ public function update(array $params) */ public function content() { - return $this->api('snippets')->content($this->project->id, $this->id); + return $this->client->snippets()->content($this->project->id, $this->id); } /** @@ -91,7 +91,7 @@ public function content() */ public function remove() { - $this->api('snippets')->remove($this->project->id, $this->id); + $this->client->snippets()->remove($this->project->id, $this->id); return true; } diff --git a/lib/Gitlab/Model/User.php b/lib/Gitlab/Model/User.php index 5ffffc16e..ef654756d 100644 --- a/lib/Gitlab/Model/User.php +++ b/lib/Gitlab/Model/User.php @@ -86,7 +86,7 @@ public static function fromArray(Client $client, array $data) */ public static function create(Client $client, $email, $password, array $params = array()) { - $data = $client->api('users')->create($email, $password, $params); + $data = $client->users()->create($email, $password, $params); return static::fromArray($client, $data); } @@ -106,7 +106,7 @@ public function __construct($id = null, Client $client = null) */ public function show() { - $data = $this->api('users')->show($this->id); + $data = $this->client->users()->show($this->id); return static::fromArray($this->getClient(), $data); } @@ -117,7 +117,7 @@ public function show() */ public function update(array $params) { - $data = $this->api('users')->update($this->id, $params); + $data = $this->client->users()->update($this->id, $params); return static::fromArray($this->getClient(), $data); } @@ -127,7 +127,7 @@ public function update(array $params) */ public function remove() { - $this->api('users')->remove($this->id); + $this->client->users()->remove($this->id); return true; } @@ -137,7 +137,7 @@ public function remove() */ public function block() { - $this->api('users')->block($this->id); + $this->client->users()->block($this->id); return true; } @@ -147,7 +147,7 @@ public function block() */ public function unblock() { - $this->api('users')->unblock($this->id); + $this->client->users()->unblock($this->id); return true; } @@ -157,7 +157,7 @@ public function unblock() */ public function keys() { - $data = $this->api('users')->keys(); + $data = $this->client->users()->keys(); $keys = array(); foreach ($data as $key) { @@ -174,7 +174,7 @@ public function keys() */ public function createKey($title, $key) { - $data = $this->api('users')->createKey($title, $key); + $data = $this->client->users()->createKey($title, $key); return Key::fromArray($this->getClient(), $data); } @@ -186,7 +186,7 @@ public function createKey($title, $key) */ public function createKeyForUser($user_id, $title, $key) { - $data = $this->api('users')->createKeyForUser($user_id, $title, $key); + $data = $this->client->users()->createKeyForUser($user_id, $title, $key); return Key::fromArray($this->getClient(), $data); } @@ -197,7 +197,7 @@ public function createKeyForUser($user_id, $title, $key) */ public function removeKey($id) { - $this->api('users')->removeKey($id); + $this->client->users()->removeKey($id); return true; } From 745fee2ea54857e47fa6304aebcfa17fca154e00 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Wed, 2 Aug 2017 12:26:23 +0200 Subject: [PATCH 40/83] run phpstan on travis-ci --- .travis.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 25b7f8c79..55eda476e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,11 +5,17 @@ sudo: false php: - 5.6 - 7.0 - - 7.1 + +matrix: + include: + - php: 7.1 + env: STATIC_ANALYSIS=yes before_script: - travis_retry composer self-update - travis_retry composer install --no-interaction --prefer-source + - if [ "$STATIC_ANALYSIS" != "" ]; then curl -L https://github.com/phpstan/phpstan/releases/download/0.8/phpstan.phar -o phpstan.phar; fi; script: - vendor/bin/phpunit --verbose --coverage-text + - if [ "$STATIC_ANALYSIS" != "" ]; then php phpstan.phar analyse --level=4 lib; fi; From 2d5e5e35d29336da4336b839a84d927c88586de1 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Thu, 3 Aug 2017 10:27:23 +0200 Subject: [PATCH 41/83] update coding standards to psr-2 --- .styleci.yml | 1 + lib/Gitlab/Api/AbstractApi.php | 9 +- lib/Gitlab/Api/Projects.php | 6 +- lib/Gitlab/Api/Repositories.php | 14 +-- lib/Gitlab/Client.php | 4 +- lib/Gitlab/Exception/ErrorException.php | 1 - .../Exception/InvalidArgumentException.php | 1 - lib/Gitlab/Exception/RuntimeException.php | 1 - .../Exception/ValidationFailedException.php | 1 - lib/Gitlab/Model/Group.php | 3 +- lib/Gitlab/Model/Project.php | 1 - test/Gitlab/Tests/Api/RepositoriesTest.php | 96 ++++++++++--------- test/Gitlab/Tests/HttpClient/BuilderTest.php | 1 + .../HttpClient/Plugin/ApiVersionTest.php | 10 +- test/Gitlab/Tests/ResultPagerTest.php | 1 - 15 files changed, 78 insertions(+), 72 deletions(-) create mode 100644 .styleci.yml diff --git a/.styleci.yml b/.styleci.yml new file mode 100644 index 000000000..247a09c5d --- /dev/null +++ b/.styleci.yml @@ -0,0 +1 @@ +preset: psr2 diff --git a/lib/Gitlab/Api/AbstractApi.php b/lib/Gitlab/Api/AbstractApi.php index 60681a529..e03123fe9 100644 --- a/lib/Gitlab/Api/AbstractApi.php +++ b/lib/Gitlab/Api/AbstractApi.php @@ -203,11 +203,15 @@ protected function createOptionsResolver() $resolver = new OptionsResolver(); $resolver->setDefined('page') ->setAllowedTypes('page', 'int') - ->setAllowedValues('page', function ($value) { return $value > 0; }) + ->setAllowedValues('page', function ($value) { + return $value > 0; + }) ; $resolver->setDefined('per_page') ->setAllowedTypes('per_page', 'int') - ->setAllowedValues('per_page', function ($value) { return $value > 0 && $value <= 100; }) + ->setAllowedValues('per_page', function ($value) { + return $value > 0 && $value <= 100; + }) ; $resolver->setDefined('sort') ->setAllowedValues('sort', ['asc', 'desc']) @@ -218,7 +222,6 @@ protected function createOptionsResolver() private function preparePath($path, array $parameters = []) { - if (count($parameters) > 0) { $path .= '?'.QueryStringBuilder::build($parameters); } diff --git a/lib/Gitlab/Api/Projects.php b/lib/Gitlab/Api/Projects.php index 6dd422c59..08caf5042 100644 --- a/lib/Gitlab/Api/Projects.php +++ b/lib/Gitlab/Api/Projects.php @@ -135,7 +135,8 @@ public function remove($project_id) * @param int $project_id * @return mixed */ - public function archive($project_id){ + public function archive($project_id) + { return $this->post("projects/".$this->encodePath($project_id)."/archive"); } @@ -143,7 +144,8 @@ public function archive($project_id){ * @param int $project_id * @return mixed */ - public function unarchive($project_id){ + public function unarchive($project_id) + { return $this->post("projects/".$this->encodePath($project_id)."/unarchive"); } diff --git a/lib/Gitlab/Api/Repositories.php b/lib/Gitlab/Api/Repositories.php index 312894ba3..6766737b5 100644 --- a/lib/Gitlab/Api/Repositories.php +++ b/lib/Gitlab/Api/Repositories.php @@ -102,12 +102,13 @@ public function createTag($project_id, $name, $ref, $message = null) * * @return mixed */ - public function createRelease( $project_id, $tag_name, $description ) { - return $this->post( $this->getProjectPath( $project_id, 'repository/tags/' . $this->encodeBranch( $tag_name ) . '/release' ), array( + public function createRelease($project_id, $tag_name, $description) + { + return $this->post($this->getProjectPath($project_id, 'repository/tags/' . $this->encodeBranch($tag_name) . '/release'), array( 'id' => $project_id, 'tag_name' => $tag_name, 'description' => $description - ) ); + )); } /** @@ -117,12 +118,13 @@ public function createRelease( $project_id, $tag_name, $description ) { * * @return mixed */ - public function updateRelease( $project_id, $tag_name, $description ) { - return $this->put( $this->getProjectPath( $project_id, 'repository/tags/' . $this->encodeBranch( $tag_name ) . '/release' ), array( + public function updateRelease($project_id, $tag_name, $description) + { + return $this->put($this->getProjectPath($project_id, 'repository/tags/' . $this->encodeBranch($tag_name) . '/release'), array( 'id' => $project_id, 'tag_name' => $tag_name, 'description' => $description - ) ); + )); } /** diff --git a/lib/Gitlab/Client.php b/lib/Gitlab/Client.php index e0e10e651..9bcf5ec43 100644 --- a/lib/Gitlab/Client.php +++ b/lib/Gitlab/Client.php @@ -162,7 +162,7 @@ public function jobs() */ public function mergeRequests() { - return new Api\MergeRequests($this); + return new Api\MergeRequests($this); } /** @@ -194,7 +194,7 @@ public function projects() */ public function repositories() { - return new Api\Repositories($this); + return new Api\Repositories($this); } /** diff --git a/lib/Gitlab/Exception/ErrorException.php b/lib/Gitlab/Exception/ErrorException.php index 322a7082d..49e1a1769 100644 --- a/lib/Gitlab/Exception/ErrorException.php +++ b/lib/Gitlab/Exception/ErrorException.php @@ -7,5 +7,4 @@ */ class ErrorException extends \ErrorException { - } diff --git a/lib/Gitlab/Exception/InvalidArgumentException.php b/lib/Gitlab/Exception/InvalidArgumentException.php index 892a6dc4b..86f9d60e1 100644 --- a/lib/Gitlab/Exception/InvalidArgumentException.php +++ b/lib/Gitlab/Exception/InvalidArgumentException.php @@ -7,5 +7,4 @@ */ class InvalidArgumentException extends \InvalidArgumentException { - } diff --git a/lib/Gitlab/Exception/RuntimeException.php b/lib/Gitlab/Exception/RuntimeException.php index 9d938e2cc..ace4bcca4 100644 --- a/lib/Gitlab/Exception/RuntimeException.php +++ b/lib/Gitlab/Exception/RuntimeException.php @@ -7,5 +7,4 @@ */ class RuntimeException extends \RuntimeException { - } diff --git a/lib/Gitlab/Exception/ValidationFailedException.php b/lib/Gitlab/Exception/ValidationFailedException.php index 9ce6635fe..c6ed9b0b4 100644 --- a/lib/Gitlab/Exception/ValidationFailedException.php +++ b/lib/Gitlab/Exception/ValidationFailedException.php @@ -7,5 +7,4 @@ */ class ValidationFailedException extends ErrorException { - } diff --git a/lib/Gitlab/Model/Group.php b/lib/Gitlab/Model/Group.php index 6844877d9..48923f182 100644 --- a/lib/Gitlab/Model/Group.php +++ b/lib/Gitlab/Model/Group.php @@ -131,9 +131,8 @@ public function removeMember($user_id) */ public function projects() { - $data = $this->client->groups()->projects($this->id); - return Group::fromArray($this->getClient(),$data); + return Group::fromArray($this->getClient(), $data); } } diff --git a/lib/Gitlab/Model/Project.php b/lib/Gitlab/Model/Project.php index 5b35a21f0..0b37fc610 100644 --- a/lib/Gitlab/Model/Project.php +++ b/lib/Gitlab/Model/Project.php @@ -1124,5 +1124,4 @@ public function job($job_id) return Job::fromArray($this->getClient(), $this, $data); } - } diff --git a/test/Gitlab/Tests/Api/RepositoriesTest.php b/test/Gitlab/Tests/Api/RepositoriesTest.php index 95c52fab8..a2907ee17 100644 --- a/test/Gitlab/Tests/Api/RepositoriesTest.php +++ b/test/Gitlab/Tests/Api/RepositoriesTest.php @@ -167,53 +167,55 @@ public function shouldCreateTag() $this->assertEquals($expectedArray, $api->createTag(1, '1.0', 'abcd1234', '1.0 release')); } - /** - * @test - */ - public function shouldCreateRelease() { - $project_id = 1; - $tagName = 'sometag'; - $description = '1.0 release'; - - $expectedArray = array( 'name' => $tagName ); - - $api = $this->getApiMock(); - $api->expects( $this->once()) - ->method('post') - ->with( 'projects/' . $project_id . '/repository/tags/' . $tagName . '/release', array( - 'id' => $project_id, - 'tag_name' => $tagName, - 'description' => $description - )) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals( $expectedArray, $api->createRelease( $project_id, $tagName, $description ) ); - } - - /** - * @test - */ - public function shouldUpdateRelease() { - $project_id = 1; - $tagName = 'sometag'; - $description = '1.0 release'; - - $expectedArray = array( 'description' => $tagName ); - - $api = $this->getApiMock(); - $api->expects( $this->once()) - ->method('put') - ->with( 'projects/' . $project_id . '/repository/tags/' . $tagName . '/release', array( - 'id' => $project_id, - 'tag_name' => $tagName, - 'description' => $description - )) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals( $expectedArray, $api->updateRelease( $project_id, $tagName, $description ) ); - } + /** + * @test + */ + public function shouldCreateRelease() + { + $project_id = 1; + $tagName = 'sometag'; + $description = '1.0 release'; + + $expectedArray = array( 'name' => $tagName ); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/' . $project_id . '/repository/tags/' . $tagName . '/release', array( + 'id' => $project_id, + 'tag_name' => $tagName, + 'description' => $description + )) + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->createRelease($project_id, $tagName, $description)); + } + + /** + * @test + */ + public function shouldUpdateRelease() + { + $project_id = 1; + $tagName = 'sometag'; + $description = '1.0 release'; + + $expectedArray = array( 'description' => $tagName ); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('put') + ->with('projects/' . $project_id . '/repository/tags/' . $tagName . '/release', array( + 'id' => $project_id, + 'tag_name' => $tagName, + 'description' => $description + )) + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->updateRelease($project_id, $tagName, $description)); + } /** * @test diff --git a/test/Gitlab/Tests/HttpClient/BuilderTest.php b/test/Gitlab/Tests/HttpClient/BuilderTest.php index fa51bdd2f..1792f68ff 100644 --- a/test/Gitlab/Tests/HttpClient/BuilderTest.php +++ b/test/Gitlab/Tests/HttpClient/BuilderTest.php @@ -1,6 +1,7 @@ willReturn($promise) ; - $this->assertEquals($promise, $plugin->handleRequest($request, [$callback, 'next'], function () {})); + $this->assertEquals($promise, $plugin->handleRequest($request, [$callback, 'next'], function () { + })); } public function testPrefixRequestPath() @@ -45,7 +45,8 @@ public function testPrefixRequestPath() ->with($expected) ; - $plugin->handleRequest($request, [$callback, 'next'], function () {}); + $plugin->handleRequest($request, [$callback, 'next'], function () { + }); } public function testNoPrefixingRequired() @@ -62,6 +63,7 @@ public function testNoPrefixingRequired() ->with($request) ; - $plugin->handleRequest($request, [$callback, 'next'], function () {}); + $plugin->handleRequest($request, [$callback, 'next'], function () { + }); } } diff --git a/test/Gitlab/Tests/ResultPagerTest.php b/test/Gitlab/Tests/ResultPagerTest.php index b411b0704..e91cb5fbd 100644 --- a/test/Gitlab/Tests/ResultPagerTest.php +++ b/test/Gitlab/Tests/ResultPagerTest.php @@ -12,7 +12,6 @@ class ResultPagerTest extends \PHPUnit_Framework_TestCase { - public function testFetch() { $client = $this->getMockBuilder(Client::class) From 6e409e87a9f0ea24814e622d95b8778d3b4081b1 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 1 Aug 2017 14:04:51 +0200 Subject: [PATCH 42/83] move sort option outside createOptionsResolver --- lib/Gitlab/Api/AbstractApi.php | 5 +---- lib/Gitlab/Api/MergeRequests.php | 3 +++ lib/Gitlab/Api/Projects.php | 6 ++++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/Gitlab/Api/AbstractApi.php b/lib/Gitlab/Api/AbstractApi.php index e03123fe9..9bad793b6 100644 --- a/lib/Gitlab/Api/AbstractApi.php +++ b/lib/Gitlab/Api/AbstractApi.php @@ -194,7 +194,7 @@ protected function encodePath($path) } /** - * Create a new OptionsResolver with page, per_page and sort options. + * Create a new OptionsResolver with page and per_page options. * * @return OptionsResolver */ @@ -213,9 +213,6 @@ protected function createOptionsResolver() return $value > 0 && $value <= 100; }) ; - $resolver->setDefined('sort') - ->setAllowedValues('sort', ['asc', 'desc']) - ; return $resolver; } diff --git a/lib/Gitlab/Api/MergeRequests.php b/lib/Gitlab/Api/MergeRequests.php index b7e857dce..fa841a36b 100644 --- a/lib/Gitlab/Api/MergeRequests.php +++ b/lib/Gitlab/Api/MergeRequests.php @@ -51,6 +51,9 @@ public function all($project_id, array $parameters = []) $resolver->setDefined('order_by') ->setAllowedValues('order_by', ['created_at', 'updated_at']) ; + $resolver->setDefined('sort') + ->setAllowedValues('sort', ['asc', 'desc']) + ; $resolver->setDefined('milestone'); $resolver->setDefined('view') ->setAllowedValues('view', ['simple']) diff --git a/lib/Gitlab/Api/Projects.php b/lib/Gitlab/Api/Projects.php index 08caf5042..192760384 100644 --- a/lib/Gitlab/Api/Projects.php +++ b/lib/Gitlab/Api/Projects.php @@ -45,6 +45,9 @@ public function all(array $parameters = []) $resolver->setDefined('order_by') ->setAllowedValues('order_by', ['id', 'name', 'path', 'created_at', 'updated_at', 'last_activity_at']) ; + $resolver->setDefined('sort') + ->setAllowedValues('sort', ['asc', 'desc']) + ; $resolver->setDefined('search'); $resolver->setDefined('simple') ->setAllowedTypes('simple', 'bool') @@ -187,6 +190,9 @@ public function pipelines($project_id, array $parameters = []) $resolver->setDefined('order_by') ->setAllowedValues('order_by', ['id', 'status', 'ref', 'user_id']) ; + $resolver->setDefined('sort') + ->setAllowedValues('sort', ['asc', 'desc']) + ; return $this->get($this->getProjectPath($project_id, 'pipelines'), $resolver->resolve($parameters)); } From 0f5663245921505761cc0748beff9dbe62f61ad5 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 1 Aug 2017 14:10:37 +0200 Subject: [PATCH 43/83] use OptionsResolver in DeployKeys api --- UPGRADE.md | 4 ++++ lib/Gitlab/Api/DeployKeys.php | 20 ++++++-------------- test/Gitlab/Tests/Api/DeployKeysTest.php | 11 ++--------- 3 files changed, 12 insertions(+), 23 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index f3ec4909b..6ec0e0005 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -13,6 +13,10 @@ See [documentation](doc/customize.md) to know how to customize the client timeou * The `setHttpClient` method have been removed. Use a `Gitlab\HttpClient\Builder` instead. * The `getHttpClient` method return type is changed to `Http\Client\Common\HttpMethodsClient`. +## `Gitlab\Api\DeployKeys` changes + +* The `all` method now take a single argument which is an associative array of query string parameters. +* The `ORDER_BY` and `SORT` class constants have been removed. ## `Gitlab\Api\Groups` changes diff --git a/lib/Gitlab/Api/DeployKeys.php b/lib/Gitlab/Api/DeployKeys.php index f7e2a39d5..32e0a82cb 100644 --- a/lib/Gitlab/Api/DeployKeys.php +++ b/lib/Gitlab/Api/DeployKeys.php @@ -2,23 +2,15 @@ class DeployKeys extends AbstractApi { - const ORDER_BY = 'id'; - const SORT = 'asc'; - /** - * @param int $page - * @param int $per_page - * @param string $order_by - * @param string $sort + * @param array $parameters + * * @return mixed */ - public function all($page = 1, $per_page = self::PER_PAGE, $order_by = self::ORDER_BY, $sort = self::SORT) + public function all(array $parameters = []) { - return $this->get('deploy_keys', array( - 'page' => $page, - 'per_page' => $per_page, - 'order_by' => $order_by, - 'sort' => $sort - )); + $resolver = $this->createOptionsResolver(); + + return $this->get('deploy_keys', $resolver->resolve($parameters)); } } diff --git a/test/Gitlab/Tests/Api/DeployKeysTest.php b/test/Gitlab/Tests/Api/DeployKeysTest.php index 9ea069487..25a796040 100644 --- a/test/Gitlab/Tests/Api/DeployKeysTest.php +++ b/test/Gitlab/Tests/Api/DeployKeysTest.php @@ -9,21 +9,14 @@ public function shouldGetAllDeployKeys() { $expectedArray = $this->getMultipleDeployKeysData(); - $api = $this->getMultipleDeployKeysRequestMock('deploy_keys', $expectedArray); - - $this->assertEquals($expectedArray, $api->all()); - } - - protected function getMultipleDeployKeysRequestMock($path, $expectedArray = array(), $page = 1, $per_page = 20, $order_by = 'id', $sort = 'asc') - { $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with($path, array('page' => $page, 'per_page' => $per_page, 'order_by' => $order_by, 'sort' => $sort)) + ->with('deploy_keys', array('page' => 2, 'per_page' => 5)) ->will($this->returnValue($expectedArray)) ; - return $api; + $this->assertEquals($expectedArray, $api->all(['page' => 2, 'per_page' => 5])); } protected function getMultipleDeployKeysData() From 42fabca9513b8a4874d91cc0eeb42150a688a438 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 1 Aug 2017 14:46:51 +0200 Subject: [PATCH 44/83] use OptionsResolver in IssueBoards api --- UPGRADE.md | 4 ++++ lib/Gitlab/Api/IssueBoards.php | 16 ++++++---------- test/Gitlab/Tests/Api/IssueBoardsTest.php | 4 +--- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 6ec0e0005..a92abd380 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -27,6 +27,10 @@ See [documentation](doc/customize.md) to know how to customize the client timeou * The second argument of `update`, `remove`, `showComments`, `showComment`, `addComment`, `updateComment`, `removeComment`, `setTimeEstimate`, `resetTimeEstimate`, `addSpentTime` and `resetSpentTime` methods is now a scoped issue id (iid). +## `Gitlab\Api\IssueBoards` changes + +* The `all` method second and subsequent arguments have been replaced by a single associative array of query string parameters. + ## `Gitlab\Api\MergeRequests` changes * The `getList`, `getByIid`, `merged`, `opened` and `closed` methods have been removed. Use `all` method instead. diff --git a/lib/Gitlab/Api/IssueBoards.php b/lib/Gitlab/Api/IssueBoards.php index 1790f5d34..e5d460bc5 100644 --- a/lib/Gitlab/Api/IssueBoards.php +++ b/lib/Gitlab/Api/IssueBoards.php @@ -4,21 +4,17 @@ class IssueBoards extends AbstractApi { /** * @param int $project_id - * @param int $page - * @param int $per_page - * @param array $params + * @param array $parameters + * * @return mixed */ - public function all($project_id = null, $page = 1, $per_page = self::PER_PAGE, array $params = array()) + public function all($project_id = null, array $parameters = []) { - $path = $project_id === null ? 'boards' : $this->getProjectPath($project_id, 'boards'); + $resolver = $this->createOptionsResolver(); - $params = array_merge(array( - 'page' => $page, - 'per_page' => $per_page - ), $params); + $path = $project_id === null ? 'boards' : $this->getProjectPath($project_id, 'boards'); - return $this->get($path, $params); + return $this->get($path, $resolver->resolve($parameters)); } /** diff --git a/test/Gitlab/Tests/Api/IssueBoardsTest.php b/test/Gitlab/Tests/Api/IssueBoardsTest.php index 0cce48dbc..40c356d0b 100644 --- a/test/Gitlab/Tests/Api/IssueBoardsTest.php +++ b/test/Gitlab/Tests/Api/IssueBoardsTest.php @@ -1,7 +1,5 @@ getApiMock(); $api->expects($this->once()) ->method('get') - ->with('boards', array('page' => 1, 'per_page' => AbstractApi::PER_PAGE)) + ->with('boards', array()) ->will($this->returnValue($expectedArray)) ; From 2de90ec100f91607735e7f9a53dabb0689e34bf7 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 1 Aug 2017 14:58:20 +0200 Subject: [PATCH 45/83] use OptionsResolver in Issues api --- UPGRADE.md | 1 + lib/Gitlab/Api/Issues.php | 46 +++++++++++++++++++++------- test/Gitlab/Tests/Api/IssuesTest.php | 10 +++--- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index a92abd380..d540ec309 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -26,6 +26,7 @@ See [documentation](doc/customize.md) to know how to customize the client timeou * The second argument of `update`, `remove`, `showComments`, `showComment`, `addComment`, `updateComment`, `removeComment`, `setTimeEstimate`, `resetTimeEstimate`, `addSpentTime` and `resetSpentTime` methods is now a scoped issue id (iid). +* The `all` method second and subsequent arguments have been replaced by a single associative array of query string parameters. ## `Gitlab\Api\IssueBoards` changes diff --git a/lib/Gitlab/Api/Issues.php b/lib/Gitlab/Api/Issues.php index d549578f3..9eb7e67a4 100644 --- a/lib/Gitlab/Api/Issues.php +++ b/lib/Gitlab/Api/Issues.php @@ -4,22 +4,46 @@ class Issues extends AbstractApi { /** * @param int $project_id - * @param int $page - * @param int $per_page - * @param array $params + * @param array $parameters ( + * + * @var string $state Return all issues or just those that are opened or closed. + * @var string $labels Comma-separated list of label names, issues must have all labels to be returned. + * No+Label lists all issues with no labels. + * @var string $milestone The milestone title. + * @var int[] $iids Return only the issues having the given iid. + * @var string $order_by Return requests ordered by created_at or updated_at fields. Default is created_at. + * @var string $sort Return requests sorted in asc or desc order. Default is desc. + * @var string $search Search issues against their title and description. + * ) + * * @return mixed */ - public function all($project_id = null, $page = 1, $per_page = self::PER_PAGE, array $params = array()) + public function all($project_id = null, array $parameters = []) { - $path = $project_id === null ? 'issues' : $this->getProjectPath($project_id, 'issues'); + $resolver = $this->createOptionsResolver(); + + $resolver->setDefined('state') + ->setAllowedValues('state', ['opened', 'closed']) + ; + $resolver->setDefined('labels'); + $resolver->setDefined('milestone'); + $resolver->setDefined('iids') + ->setAllowedTypes('iids', 'array') + ->setAllowedValues('iids', function (array $value) { + return count($value) == count(array_filter($value, 'is_int')); + }) + ; + $resolver->setDefined('order_by') + ->setAllowedValues('order_by', ['created_at', 'updated_at']) + ; + $resolver->setDefined('sort') + ->setAllowedValues('sort', ['asc', 'desc']) + ; + $resolver->setDefined('search'); - $params = array_intersect_key($params, array('labels' => '', 'state' => '', 'sort' => '', 'order_by' => '', 'milestone' => '')); - $params = array_merge(array( - 'page' => $page, - 'per_page' => $per_page - ), $params); + $path = $project_id === null ? 'issues' : $this->getProjectPath($project_id, 'issues'); - return $this->get($path, $params); + return $this->get($path, $resolver->resolve($parameters)); } /** diff --git a/test/Gitlab/Tests/Api/IssuesTest.php b/test/Gitlab/Tests/Api/IssuesTest.php index 6b5bc3759..0bd9e66fa 100644 --- a/test/Gitlab/Tests/Api/IssuesTest.php +++ b/test/Gitlab/Tests/Api/IssuesTest.php @@ -1,7 +1,5 @@ getApiMock(); $api->expects($this->once()) ->method('get') - ->with('issues', array('page' => 1, 'per_page' => AbstractApi::PER_PAGE)) + ->with('issues', array()) ->will($this->returnValue($expectedArray)) ; @@ -41,7 +39,7 @@ public function shouldGetProjectIssuesWithPagination() ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->all(1, 2, 5)); + $this->assertEquals($expectedArray, $api->all(1, ['page' => 2, 'per_page' => 5])); } /** @@ -57,11 +55,11 @@ public function shouldGetProjectIssuesWithParams() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/issues', array('page' => 2, 'per_page' => 5, 'order_by' => 'created_at', 'sort' => 'desc', 'labels' => 'foo,bar', 'state' => 'open')) + ->with('projects/1/issues', array('order_by' => 'created_at', 'sort' => 'desc', 'labels' => 'foo,bar', 'state' => 'opened')) ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->all(1, 2, 5, array('order_by' => 'created_at', 'sort' => 'desc', 'labels' => 'foo,bar', 'state' => 'open'))); + $this->assertEquals($expectedArray, $api->all(1, array('order_by' => 'created_at', 'sort' => 'desc', 'labels' => 'foo,bar', 'state' => 'opened'))); } /** From f338fc82cebfbf7016db6eff1ef71aac7fd7eec5 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 1 Aug 2017 15:14:29 +0200 Subject: [PATCH 46/83] Use OptionsResolver in Groups::all --- UPGRADE.md | 2 + lib/Gitlab/Api/Groups.php | 62 +++++++++++++++++++--------- test/Gitlab/Tests/Api/GroupsTest.php | 44 +------------------- 3 files changed, 46 insertions(+), 62 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index d540ec309..e3d0613dd 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -21,6 +21,8 @@ See [documentation](doc/customize.md) to know how to customize the client timeou ## `Gitlab\Api\Groups` changes * The `visibility_level` parameter have been removed from `create` method. Use `visibility` instead. +* The `all` method now take a single argument which is an associative array of query string parameters. +* The `search` method have been removed. Use `all` method instead. ## `Gitlab\Api\Issues` changes diff --git a/lib/Gitlab/Api/Groups.php b/lib/Gitlab/Api/Groups.php index ef98265e7..9ecf17f91 100644 --- a/lib/Gitlab/Api/Groups.php +++ b/lib/Gitlab/Api/Groups.php @@ -3,30 +3,52 @@ class Groups extends AbstractApi { /** - * @param int $page - * @param int $per_page + * @param array $parameters ( + * + * @var int[] $skip_groups Skip the group IDs passes. + * @var bool $all_available Show all the groups you have access to. + * @var string $search Return list of authorized groups matching the search criteria. + * @var string $order_by Order groups by name or path. Default is name. + * @var string $sort Order groups in asc or desc order. Default is asc. + * @var bool $statistics Include group statistics (admins only). + * @var bool $owned Limit by groups owned by the current user. + * ) * @return mixed */ - public function all($page = 1, $per_page = self::PER_PAGE) + public function all(array $parameters = []) { - return $this->get('groups', array( - 'page' => $page, - 'per_page' => $per_page - )); - } + $resolver = $this->createOptionsResolver(); + $booleanNormalizer = function ($value) { + return $value ? 'true' : 'false'; + }; - /** - * @param string $query - * @param int $page - * @param int $per_page - * @return mixed - */ - public function search($query, $page = 1, $per_page = self::PER_PAGE) - { - return $this->get('groups?search='.$this->encodePath($query), array( - 'page' => $page, - 'per_page' => $per_page - )); + $resolver->setDefined('skip_groups') + ->setAllowedTypes('skip_groups', 'array') + ->setAllowedValues('skip_groups', function (array $value) { + return count($value) == count(array_filter($value, 'is_int')); + }) + ; + $resolver->setDefined('all_available') + ->setAllowedTypes('all_available', 'bool') + ->setNormalizer('all_available', $booleanNormalizer) + ; + $resolver->setDefined('search'); + $resolver->setDefined('order_by') + ->setAllowedValues('order_by', ['name', 'path']) + ; + $resolver->setDefined('sort') + ->setAllowedValues('sort', ['asc', 'desc']) + ; + $resolver->setDefined('statistics') + ->setAllowedTypes('statistics', 'bool') + ->setNormalizer('statistics', $booleanNormalizer) + ; + $resolver->setDefined('owned') + ->setAllowedTypes('owned', 'bool') + ->setNormalizer('owned', $booleanNormalizer) + ; + + return $this->get('groups', $resolver->resolve($parameters)); } /** diff --git a/test/Gitlab/Tests/Api/GroupsTest.php b/test/Gitlab/Tests/Api/GroupsTest.php index 00afe60eb..1d244b967 100644 --- a/test/Gitlab/Tests/Api/GroupsTest.php +++ b/test/Gitlab/Tests/Api/GroupsTest.php @@ -21,7 +21,7 @@ public function shouldGetAllGroups() ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->all(1, 10)); + $this->assertEquals($expectedArray, $api->all(['page' => 1, 'per_page' => 10])); } /** @@ -37,53 +37,13 @@ public function shouldNotNeedPaginationWhenGettingGroups() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('groups', array('page' => 1, 'per_page' => AbstractApi::PER_PAGE)) + ->with('groups', array()) ->will($this->returnValue($expectedArray)) ; $this->assertEquals($expectedArray, $api->all()); } - /** - * @test - */ - public function shouldSearchGroups() - { - $expectedArray = array( - array('id' => 1, 'name' => 'A group'), - array('id' => 2, 'name' => 'Another group'), - ); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('groups?search=some%20group', array('page' => 1, 'per_page' => AbstractApi::PER_PAGE)) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->search('some group')); - } - - /** - * @test - */ - public function shouldSearchGroupsWithPagination() - { - $expectedArray = array( - array('id' => 1, 'name' => 'A group'), - array('id' => 2, 'name' => 'Another group'), - ); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('groups?search=group', array('page' => 2, 'per_page' => 5)) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->search('group', 2, 5)); - } - /** * @test */ From 049dba3448e82e1bec12f5d8e2c6075b0fdd8603 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 1 Aug 2017 15:54:46 +0200 Subject: [PATCH 47/83] Use OptionsResolver in Groups::members --- UPGRADE.md | 1 + lib/Gitlab/Api/Groups.php | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index e3d0613dd..1f38be894 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -23,6 +23,7 @@ See [documentation](doc/customize.md) to know how to customize the client timeou * The `visibility_level` parameter have been removed from `create` method. Use `visibility` instead. * The `all` method now take a single argument which is an associative array of query string parameters. * The `search` method have been removed. Use `all` method instead. +* The `members` method second and subsequent arguments have been replaced by a single associative array of query string parameters. ## `Gitlab\Api\Issues` changes diff --git a/lib/Gitlab/Api/Groups.php b/lib/Gitlab/Api/Groups.php index 9ecf17f91..77fd1ed97 100644 --- a/lib/Gitlab/Api/Groups.php +++ b/lib/Gitlab/Api/Groups.php @@ -107,17 +107,20 @@ public function transfer($group_id, $project_id) } /** - * @param int $id - * @param int $page - * @param int $per_page + * @param int $id + * @param array $parameters ( + * + * @var string $query A query string to search for members. + * ) + * * @return mixed */ - public function members($id, $page = 1, $per_page = self::PER_PAGE) + public function members($id, array $parameters = []) { - return $this->get('groups/'.$this->encodePath($id).'/members', array( - 'page' => $page, - 'per_page' => $per_page - )); + $resolver = $this->createOptionsResolver(); + $resolver->setDefined('query'); + + return $this->get('groups/'.$this->encodePath($id).'/members', $resolver->resolve($parameters)); } /** From ee2b0e633a5a1e21e8e910de7440d719e9b8cd1e Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 1 Aug 2017 16:03:52 +0200 Subject: [PATCH 48/83] Use OptionsResolver in Groups::projects --- UPGRADE.md | 1 + lib/Gitlab/Api/Groups.php | 54 ++++++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 1f38be894..5311807da 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -24,6 +24,7 @@ See [documentation](doc/customize.md) to know how to customize the client timeou * The `all` method now take a single argument which is an associative array of query string parameters. * The `search` method have been removed. Use `all` method instead. * The `members` method second and subsequent arguments have been replaced by a single associative array of query string parameters. +* The `projects` method second and subsequent arguments have been replaced by a single associative array of query string parameters. ## `Gitlab\Api\Issues` changes diff --git a/lib/Gitlab/Api/Groups.php b/lib/Gitlab/Api/Groups.php index 77fd1ed97..94484ead5 100644 --- a/lib/Gitlab/Api/Groups.php +++ b/lib/Gitlab/Api/Groups.php @@ -162,15 +162,55 @@ public function removeMember($group_id, $user_id) /** * @param $id - * @param int $page - * @param int $per_page + * @param array $parameters ( + * + * @var bool $archived Limit by archived status. + * @var string $visibility Limit by visibility public, internal, or private. + * @var string $order_by Return projects ordered by id, name, path, created_at, updated_at, or last_activity_at fields. + * Default is created_at. + * @var string $sort Return projects sorted in asc or desc order. Default is desc. + * @var string $search Return list of authorized projects matching the search criteria. + * @var bool $simple Return only the ID, URL, name, and path of each project. + * @var bool $owned Limit by projects owned by the current user. + * @var bool $starred Limit by projects starred by the current user. + * ) + * * @return mixed */ - public function projects($id, $page = 1, $per_page = self::PER_PAGE) + public function projects($id, array $parameters = []) { - return $this->get('groups/'.$this->encodePath($id).'/projects', array( - 'page' => $page, - 'per_page' => $per_page - )); + $resolver = $this->createOptionsResolver(); + $booleanNormalizer = function ($value) { + return $value ? 'true' : 'false'; + }; + + $resolver->setDefined('archived') + ->setAllowedTypes('archived', 'bool') + ->setNormalizer('archived', $booleanNormalizer) + ; + $resolver->setDefined('visibility') + ->setAllowedValues('visibility', ['public', 'internal', 'private']) + ; + $resolver->setDefined('order_by') + ->setAllowedValues('order_by', ['id', 'name', 'path', 'created_at', 'updated_at', 'last_activity_at']) + ; + $resolver->setDefined('sort') + ->setAllowedValues('sort', ['asc', 'desc']) + ; + $resolver->setDefined('search'); + $resolver->setDefined('simple') + ->setAllowedTypes('simple', 'bool') + ->setNormalizer('simple', $booleanNormalizer) + ; + $resolver->setDefined('owned') + ->setAllowedTypes('owned', 'bool') + ->setNormalizer('owned', $booleanNormalizer) + ; + $resolver->setDefined('starred') + ->setAllowedTypes('starred', 'bool') + ->setNormalizer('starred', $booleanNormalizer) + ; + + return $this->get('groups/'.$this->encodePath($id).'/projects', $resolver->resolve($parameters)); } } From 14f294c86347fa15f678cf04b37fb4f81a8309cc Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 1 Aug 2017 16:41:19 +0200 Subject: [PATCH 49/83] use OptionsResolver in Jobs api --- lib/Gitlab/Api/Jobs.php | 65 +++++++++++++++++++++++++----- test/Gitlab/Tests/Api/JobsTest.php | 6 +-- 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/lib/Gitlab/Api/Jobs.php b/lib/Gitlab/Api/Jobs.php index 246f8f148..2bec56796 100644 --- a/lib/Gitlab/Api/Jobs.php +++ b/lib/Gitlab/Api/Jobs.php @@ -1,6 +1,7 @@ get("projects/".$this->encodePath($project_id)."/jobs", array( - 'scope' => $scope - )); + $resolver = $this->createOptionsResolver(); + + return $this->get("projects/".$this->encodePath($project_id)."/jobs", $resolver->resolve($parameters)); } /** * @param int|string $project_id * @param int $pipeline_id - * @param array $scope + * @param array $parameters ( + * + * @var string|string[] $scope The scope of jobs to show, one or array of: created, pending, running, failed, + * success, canceled, skipped, manual; showing all jobs if none provided. + * ) + * * @return mixed */ - public function pipelineJobs($project_id, $pipeline_id, array $scope = []) + public function pipelineJobs($project_id, $pipeline_id, array $parameters = []) { - return $this->get("projects/".$this->encodePath($project_id)."/pipelines/".$this->encodePath($pipeline_id)."/jobs", array( - 'scope' => $scope - )); + $resolver = $this->createOptionsResolver(); + + return $this->get( + $this->getProjectPath($project_id, 'pipelines/').$this->encodePath($pipeline_id)."/jobs", + $resolver->resolve($parameters) + ); } /** @@ -130,4 +144,35 @@ public function play($project_id, $job_id) { return $this->post("projects/".$this->encodePath($project_id)."/jobs/".$this->encodePath($job_id)."/play"); } + + /** + * {@inheritdoc} + */ + protected function createOptionsResolver() + { + $allowedScopeValues = [ + self::SCOPE_CANCELED, + self::SCOPE_CREATED, + self::SCOPE_FAILED, + self::SCOPE_MANUAL, + self::SCOPE_PENDING, + self::SCOPE_RUNNING, + self::SCOPE_SKIPPED, + self::SCOPE_SUCCESS, + ]; + + $resolver = parent::createOptionsResolver(); + $resolver->setDefined('scope') + ->setAllowedTypes('scope', ['string', 'array']) + ->setAllowedValues('scope', $allowedScopeValues) + ->addAllowedValues('scope', function ($value) use ($allowedScopeValues) { + return is_array($value) && empty(array_diff($value, $allowedScopeValues)); + }) + ->setNormalizer('scope', function (OptionsResolver $resolver, $value) { + return (array) $value; + }) + ; + + return $resolver; + } } diff --git a/test/Gitlab/Tests/Api/JobsTest.php b/test/Gitlab/Tests/Api/JobsTest.php index c002437dc..d8188ea35 100644 --- a/test/Gitlab/Tests/Api/JobsTest.php +++ b/test/Gitlab/Tests/Api/JobsTest.php @@ -24,7 +24,7 @@ public function shouldGetAllJobs() ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->all(1, [Jobs::SCOPE_PENDING])); + $this->assertEquals($expectedArray, $api->all(1, ['scope' => Jobs::SCOPE_PENDING])); } /** @@ -41,12 +41,12 @@ public function shouldGetPipelineJobs() $api->expects($this->once()) ->method('get') ->with('projects/1/pipelines/2/jobs', array( - 'scope' => ['pending'] + 'scope' => ['pending', 'running'] )) ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->pipelineJobs(1, 2, [Jobs::SCOPE_PENDING])); + $this->assertEquals($expectedArray, $api->pipelineJobs(1, 2, ['scope' => [Jobs::SCOPE_PENDING, Jobs::SCOPE_RUNNING]])); } /** From f1c3bb62914a7ee8411ddd41b39f5beae38fffcc Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 1 Aug 2017 16:52:42 +0200 Subject: [PATCH 50/83] use OptionsResolver in Milestones api --- UPGRADE.md | 4 ++++ lib/Gitlab/Api/Milestones.php | 28 +++++++++++++++++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 5311807da..59d882c27 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -43,6 +43,10 @@ See [documentation](doc/customize.md) to know how to customize the client timeou * The `all` method now take a single argument which is an associative array of query string parameters. * The `getNotes` method now take only two arguments, the project id and the merge request iid. +## `Gitlab\Api\Milestones` changes + +* The `all` method second and subsequent arguments have been replaced by a single associative array of query string parameters. + ## `Gitlab\Api\Projects` changes * The `keys`, `key`, `addKey`, `removeKey`, `disableKey` and `enableKey` methods have been removed. diff --git a/lib/Gitlab/Api/Milestones.php b/lib/Gitlab/Api/Milestones.php index 3b1528183..0f9b2d25e 100644 --- a/lib/Gitlab/Api/Milestones.php +++ b/lib/Gitlab/Api/Milestones.php @@ -4,16 +4,30 @@ class Milestones extends AbstractApi { /** * @param int $project_id - * @param int $page - * @param int $per_page + * @param array $parameters ( + * + * @var int[] $iids Return only the milestones having the given iids. + * @var string $state Return only active or closed milestones. + * @var string $search Return only milestones with a title or description matching the provided string. + * ) + * * @return mixed */ - public function all($project_id, $page = 1, $per_page = self::PER_PAGE) + public function all($project_id, array $parameters = []) { - return $this->get($this->getProjectPath($project_id, 'milestones'), array( - 'page' => $page, - 'per_page' => $per_page - )); + $resolver = $this->createOptionsResolver(); + $resolver->setDefined('iids') + ->setAllowedTypes('iids', 'array') + ->setAllowedValues('iids', function (array $value) { + return count($value) == count(array_filter($value, 'is_int')); + }) + ; + $resolver->setDefined('state') + ->setAllowedValues('state', ['active', 'closed']) + ; + $resolver->setDefined('search'); + + return $this->get($this->getProjectPath($project_id, 'milestones'), $resolver->resolve($parameters)); } /** From 78c9c49bf5bc3e31a76715adef4dc630c587f780 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 1 Aug 2017 16:57:27 +0200 Subject: [PATCH 51/83] use OptionsResolver in ProjectNamespaces api --- UPGRADE.md | 5 +++ lib/Gitlab/Api/ProjectNamespaces.php | 30 ++++---------- .../Tests/Api/ProjectNamespacesTest.php | 41 +------------------ 3 files changed, 15 insertions(+), 61 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 59d882c27..4aef8b008 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -58,6 +58,11 @@ Use the `deployKeys`, `deployKey`, `addDeployKey`, `deleteDeployKey`, `removeDep * The `builds` method have been removed. Use `Gitlab\Api\Jobs::all` instead. * The `build` method have been removed. Use `Gitlab\Api\Jobs::show` instead. +## `Gitlab\Api\ProjectNamespaces` changes + +* The `search` method have been removed. Use `all` method instead. +* The `all` method now take a single argument which is an associative array of query string parameters. + ## `Gitlab\Api\Repositories` changes * The `commits` page argument now start from 1 instead of 0. diff --git a/lib/Gitlab/Api/ProjectNamespaces.php b/lib/Gitlab/Api/ProjectNamespaces.php index 480fa79c8..815d4e083 100644 --- a/lib/Gitlab/Api/ProjectNamespaces.php +++ b/lib/Gitlab/Api/ProjectNamespaces.php @@ -3,30 +3,18 @@ class ProjectNamespaces extends AbstractApi { /** - * @param int $page - * @param int $per_page + * @param array $parameters ( + * + * @var string $search Returns a list of namespaces the user is authorized to see based on the search criteria. + * ) + * * @return mixed */ - public function all($page = 1, $per_page = self::PER_PAGE) + public function all(array $parameters = []) { - return $this->get('namespaces', array( - 'page' => $page, - 'per_page' => $per_page - )); - } + $resolver = $this->createOptionsResolver(); + $resolver->setDefined('search'); - /** - * @param string $terms - * @param int $page - * @param int $per_page - * @return mixed - */ - public function search($terms, $page = 1, $per_page = self::PER_PAGE) - { - return $this->get('namespaces', array( - 'search' => $terms, - 'page' => $page, - 'per_page' => $per_page - )); + return $this->get('namespaces', $resolver->resolve($parameters)); } } diff --git a/test/Gitlab/Tests/Api/ProjectNamespacesTest.php b/test/Gitlab/Tests/Api/ProjectNamespacesTest.php index 89a273cd1..049027924 100644 --- a/test/Gitlab/Tests/Api/ProjectNamespacesTest.php +++ b/test/Gitlab/Tests/Api/ProjectNamespacesTest.php @@ -17,51 +17,12 @@ public function shouldGetAllNamespaces() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('namespaces', array('page' => 1, 'per_page' => 10)) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->all(1, 10)); - } - - /** - * @test - */ - public function shouldNotNeedPaginationWhenGettingNamespaces() - { - $expectedArray = array( - array('id' => 1, 'name' => 'bespokes'), - array('id' => 2, 'name' => 'internal') - ); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('namespaces', array('page' => 1, 'per_page' => AbstractApi::PER_PAGE)) + ->with('namespaces', array()) ->will($this->returnValue($expectedArray)) ; $this->assertEquals($expectedArray, $api->all()); } - /** - * @test - */ - public function shouldSearchNamespaces() - { - $expectedArray = array( - array('id' => 1, 'name' => 'bespokes'), - array('id' => 2, 'name' => 'internal') - ); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('namespaces', array('search' => 'term', 'page' => 1, 'per_page' => 10)) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->search('term', 1, 10)); - } protected function getApiClass() { From 76f77f699e923f75acddc3978c3c17003204600f Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 1 Aug 2017 17:05:55 +0200 Subject: [PATCH 52/83] Use OptionsResolver in Projects::hooks --- lib/Gitlab/Api/Projects.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/Gitlab/Api/Projects.php b/lib/Gitlab/Api/Projects.php index 192760384..0bee607e9 100644 --- a/lib/Gitlab/Api/Projects.php +++ b/lib/Gitlab/Api/Projects.php @@ -299,16 +299,15 @@ public function removeMember($project_id, $user_id) /** * @param int $project_id - * @param int $page - * @param int $per_page + * @param array $parameters + * * @return mixed */ - public function hooks($project_id, $page = 1, $per_page = self::PER_PAGE) + public function hooks($project_id, array $parameters = []) { - return $this->get($this->getProjectPath($project_id, 'hooks'), array( - 'page' => $page, - 'per_page' => $per_page - )); + $resolver = $this->createOptionsResolver(); + + return $this->get($this->getProjectPath($project_id, 'hooks'), $resolver->resolve($parameters)); } /** From a7d94b67da5073f443307c29c1a62a7f531ae443 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 1 Aug 2017 17:19:48 +0200 Subject: [PATCH 53/83] Use OptionsResolver in Projects::events --- UPGRADE.md | 1 + lib/Gitlab/Api/Projects.php | 40 +++++++++++++++++++++----- test/Gitlab/Tests/Api/ProjectsTest.php | 7 ++--- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 4aef8b008..c8decec8d 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -57,6 +57,7 @@ Use the `deployKeys`, `deployKey`, `addDeployKey`, `deleteDeployKey`, `removeDep * The `trace` method have been removed. Use `Gitlab\Api\Jobs::trace` instead. * The `builds` method have been removed. Use `Gitlab\Api\Jobs::all` instead. * The `build` method have been removed. Use `Gitlab\Api\Jobs::show` instead. +* The `events` method second and subsequent arguments have been replaced by a single associative array of query string parameters. ## `Gitlab\Api\ProjectNamespaces` changes diff --git a/lib/Gitlab/Api/Projects.php b/lib/Gitlab/Api/Projects.php index 0bee607e9..766aa44c2 100644 --- a/lib/Gitlab/Api/Projects.php +++ b/lib/Gitlab/Api/Projects.php @@ -413,16 +413,42 @@ public function enableDeployKey($project_id, $key_id) /** * @param int $project_id - * @param int $page - * @param int $per_page + * @param array $parameters ( + * + * @var string $action Include only events of a particular action type. + * @var string $target_type Include only events of a particular target type. + * @var \DateTimeInterface $before Include only events created before a particular date. + * @var \DateTimeInterface $after Include only events created after a particular date. + * @var string $sort Sort events in asc or desc order by created_at. Default is desc. + * ) + * * @return mixed */ - public function events($project_id, $page = 1, $per_page = self::PER_PAGE) + public function events($project_id, array $parameters = []) { - return $this->get($this->getProjectPath($project_id, 'events'), array( - 'page' => $page, - 'per_page' => $per_page - )); + $resolver = $this->createOptionsResolver(); + $datetimeNormalizer = function (\DateTimeInterface $value) { + return $value->format('Y-m-d'); + }; + + $resolver->setDefined('action') + ->setAllowedValues('action', ['created', 'updated', 'closed', 'reopened', 'pushed', 'commented', 'merged', 'joined', 'left', 'destroyed', 'expired']) + ; + $resolver->setDefined('target_type') + ->setAllowedValues('target_type', ['issue', 'milestone', 'merge_request', 'note', 'project', 'snippet', 'user']) + ; + $resolver->setDefined('before') + ->setAllowedTypes('before', \DateTimeInterface::class) + ->setNormalizer('before', $datetimeNormalizer); + $resolver->setDefined('after') + ->setAllowedTypes('after', \DateTimeInterface::class) + ->setNormalizer('after', $datetimeNormalizer) + ; + $resolver->setDefined('sort') + ->setAllowedValues('sort', ['asc', 'desc']) + ; + + return $this->get($this->getProjectPath($project_id, 'events'), $resolver->resolve($parameters)); } /** diff --git a/test/Gitlab/Tests/Api/ProjectsTest.php b/test/Gitlab/Tests/Api/ProjectsTest.php index 66d09b837..bbc4a0a48 100644 --- a/test/Gitlab/Tests/Api/ProjectsTest.php +++ b/test/Gitlab/Tests/Api/ProjectsTest.php @@ -636,10 +636,7 @@ public function shouldGetEvents() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/events', array( - 'page' => 1, - 'per_page' => AbstractApi::PER_PAGE - )) + ->with('projects/1/events', array()) ->will($this->returnValue($expectedArray)) ; @@ -666,7 +663,7 @@ public function shouldGetEventsWithPagination() ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->events(1, 2, 15)); + $this->assertEquals($expectedArray, $api->events(1, ['page' => 2, 'per_page' => 15])); } /** From 01ee70fe21880b530d7e7abf4030ee6da5711953 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 1 Aug 2017 17:25:34 +0200 Subject: [PATCH 54/83] Use OptionsResolver in Projects::deployments --- UPGRADE.md | 1 + lib/Gitlab/Api/Projects.php | 13 ++++++------- test/Gitlab/Tests/Api/ProjectsTest.php | 7 ++----- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index c8decec8d..be8a7e0f0 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -58,6 +58,7 @@ Use the `deployKeys`, `deployKey`, `addDeployKey`, `deleteDeployKey`, `removeDep * The `builds` method have been removed. Use `Gitlab\Api\Jobs::all` instead. * The `build` method have been removed. Use `Gitlab\Api\Jobs::show` instead. * The `events` method second and subsequent arguments have been replaced by a single associative array of query string parameters. +* The `deployments` method second and subsequent arguments have been replaced by a single associative array of query string parameters. ## `Gitlab\Api\ProjectNamespaces` changes diff --git a/lib/Gitlab/Api/Projects.php b/lib/Gitlab/Api/Projects.php index 766aa44c2..19d61bd96 100644 --- a/lib/Gitlab/Api/Projects.php +++ b/lib/Gitlab/Api/Projects.php @@ -609,16 +609,15 @@ public function uploadFile($project_id, $file) /** * @param int $project_id - * @param int $page - * @param int $per_page + * @param array $parameters + * * @return mixed */ - public function deployments($project_id, $page = 1, $per_page = self::PER_PAGE) + public function deployments($project_id, array $parameters = []) { - return $this->get($this->getProjectPath($project_id, 'deployments'), array( - 'page' => $page, - 'per_page' => $per_page - )); + $resolver = $this->createOptionsResolver(); + + return $this->get($this->getProjectPath($project_id, 'deployments'), $resolver->resolve($parameters)); } /** diff --git a/test/Gitlab/Tests/Api/ProjectsTest.php b/test/Gitlab/Tests/Api/ProjectsTest.php index bbc4a0a48..8515d4d41 100644 --- a/test/Gitlab/Tests/Api/ProjectsTest.php +++ b/test/Gitlab/Tests/Api/ProjectsTest.php @@ -930,10 +930,7 @@ public function shouldGetDeployments() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/deployments', array( - 'page' => 1, - 'per_page' => AbstractApi::PER_PAGE - )) + ->with('projects/1/deployments', array()) ->will($this->returnValue($expectedArray)) ; @@ -960,7 +957,7 @@ public function shouldGetDeploymentsWithPagination() ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->deployments(1, 2, 15)); + $this->assertEquals($expectedArray, $api->deployments(1, ['page' => 2, 'per_page' => 15])); } protected function getMultipleProjectsData() From bfd48ac9a68107ba7f17be669f734809cc55879a Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 1 Aug 2017 17:31:06 +0200 Subject: [PATCH 55/83] Use OptionsResolver in Repositories::commits --- UPGRADE.md | 2 +- lib/Gitlab/Api/Repositories.php | 33 ++++++++++++++++------ test/Gitlab/Tests/Api/RepositoriesTest.php | 4 +-- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index be8a7e0f0..53ca13f50 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -67,8 +67,8 @@ Use the `deployKeys`, `deployKey`, `addDeployKey`, `deleteDeployKey`, `removeDep ## `Gitlab\Api\Repositories` changes -* The `commits` page argument now start from 1 instead of 0. * The `commitBuilds` method have been removed. Use `Gitlab\Api\Projects::pipelines` instead. +* The `commits` method second and subsequent arguments have been replaced by a single associative array of query string parameters. ## `Gitlab\Model\Project` changes diff --git a/lib/Gitlab/Api/Repositories.php b/lib/Gitlab/Api/Repositories.php index 6766737b5..c633f3a07 100644 --- a/lib/Gitlab/Api/Repositories.php +++ b/lib/Gitlab/Api/Repositories.php @@ -129,18 +129,33 @@ public function updateRelease($project_id, $tag_name, $description) /** * @param int $project_id - * @param int $page - * @param int $per_page - * @param null $ref_name + * @param array $parameters ( + * + * @var string $ref_name The name of a repository branch or tag or if not given the default branch. + * @var \DateTimeInterface $since Only commits after or on this date will be returned. + * @var \DateTimeInterface $until Only commits before or on this date will be returned. + * ) + * * @return mixed */ - public function commits($project_id, $page = 1, $per_page = self::PER_PAGE, $ref_name = null) + public function commits($project_id, array $parameters = []) { - return $this->get($this->getProjectPath($project_id, 'repository/commits'), array( - 'page' => $page, - 'per_page' => $per_page, - 'ref_name' => $ref_name - )); + $resolver = $this->createOptionsResolver(); + $datetimeNormalizer = function (\DateTimeInterface $value) { + return $value->format('c'); + }; + + $resolver->setDefined('ref_name'); + $resolver->setDefined('since') + ->setAllowedTypes('since', \DateTimeInterface::class) + ->setNormalizer('since', $datetimeNormalizer) + ; + $resolver->setDefined('until') + ->setAllowedTypes('until', \DateTimeInterface::class) + ->setNormalizer('until', $datetimeNormalizer) + ; + + return $this->get($this->getProjectPath($project_id, 'repository/commits'), $resolver->resolve($parameters)); } /** diff --git a/test/Gitlab/Tests/Api/RepositoriesTest.php b/test/Gitlab/Tests/Api/RepositoriesTest.php index a2907ee17..fcad85309 100644 --- a/test/Gitlab/Tests/Api/RepositoriesTest.php +++ b/test/Gitlab/Tests/Api/RepositoriesTest.php @@ -230,7 +230,7 @@ public function shouldGetCommits() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/repository/commits', array('page' => 1, 'per_page' => AbstractApi::PER_PAGE, 'ref_name' => null)) + ->with('projects/1/repository/commits', array()) ->will($this->returnValue($expectedArray)) ; @@ -254,7 +254,7 @@ public function shouldGetCommitsWithParams() ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->commits(1, 2, 25, 'master')); + $this->assertEquals($expectedArray, $api->commits(1, ['page' => 2, 'per_page' => 25, 'ref_name' => 'master'])); } /** From 35bcdae4b7c2a3ff42261418b94774adf8eb37ab Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 1 Aug 2017 17:33:30 +0200 Subject: [PATCH 56/83] Use OptionsResolver in Repositories::commitComments --- UPGRADE.md | 1 + lib/Gitlab/Api/Repositories.php | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 53ca13f50..d30733671 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -69,6 +69,7 @@ Use the `deployKeys`, `deployKey`, `addDeployKey`, `deleteDeployKey`, `removeDep * The `commitBuilds` method have been removed. Use `Gitlab\Api\Projects::pipelines` instead. * The `commits` method second and subsequent arguments have been replaced by a single associative array of query string parameters. +* The `commitComments` method third and subsequent arguments have been replaced by a single associative array of query string parameters. ## `Gitlab\Model\Project` changes diff --git a/lib/Gitlab/Api/Repositories.php b/lib/Gitlab/Api/Repositories.php index c633f3a07..752e909a0 100644 --- a/lib/Gitlab/Api/Repositories.php +++ b/lib/Gitlab/Api/Repositories.php @@ -169,18 +169,20 @@ public function commit($project_id, $sha) } /** - * @param int $project_id + * @param int $project_id * @param string $sha - * @param int $page - * @param int $per_page + * @param array $parameters + * * @return mixed */ - public function commitComments($project_id, $sha, $page = 0, $per_page = self::PER_PAGE) + public function commitComments($project_id, $sha, array $parameters = []) { - return $this->get($this->getProjectPath($project_id, 'repository/commits/'.$this->encodePath($sha).'/comments'), array( - 'page' => $page, - 'per_page' => $per_page - )); + $resolver = $this->createOptionsResolver(); + + return $this->get( + $this->getProjectPath($project_id, 'repository/commits/'.$this->encodePath($sha).'/comments'), + $resolver->resolve($parameters) + ); } /** From 9b22dd49ed5d1d472de41014a55b7d0bcd05ecb1 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 1 Aug 2017 17:34:31 +0200 Subject: [PATCH 57/83] Typo in UPGRADE.md --- UPGRADE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UPGRADE.md b/UPGRADE.md index d30733671..e2fb1b39e 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -78,4 +78,4 @@ Use the `deployKeys`, `deployKey`, `addDeployKey`, `deleteDeployKey`, `removeDep ## `Gitlab\Model\Snippet` changes -The `expires_at` property have been removed.` +* The `expires_at` property have been removed.` From 016c93c70dd843dc5b4cfc0524ab1c889bf9dfef Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 1 Aug 2017 17:49:52 +0200 Subject: [PATCH 58/83] use OptionsResolver in Users api --- UPGRADE.md | 5 ++ lib/Gitlab/Api/Users.php | 88 ++++++++++++++++------------- test/Gitlab/Tests/Api/UsersTest.php | 85 ++-------------------------- 3 files changed, 57 insertions(+), 121 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index e2fb1b39e..5d0d87f4a 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -79,3 +79,8 @@ Use the `deployKeys`, `deployKey`, `addDeployKey`, `deleteDeployKey`, `removeDep ## `Gitlab\Model\Snippet` changes * The `expires_at` property have been removed.` + +## `Gitlab\Model\Users` changes + +* The `all` method now take a single argument which is an associative array of query string parameters. +* The `lookup` and `search` methods have been removed. Use `all` method instead. diff --git a/lib/Gitlab/Api/Users.php b/lib/Gitlab/Api/Users.php index 87f0bec5c..b23430078 100644 --- a/lib/Gitlab/Api/Users.php +++ b/lib/Gitlab/Api/Users.php @@ -3,46 +3,54 @@ class Users extends AbstractApi { /** - * @param null|true $active - * @param int $page - * @param int $per_page - * @return mixed - */ - public function all($active = null, $page = 1, $per_page = self::PER_PAGE) - { - return $this->get('users', array( - 'active' => $active, - 'page' => $page, - 'per_page' => $per_page - )); - } - - /** - * @param string $username - * @return mixed - */ - public function lookup($username) - { - return $this->get('users', array( - 'username' => $username - )); - } - - /** - * @param string $query - * @param null|true $active - * @param int $page - * @param int $per_page - * @return mixed - */ - public function search($query, $active = null, $page = 1, $per_page = self::PER_PAGE) - { - return $this->get('users', array( - 'search' => $query, - 'active' => $active, - 'page' => $page, - 'per_page' => $per_page - )); + * @param array $parameters ( + * + * @var string $search Search for user by email or username. + * @var string $username Lookup for user by username. + * @var bool $external Search for external users only. + * @var string $extern_uid Lookup for users by external uid. + * @var string $provider Lookup for users by provider. + * @var \DateTimeInterface $created_before Return users created before the given time (inclusive). + * @var \DateTimeInterface $created_after Return users created after the given time (inclusive). + * @var bool $active Return only active users. It does not support filtering inactive users. + * @var bool $blocked Return only blocked users. It does not support filtering non-blocked users. + * ) + * + * @return mixed + */ + public function all(array $parameters = []) + { + $resolver = $this->createOptionsResolver(); + $datetimeNormalizer = function (\DateTimeInterface $value) { + return $value->format('c'); + }; + + $resolver->setDefined('search'); + $resolver->setDefined('username'); + $resolver->setDefined('external') + ->setAllowedTypes('external', 'bool') + ; + $resolver->setDefined('extern_uid'); + $resolver->setDefined('provider'); + $resolver->setDefined('created_before') + ->setAllowedTypes('created_before', \DateTimeInterface::class) + ->setNormalizer('created_before', $datetimeNormalizer) + ; + $resolver->setDefined('created_after') + ->setAllowedTypes('created_after', \DateTimeInterface::class) + ->setNormalizer('created_after', $datetimeNormalizer) + ; + $resolver->setDefined('active') + ->setAllowedTypes('active', 'bool') + ->setAllowedValues('active', true) + ; + $resolver->setDefined('blocked') + ->setAllowedTypes('blocked', 'bool') + ->setAllowedValues('blocked', true) + ; + + + return $this->get('users', $resolver->resolve($parameters)); } /** diff --git a/test/Gitlab/Tests/Api/UsersTest.php b/test/Gitlab/Tests/Api/UsersTest.php index ff76c5590..6eedc93ac 100644 --- a/test/Gitlab/Tests/Api/UsersTest.php +++ b/test/Gitlab/Tests/Api/UsersTest.php @@ -17,11 +17,11 @@ public function shouldGetAllUsers() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('users', array('active' => null, 'page' => 1, 'per_page' => 10)) + ->with('users', array()) ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->all(null, 1, 10)); + $this->assertEquals($expectedArray, $api->all()); } /** @@ -37,88 +37,11 @@ public function shouldGetActiveUsers() $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('users', array('active' => true, 'page' => 1, 'per_page' => AbstractApi::PER_PAGE)) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->all(true)); - } - - /** - * @test - */ - public function shouldNotNeedPaginationWhenGettingUsers() - { - $expectedArray = array( - array('id' => 1, 'name' => 'Matt'), - array('id' => 2, 'name' => 'John'), - ); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('users', array('active' => null, 'page' => 1, 'per_page' => AbstractApi::PER_PAGE)) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->all()); - } - - /** - * @test - */ - public function shouldSearchUsers() - { - $expectedArray = array( - array('id' => 1, 'name' => 'Matt') - ); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('users', array('search' => 'ma', 'active' => null, 'page' => 1, 'per_page' => AbstractApi::PER_PAGE)) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->search('ma')); - } - - /** - * @test - */ - public function shouldSearchActiveUsers() - { - $expectedArray = array( - array('id' => 1, 'name' => 'Matt') - ); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('users', array('search' => 'ma', 'active' => true, 'page' => 1, 'per_page' => AbstractApi::PER_PAGE)) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->search('ma', true)); - } - - /** - * @test - */ - public function shouldSearchActiveUsersWithPagination() - { - $expectedArray = array( - array('id' => 1, 'name' => 'Matt') - ); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('users', array('search' => 'ma', 'active' => true, 'page' => 2, 'per_page' => 5)) + ->with('users', array('active' => true)) ->will($this->returnValue($expectedArray)) ; - $this->assertEquals($expectedArray, $api->search('ma', true, 2, 5)); + $this->assertEquals($expectedArray, $api->all(['active' => true])); } /** From 6b037a19939df59b7717f569036d4bccf2eeab7a Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Thu, 3 Aug 2017 10:03:29 +0200 Subject: [PATCH 59/83] Use OptionsResolver in Branch & Project models --- lib/Gitlab/Model/Branch.php | 12 +++--- lib/Gitlab/Model/Project.php | 76 +++++++++++++++++++++--------------- 2 files changed, 51 insertions(+), 37 deletions(-) diff --git a/lib/Gitlab/Model/Branch.php b/lib/Gitlab/Model/Branch.php index 30dfc17a5..8c7ef36b4 100644 --- a/lib/Gitlab/Model/Branch.php +++ b/lib/Gitlab/Model/Branch.php @@ -1,7 +1,7 @@ project->commits($page, $per_page, $this->name); + return $this->project->commits($parameters); } /** diff --git a/lib/Gitlab/Model/Project.php b/lib/Gitlab/Model/Project.php index 0b37fc610..a468b565d 100644 --- a/lib/Gitlab/Model/Project.php +++ b/lib/Gitlab/Model/Project.php @@ -1,8 +1,8 @@ client->projects()->hooks($this->id, $page, $per_page); + $data = $this->client->projects()->hooks($this->id, $parameters); $hooks = array(); foreach ($data as $hook) { @@ -449,14 +451,15 @@ public function tags() } /** - * @param int $page - * @param int $per_page - * @param string $ref_name + * @param array $parameters + * + * @see Repositories::commits() for available parameters. + * * @return Commit[] */ - public function commits($page = 0, $per_page = Api::PER_PAGE, $ref_name = null) + public function commits(array $parameters = []) { - $data = $this->client->repositories()->commits($this->id, $page, $per_page, $ref_name); + $data = $this->client->repositories()->commits($this->id, $parameters); $commits = array(); foreach ($data as $commit) { @@ -479,13 +482,15 @@ public function commit($sha) /** * @param string $ref - * @param int $page - * @param int $per_page + * @param array $parameters + * + * @see Repositories::commitComments() for available parameters. + * * @return Commit[] */ - public function commitComments($ref, $page = 0, $per_page = Api::PER_PAGE) + public function commitComments($ref, array $parameters = []) { - $data = $this->client->repositories()->commitComments($this->id, $ref, $page, $per_page); + $data = $this->client->repositories()->commitComments($this->id, $ref, $parameters); $comments = array(); foreach ($data as $comment) { @@ -614,13 +619,15 @@ public function deleteFile($file_path, $branch_name, $commit_message, $author_em } /** - * @param int $page - * @param int $per_page + * @param array $parameters + * + * @see Projects::events() for available parameters. + * * @return Event[] */ - public function events($page = 1, $per_page = Api::PER_PAGE) + public function events(array $parameters = []) { - $data = $this->client->projects()->events($this->id, $page, $per_page); + $data = $this->client->projects()->events($this->id, $parameters); $events = array(); foreach ($data as $event) { @@ -631,14 +638,15 @@ public function events($page = 1, $per_page = Api::PER_PAGE) } /** - * @param int $page - * @param int $per_page - * @param string $state + * @param array $parameters + * + * @see MergeRequests::all() for available parameters. + * * @return MergeRequest[] */ - public function mergeRequests($page = 1, $per_page = Api::PER_PAGE, $state = MergeRequests::STATE_ALL) + public function mergeRequests(array $parameters = []) { - $data = $this->client->mergeRequests()->$state($this->id, $page, $per_page); + $data = $this->client->mergeRequests()->all($this->id, $parameters); $mrs = array(); foreach ($data as $mr) { @@ -720,13 +728,15 @@ public function mergeMergeRequest($id) } /** - * @param int $page - * @param int $per_page + * @param array $parameters + * + * @see Issues::all() for available parameters. + * * @return Issue[] */ - public function issues($page = 1, $per_page = Api::PER_PAGE) + public function issues(array $parameters = []) { - $data = $this->client->issues()->all($this->id, $page, $per_page); + $data = $this->client->issues()->all($this->id, $parameters); $issues = array(); foreach ($data as $issue) { @@ -796,13 +806,15 @@ public function openIssue($id) } /** - * @param int $page - * @param int $per_page + * @param array $parameters + * + * @see Milestones::all() for available parameters. + * * @return Milestone[] */ - public function milestones($page = 1, $per_page = Api::PER_PAGE) + public function milestones(array $parameters = []) { - $data = $this->client->milestones()->all($this->id, $page, $per_page); + $data = $this->client->milestones()->all($this->id, $parameters); $milestones = array(); foreach ($data as $milestone) { From 4e6800bfba369ad1d536bf7ab7d85c1151ee4ffe Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Thu, 3 Aug 2017 10:08:43 +0200 Subject: [PATCH 60/83] remove AbstractApi::PER_PAGE constant --- UPGRADE.md | 4 ++++ lib/Gitlab/Api/AbstractApi.php | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 5d0d87f4a..9062b5c69 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -13,6 +13,10 @@ See [documentation](doc/customize.md) to know how to customize the client timeou * The `setHttpClient` method have been removed. Use a `Gitlab\HttpClient\Builder` instead. * The `getHttpClient` method return type is changed to `Http\Client\Common\HttpMethodsClient`. +## `Gitlab\Api\AbstractApi` changes + +* The `PER_PAGE` class constant have been removed. + ## `Gitlab\Api\DeployKeys` changes * The `all` method now take a single argument which is an associative array of query string parameters. diff --git a/lib/Gitlab/Api/AbstractApi.php b/lib/Gitlab/Api/AbstractApi.php index 9bad793b6..985dad96a 100644 --- a/lib/Gitlab/Api/AbstractApi.php +++ b/lib/Gitlab/Api/AbstractApi.php @@ -19,11 +19,6 @@ */ abstract class AbstractApi implements ApiInterface { - /** - * Default entries per page - */ - const PER_PAGE = 20; - /** * The client * From ac66897ff929c5ac31d602eb279fc957643b6111 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Thu, 3 Aug 2017 10:52:45 +0200 Subject: [PATCH 61/83] add version compatibility table --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a209994c5..fc5b871c4 100644 --- a/README.md +++ b/README.md @@ -21,12 +21,13 @@ You can visit [HTTPlug for library users](http://docs.php-http.org/en/latest/htt Versioning ---------- -From the 6.0 stable release of Gitlab, I shall now be matching the client version with the Gitlab version. For example -when Gitlab 6.1 is released I will release version 6.1.0 of the API client. If I need to make future updates to the client -before the next API version is released, I'll simply use a 3rd build version - `6.1.1`, `6.1.2` etc for example. +Depending on your Gitlab server version, you must choose the right version of this library. +Please refer to the following table to pick the right one. -It is recommended that you keep your composer file in sync with whatever version of Gitlab you are currently running: -if you are using 6.0, you should require `6.0.*`; 6.1 should be `6.1.*`... +|Version|Gitlab API Version|Gitlab Version| +|-------|------------------|--------------| +|9.x | V4 | >= 9.0 | +|8.x | V3 | < 9.5 | General API Usage ----------------- From 24baaf0cf79d7d54897c23d7d1f0641566f9c159 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Thu, 3 Aug 2017 10:59:53 +0200 Subject: [PATCH 62/83] update badges --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index fc5b871c4..33c3f6cfb 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ A PHP wrapper to be used with [Gitlab's API](https://github.com/gitlabhq/gitlabh ============== [![Build Status](https://travis-ci.org/m4tthumphrey/php-gitlab-api.svg?branch=master)](https://travis-ci.org/m4tthumphrey/php-gitlab-api) +[![StyleCI](https://styleci.io/repos/6816335/shield?branch=master)](https://styleci.io/repos/6816335) +[![Total Downloads](https://poser.pugx.org/m4tthumphrey/php-gitlab-api/downloads?format=flat-square)](https://packagist.org/packages/m4tthumphrey/php-gitlab-api) +[![Latest Stable Version](https://poser.pugx.org/m4tthumphrey/php-gitlab-api/version?format=flat-square)](https://packagist.org/packages/m4tthumphrey/php-gitlab-api) +[![Latest Unstable Version](https://poser.pugx.org/m4tthumphrey/php-gitlab-api/v/unstable?format=flat-square)](//packagist.org/packages/m4tthumphrey/php-gitlab-api) Based on [php-github-api](https://github.com/m4tthumphrey/php-github-api) and code from [KnpLabs](https://github.com/KnpLabs/php-github-api). From 16d6b9db1b41a23b1a8e00d20fe27f09648ab2b4 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 25 Jul 2017 23:04:19 +0200 Subject: [PATCH 63/83] fix put calls + remove unused patch --- lib/Gitlab/Api/AbstractApi.php | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/lib/Gitlab/Api/AbstractApi.php b/lib/Gitlab/Api/AbstractApi.php index e03123fe9..808bab5a6 100644 --- a/lib/Gitlab/Api/AbstractApi.php +++ b/lib/Gitlab/Api/AbstractApi.php @@ -121,23 +121,6 @@ protected function post($path, array $parameters = array(), $requestHeaders = ar return ResponseMediator::getContent($response); } - /** - * @param string $path - * @param array $parameters - * @param array $requestHeaders - * @return mixed - */ - protected function patch($path, array $parameters = array(), $requestHeaders = array()) - { - $path = $this->preparePath($path); - - $body = empty($parameters) ? null : $this->streamFactory->createStream(http_build_query($parameters)); - - $response = $this->client->getHttpClient()->patch($path, $requestHeaders, $body); - - return ResponseMediator::getContent($response); - } - /** * @param string $path * @param array $parameters @@ -148,7 +131,11 @@ protected function put($path, array $parameters = array(), $requestHeaders = arr { $path = $this->preparePath($path); - $body = empty($parameters) ? null : $this->streamFactory->createStream(http_build_query($parameters)); + $body = null; + if (!empty($parameters)) { + $body = $this->streamFactory->createStream(http_build_query($parameters)); + $requestHeaders['Content-Type'] = 'application/x-www-form-urlencoded'; + } $response = $this->client->getHttpClient()->put($path, $requestHeaders, $body); From 4322ad4adbec3b153ce0768ac892d67168d3b474 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Tue, 25 Jul 2017 23:34:55 +0200 Subject: [PATCH 64/83] fix delete calls with parameters --- lib/Gitlab/Api/AbstractApi.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/Gitlab/Api/AbstractApi.php b/lib/Gitlab/Api/AbstractApi.php index 808bab5a6..fba3ac981 100644 --- a/lib/Gitlab/Api/AbstractApi.php +++ b/lib/Gitlab/Api/AbstractApi.php @@ -150,11 +150,9 @@ protected function put($path, array $parameters = array(), $requestHeaders = arr */ protected function delete($path, array $parameters = array(), $requestHeaders = array()) { - $path = $this->preparePath($path); - - $body = empty($parameters) ? null : $this->streamFactory->createStream(http_build_query($parameters)); + $path = $this->preparePath($path, $parameters); - $response = $this->client->getHttpClient()->delete($path, $requestHeaders, $body); + $response = $this->client->getHttpClient()->delete($path, $requestHeaders); return ResponseMediator::getContent($response); } From 575933506afc6eddefd9b9e285e7918c92f3bce8 Mon Sep 17 00:00:00 2001 From: Jaime Date: Tue, 8 Aug 2017 17:45:14 +0200 Subject: [PATCH 65/83] use iid instead id on Issue model. --- lib/Gitlab/Model/Issue.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Gitlab/Model/Issue.php b/lib/Gitlab/Model/Issue.php index 0b5f1d77d..d20f48260 100644 --- a/lib/Gitlab/Model/Issue.php +++ b/lib/Gitlab/Model/Issue.php @@ -135,7 +135,7 @@ public function reopen() */ public function addComment($comment) { - $data = $this->client->issues()->addComment($this->project->id, $this->id, array( + $data = $this->client->issues()->addComment($this->project->id, $this->iid, array( 'body' => $comment )); @@ -148,7 +148,7 @@ public function addComment($comment) public function showComments() { $notes = array(); - $data = $this->client->issues()->showComments($this->project->id, $this->id); + $data = $this->client->issues()->showComments($this->project->id, $this->iid); foreach ($data as $note) { $notes[] = Note::fromArray($this->getClient(), $this, $note); From 96554de40bda7d50c0d5b155d2371fd0eb09ba69 Mon Sep 17 00:00:00 2001 From: Vincent Klaiber Date: Thu, 10 Aug 2017 13:34:20 +0200 Subject: [PATCH 66/83] Add .gitattributes Exclude non-essential files in .gitattributes. --- .gitattributes | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..d6221e58e --- /dev/null +++ b/.gitattributes @@ -0,0 +1,12 @@ + +* text=auto + +/doc export-ignore +/tests export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.styleci.yml export-ignore +/.travis.yml export-ignore +/phpunit.xml.dist export-ignore +/README.md export-ignore +/UPGRADE.md export-ignore From e03905ff10d6089d729553baa5989fcc6c3ad0d1 Mon Sep 17 00:00:00 2001 From: Vincent Klaiber Date: Thu, 10 Aug 2017 13:34:41 +0200 Subject: [PATCH 67/83] Update .gitattributes --- .gitattributes | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index d6221e58e..4d906e085 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,3 @@ - * text=auto /doc export-ignore From 3335957125bc3d13dc6931213168927783c9306d Mon Sep 17 00:00:00 2001 From: Vincent Klaiber Date: Thu, 10 Aug 2017 13:35:31 +0200 Subject: [PATCH 68/83] Update Laravel link Updated the Laravel integration link. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 33c3f6cfb..5794e7d99 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ You get the idea! Take a look around ([API methods](https://github.com/m4tthumph Framework Integrations ---------------------- - **Symfony** - https://github.com/Zeichen32/GitLabApiBundle -- **Laravel** - https://github.com/vinkla/gitlab +- **Laravel** - https://github.com/vinkla/laravel-gitlab If you have integrated GitLab into a popular PHP framework, let us know! From fac3eac82c5427f7d12b42d392bae8db4c16e7f1 Mon Sep 17 00:00:00 2001 From: Vincent Klaiber Date: Thu, 10 Aug 2017 18:59:44 +0200 Subject: [PATCH 69/83] Fix typo Should be `test` and not `tests`. Sorry about that. --- .gitattributes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 4d906e085..5a646aae4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,7 +1,7 @@ * text=auto /doc export-ignore -/tests export-ignore +/test export-ignore /.gitattributes export-ignore /.gitignore export-ignore /.styleci.yml export-ignore From d4459e3a0948001db57ecd3c678c21f7a8fdd213 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Wed, 16 Aug 2017 16:32:56 +0200 Subject: [PATCH 70/83] use QueryStringBuilder for POST requests --- lib/Gitlab/Api/AbstractApi.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Gitlab/Api/AbstractApi.php b/lib/Gitlab/Api/AbstractApi.php index 7c5cfe65d..ef9120a20 100644 --- a/lib/Gitlab/Api/AbstractApi.php +++ b/lib/Gitlab/Api/AbstractApi.php @@ -89,7 +89,7 @@ protected function post($path, array $parameters = array(), $requestHeaders = ar $body = null; if (empty($files) && !empty($parameters)) { - $body = $this->streamFactory->createStream(http_build_query($parameters)); + $body = $this->streamFactory->createStream(QueryStringBuilder::build($parameters)); $requestHeaders['Content-Type'] = 'application/x-www-form-urlencoded'; } elseif (!empty($files)) { $builder = new MultipartStreamBuilder($this->streamFactory); From 09fe8a644adff2c6794d2e4080fb406d2c99922b Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Wed, 16 Aug 2017 16:44:30 +0200 Subject: [PATCH 71/83] add createCommit --- lib/Gitlab/Api/Repositories.php | 65 ++++++++++++++++++++++ test/Gitlab/Tests/Api/RepositoriesTest.php | 34 +++++++++++ 2 files changed, 99 insertions(+) diff --git a/lib/Gitlab/Api/Repositories.php b/lib/Gitlab/Api/Repositories.php index 752e909a0..e67d79f4a 100644 --- a/lib/Gitlab/Api/Repositories.php +++ b/lib/Gitlab/Api/Repositories.php @@ -1,5 +1,7 @@ get($this->getProjectPath($project_id, 'repository/commits/'.$this->encodePath($sha))); } + /** + * @param int $project_id + * @param array $parameters ( + * + * @var string $branch Name of the branch to commit into. To create a new branch, also provide start_branch. + * @var string $commit_message Commit message. + * @var string $start_branch Name of the branch to start the new commit from. + * @var array $actions ( + * + * @var string $action he action to perform, create, delete, move, update. + * @var string $file_path Full path to the file. + * @var string $previous_path Original full path to the file being moved. + * @var string $content File content, required for all except delete. Optional for move. + * @var string $encoding text or base64. text is default. + * ) + * @var string $author_email Specify the commit author's email address. + * @var string $author_name Specify the commit author's name. + * ) + * + * @return mixed + */ + public function createCommit($project_id, array $parameters = []) + { + $resolver = new OptionsResolver(); + $resolver->setDefined('branch') + ->setRequired('branch') + ; + $resolver->setDefined('commit_message') + ->setRequired('commit_message') + ; + $resolver->setDefined('start_branch'); + $resolver->setDefined('actions') + ->setRequired('actions') + ->setAllowedTypes('actions', 'array') + ->setAllowedValues('actions', function (array $actions) { + return !empty($actions); + }) + ->setNormalizer('actions', function (OptionsResolver $resolver, array $actions) { + $actionsOptionsResolver = new OptionsResolver(); + $actionsOptionsResolver->setDefined('action') + ->setRequired('action') + ->setAllowedValues('action', ['create', 'delete', 'move', 'update']) + ; + $actionsOptionsResolver->setDefined('file_path') + ->setRequired('file_path') + ; + $actionsOptionsResolver->setDefined('previous_path'); + $actionsOptionsResolver->setDefined('content'); + $actionsOptionsResolver->setDefined('encoding') + ->setAllowedValues('encoding', ['test', 'base64']) + ; + + return array_map(function ($action) use ($actionsOptionsResolver) { + return $actionsOptionsResolver->resolve($action); + }, $actions); + }) + ; + $resolver->setDefined('author_email'); + $resolver->setDefined('author_name'); + + return $this->post($this->getProjectPath($project_id, 'repository/commits'), $resolver->resolve($parameters)); + } + /** * @param int $project_id * @param string $sha diff --git a/test/Gitlab/Tests/Api/RepositoriesTest.php b/test/Gitlab/Tests/Api/RepositoriesTest.php index fcad85309..64cc8bc16 100644 --- a/test/Gitlab/Tests/Api/RepositoriesTest.php +++ b/test/Gitlab/Tests/Api/RepositoriesTest.php @@ -274,6 +274,40 @@ public function shouldGetCommit() $this->assertEquals($expectedArray, $api->commit(1, 'abcd1234')); } + /** + * @test + */ + public function shouldCreateCommit() + { + $expectedArray = array('title' => 'Initial commit.', 'author_name' => 'John Doe', 'author_email' => 'john@example.com'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/repository/commits') + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->createCommit(1, [ + 'branch' => 'master', + 'commit_message' => 'Initial commit.', + 'actions' => [ + [ + 'action' => 'create', + 'file_path' => 'README.md', + 'content' => '# My new project', + ], + [ + 'action' => 'create', + 'file_path' => 'LICENSE', + 'content' => 'MIT License...', + ], + ], + 'author_name' => 'John Doe', + 'author_email' => 'john@example.com', + ])); + } + /** * @test */ From 6edbeb21a5bb24a021501e88d0c23cc60a08a288 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Fri, 18 Aug 2017 15:48:33 +0200 Subject: [PATCH 72/83] add php 7.2 to travis matrix --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 55eda476e..1029226b6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,10 +5,11 @@ sudo: false php: - 5.6 - 7.0 + - 7.1 matrix: include: - - php: 7.1 + - php: 7.2 env: STATIC_ANALYSIS=yes before_script: From ff18431b70efdf1fa049007307b07364e1a87ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20Klabbers?= Date: Tue, 22 Aug 2017 16:27:12 +0200 Subject: [PATCH 73/83] Update ProjectHook.php adds pipeline events, see https://docs.gitlab.com/ce/api/projects.html#edit-project-hook --- lib/Gitlab/Model/ProjectHook.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/Gitlab/Model/ProjectHook.php b/lib/Gitlab/Model/ProjectHook.php index 7090e79eb..1789ca68b 100644 --- a/lib/Gitlab/Model/ProjectHook.php +++ b/lib/Gitlab/Model/ProjectHook.php @@ -13,6 +13,7 @@ * @property-read bool $merge_requests_events * @property-read bool $job_events * @property-read bool $tag_push_events + * @property-read bool $pipeline_events * @property-read string $created_at * @property-read Project $project */ @@ -31,6 +32,7 @@ class ProjectHook extends AbstractModel 'merge_requests_events', 'job_events', 'tag_push_events', + 'pipeline_events', 'created_at' ); From 64638fbdfaa6f3db34fe35204d64fa94de6f96aa Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Fri, 25 Aug 2017 11:43:05 +0200 Subject: [PATCH 74/83] fix false boolean query string encoding --- .../HttpClient/Message/QueryStringBuilder.php | 20 +++++++++++++++++-- .../Message/QueryStringBuilderTest.php | 6 ++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/Gitlab/HttpClient/Message/QueryStringBuilder.php b/lib/Gitlab/HttpClient/Message/QueryStringBuilder.php index b916d29d5..03e16a326 100644 --- a/lib/Gitlab/HttpClient/Message/QueryStringBuilder.php +++ b/lib/Gitlab/HttpClient/Message/QueryStringBuilder.php @@ -15,7 +15,7 @@ final class QueryStringBuilder public static function build($query) { if (!is_array($query)) { - return rawurlencode($query); + return static::rawurlencode($query); } return implode('&', array_map(function ($value, $key) { return static::encode($value, $key); @@ -32,7 +32,7 @@ public static function build($query) private static function encode($query, $prefix) { if (!is_array($query)) { - return rawurlencode($prefix).'='.rawurlencode($query); + return static::rawurlencode($prefix).'='.static::rawurlencode($query); } $isIndexedArray = static::isIndexedArray($query); @@ -57,4 +57,20 @@ public static function isIndexedArray(array $query) return array_keys($query) === range(0, count($query) - 1); } + + /** + * Encode a value like rawurlencode, but return "0" when false is given. + * + * @param mixed $value + * + * @return string + */ + private static function rawurlencode($value) + { + if ($value === false) { + return '0'; + } + + return rawurlencode($value); + } } diff --git a/test/Gitlab/Tests/HttpClient/Message/QueryStringBuilderTest.php b/test/Gitlab/Tests/HttpClient/Message/QueryStringBuilderTest.php index db563cdce..4dc2e9c3e 100644 --- a/test/Gitlab/Tests/HttpClient/Message/QueryStringBuilderTest.php +++ b/test/Gitlab/Tests/HttpClient/Message/QueryStringBuilderTest.php @@ -40,6 +40,12 @@ public function queryStringProvider() 'iids%5B0%5D=88&iids%5B2%5D=86' ]; + //Boolean encoding + yield [ + ['push_events' => false, 'merge_requests_events' => 1], + 'push_events=0&merge_requests_events=1' + ]; + //A deeply nested array. yield [ [ From 7bb056d9481dc757ac0b8351d321f84a0fe02592 Mon Sep 17 00:00:00 2001 From: Sebastian Blank Date: Fri, 25 Aug 2017 14:13:15 +0200 Subject: [PATCH 75/83] Add pagination to load tags --- lib/Gitlab/Api/Repositories.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/Gitlab/Api/Repositories.php b/lib/Gitlab/Api/Repositories.php index e67d79f4a..f9f5ab754 100644 --- a/lib/Gitlab/Api/Repositories.php +++ b/lib/Gitlab/Api/Repositories.php @@ -74,11 +74,14 @@ public function unprotectBranch($project_id, $branch_name) /** * @param int $project_id + * @param array $parameters * @return mixed */ - public function tags($project_id) + public function tags($project_id, array $parameters = []) { - return $this->get($this->getProjectPath($project_id, 'repository/tags')); + $resolver = $this->createOptionsResolver(); + + return $this->get($this->getProjectPath($project_id, 'repository/tags'), $resolver->resolve($parameters)); } /** From 6ae9c057bce811c5e023c02f76d28fae73419f00 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Mon, 28 Aug 2017 13:35:00 +0200 Subject: [PATCH 76/83] deprecate merge request comment related methods --- lib/Gitlab/Api/MergeRequests.php | 10 +++--- test/Gitlab/Tests/Api/MergeRequestsTest.php | 37 --------------------- 2 files changed, 6 insertions(+), 41 deletions(-) diff --git a/lib/Gitlab/Api/MergeRequests.php b/lib/Gitlab/Api/MergeRequests.php index fa841a36b..691ca393e 100644 --- a/lib/Gitlab/Api/MergeRequests.php +++ b/lib/Gitlab/Api/MergeRequests.php @@ -162,7 +162,9 @@ public function addNote($project_id, $mr_id, $note) */ public function showComments($project_id, $mr_id) { - return $this->get($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/comments')); + @trigger_error(sprintf('The %s() method is deprecated since version 9.1 and will be removed in 10.0. Use the showNotes() method instead.', __METHOD__), E_USER_DEPRECATED); + + return $this->showNotes($project_id, $mr_id); } /** @@ -173,9 +175,9 @@ public function showComments($project_id, $mr_id) */ public function addComment($project_id, $mr_id, $note) { - return $this->post($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($mr_id).'/comments'), array( - 'note' => $note - )); + @trigger_error(sprintf('The %s() method is deprecated since version 9.1 and will be removed in 10.0. Use the addNote() method instead.', __METHOD__), E_USER_DEPRECATED); + + return $this->addNote($project_id, $mr_id, $note); } /** diff --git a/test/Gitlab/Tests/Api/MergeRequestsTest.php b/test/Gitlab/Tests/Api/MergeRequestsTest.php index 8f9c51942..6605c7ea4 100644 --- a/test/Gitlab/Tests/Api/MergeRequestsTest.php +++ b/test/Gitlab/Tests/Api/MergeRequestsTest.php @@ -163,43 +163,6 @@ public function shouldGetMergeRequestNotes() $this->assertEquals($expectedArray, $api->showNotes(1, 2)); } - /** - * @test - */ - public function shouldGetMergeRequestComments() - { - $expectedArray = array( - array('id' => 1, 'note' => 'A comment'), - array('id' => 2, 'note' => 'Another comment') - ); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('projects/1/merge_requests/2/comments') - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->showComments(1, 2)); - } - - /** - * @test - */ - public function shouldAddMergeRequestComment() - { - $expectedArray = array('id' => 2, 'title' => 'A comment'); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('post') - ->with('projects/1/merge_requests/2/comments', array('note' => 'A comment')) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->addComment(1, 2, 'A comment')); - } - /** * @test */ From 032b7cca7b376686522d00bcb404bc9167a6e0c4 Mon Sep 17 00:00:00 2001 From: Fabien Bourigault Date: Wed, 6 Sep 2017 12:15:50 +0200 Subject: [PATCH 77/83] add RepositoryFiles api endpoint --- lib/Gitlab/Api/Repositories.php | 30 +- lib/Gitlab/Api/RepositoryFiles.php | 135 +++++++++ lib/Gitlab/Client.php | 8 + lib/Gitlab/Model/Project.php | 50 +++- test/Gitlab/Tests/Api/RepositoriesTest.php | 230 --------------- test/Gitlab/Tests/Api/RepositoryFilesTest.php | 279 ++++++++++++++++++ 6 files changed, 487 insertions(+), 245 deletions(-) create mode 100644 lib/Gitlab/Api/RepositoryFiles.php create mode 100644 test/Gitlab/Tests/Api/RepositoryFilesTest.php diff --git a/lib/Gitlab/Api/Repositories.php b/lib/Gitlab/Api/Repositories.php index f9f5ab754..9fcca55a6 100644 --- a/lib/Gitlab/Api/Repositories.php +++ b/lib/Gitlab/Api/Repositories.php @@ -309,9 +309,9 @@ public function tree($project_id, array $params = array()) */ public function blob($project_id, $sha, $filepath) { - return $this->get($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($filepath).'/raw'), array( - 'ref' => $sha, - )); + @trigger_error(sprintf('The %s() method is deprecated since version 9.2 and will be removed in 10.0. Use the %s::getRawFile() method instead.', __METHOD__, RepositoryFiles::class), E_USER_DEPRECATED); + + return $this->client->repositoryFiles()->getRawFile($project_id, $filepath, $sha); } /** @@ -322,9 +322,9 @@ public function blob($project_id, $sha, $filepath) */ public function getFile($project_id, $file_path, $ref) { - return $this->get($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($file_path)), array( - 'ref' => $ref - )); + @trigger_error(sprintf('The %s() method is deprecated since version 9.2 and will be removed in 10.0. Use the %s::getFile() method instead.', __METHOD__, RepositoryFiles::class), E_USER_DEPRECATED); + + return $this->client->repositoryFiles()->getFile($project_id, $file_path, $ref); } /** @@ -340,7 +340,9 @@ public function getFile($project_id, $file_path, $ref) */ public function createFile($project_id, $file_path, $content, $branch, $commit_message, $encoding = null, $author_email = null, $author_name = null) { - return $this->post($this->getProjectPath($project_id, 'repository/files'), array( + @trigger_error(sprintf('The %s() method is deprecated since version 9.2 and will be removed in 10.0. Use the %s::createFile() method instead.', __METHOD__, RepositoryFiles::class), E_USER_DEPRECATED); + + return $this->client->repositoryFiles()->createFile($project_id, [ 'file_path' => $file_path, 'branch' => $branch, 'content' => $content, @@ -348,7 +350,7 @@ public function createFile($project_id, $file_path, $content, $branch, $commit_m 'encoding' => $encoding, 'author_email' => $author_email, 'author_name' => $author_name, - )); + ]); } /** @@ -364,7 +366,9 @@ public function createFile($project_id, $file_path, $content, $branch, $commit_m */ public function updateFile($project_id, $file_path, $content, $branch, $commit_message, $encoding = null, $author_email = null, $author_name = null) { - return $this->put($this->getProjectPath($project_id, 'repository/files'), array( + @trigger_error(sprintf('The %s() method is deprecated since version 9.2 and will be removed in 10.0. Use the %s::updateFile() method instead.', __METHOD__, RepositoryFiles::class), E_USER_DEPRECATED); + + return $this->client->repositoryFiles()->updateFile($project_id, [ 'file_path' => $file_path, 'branch' => $branch, 'content' => $content, @@ -372,7 +376,7 @@ public function updateFile($project_id, $file_path, $content, $branch, $commit_m 'encoding' => $encoding, 'author_email' => $author_email, 'author_name' => $author_name, - )); + ]); } /** @@ -386,13 +390,15 @@ public function updateFile($project_id, $file_path, $content, $branch, $commit_m */ public function deleteFile($project_id, $file_path, $branch, $commit_message, $author_email = null, $author_name = null) { - return $this->delete($this->getProjectPath($project_id, 'repository/files'), array( + @trigger_error(sprintf('The %s() method is deprecated since version 9.2 and will be removed in 10.0. Use the %s::deleteFile() method instead.', __METHOD__, RepositoryFiles::class), E_USER_DEPRECATED); + + return $this->client->repositoryFiles()->deleteFile($project_id, [ 'file_path' => $file_path, 'branch' => $branch, 'commit_message' => $commit_message, 'author_email' => $author_email, 'author_name' => $author_name, - )); + ]); } /** diff --git a/lib/Gitlab/Api/RepositoryFiles.php b/lib/Gitlab/Api/RepositoryFiles.php new file mode 100644 index 000000000..bc20c00f0 --- /dev/null +++ b/lib/Gitlab/Api/RepositoryFiles.php @@ -0,0 +1,135 @@ +get($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($file_path)), array( + 'ref' => $ref + )); + } + + /** + * @param int $project_id + * @param string $file_path + * @param string $ref + * @return mixed + */ + public function getRawFile($project_id, $file_path, $ref) + { + return $this->get($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($file_path).'/raw'), array( + 'ref' => $ref, + )); + } + + /** + * @param int $project_id + * @param array $parameters ( + * + * @var string $file_path Url encoded full path to new file. Ex. lib%2Fclass%2Erb. + * @var string $branch Name of the branch. + * @var string $start_branch Name of the branch to start the new commit from. + * @var string $encoding Change encoding to 'base64'. Default is text. + * @var string $author_email Specify the commit author's email address. + * @var string $author_name Specify the commit author's name. + * @var string $content File content. + * @var string $commit_message Commit message. + * ) + * + * @return mixed + */ + public function createFile($project_id, array $parameters = []) + { + $resolver = new OptionsResolver(); + $resolver->setRequired('file_path'); + $resolver->setRequired('branch'); + $resolver->setDefined('start_branch'); + $resolver->setDefined('encoding') + ->setAllowedValues('encoding', ['text', 'base64']) + ; + $resolver->setDefined('author_email'); + $resolver->setDefined('author_name'); + $resolver->setRequired('content'); + $resolver->setRequired('commit_message'); + + $resolved = $resolver->resolve($parameters); + + return $this->post($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($resolved['file_path'])), $resolved); + } + + /** + * @param int $project_id + * @param array $parameters ( + * + * @var string $file_path Url encoded full path to new file. Ex. lib%2Fclass%2Erb. + * @var string $branch Name of the branch. + * @var string $start_branch Name of the branch to start the new commit from. + * @var string $encoding Change encoding to 'base64'. Default is text. + * @var string $author_email Specify the commit author's email address. + * @var string $author_name Specify the commit author's name. + * @var string $content File content. + * @var string $commit_message Commit message. + * @var string $last_commit_id Last known file commit id. + * ) + * + * @return mixed + */ + public function updateFile($project_id, array $parameters = []) + { + $resolver = new OptionsResolver(); + $resolver->setRequired('file_path'); + $resolver->setRequired('branch'); + $resolver->setDefined('start_branch'); + $resolver->setDefined('encoding') + ->setAllowedValues('encoding', ['text', 'base64']) + ; + $resolver->setDefined('author_email'); + $resolver->setDefined('author_name'); + $resolver->setRequired('content'); + $resolver->setRequired('commit_message'); + $resolver->setDefined('last_commit_id'); + + $resolved = $resolver->resolve($parameters); + + return $this->put($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($resolved['file_path'])), $resolved); + } + + /** + * @param int $project_id + * @param array $parameters ( + * + * @var string $file_path Url encoded full path to new file. Ex. lib%2Fclass%2Erb. + * @var string $branch Name of the branch. + * @var string $start_branch Name of the branch to start the new commit from. + * @var string $author_email Specify the commit author's email address. + * @var string $author_name Specify the commit author's name. + * @var string $commit_message Commit message. + * ) + * + * @return mixed + */ + public function deleteFile($project_id, array $parameters = []) + { + $resolver = new OptionsResolver(); + $resolver->setRequired('file_path'); + $resolver->setRequired('branch'); + $resolver->setDefined('start_branch'); + $resolver->setDefined('author_email'); + $resolver->setDefined('author_name'); + $resolver->setRequired('commit_message'); + + $resolved = $resolver->resolve($parameters); + + return $this->delete($this->getProjectPath($project_id, 'repository/files/'.$this->encodePath($resolved['file_path'])), $resolved); + } +} diff --git a/lib/Gitlab/Client.php b/lib/Gitlab/Client.php index 9bcf5ec43..08679e011 100644 --- a/lib/Gitlab/Client.php +++ b/lib/Gitlab/Client.php @@ -197,6 +197,14 @@ public function repositories() return new Api\Repositories($this); } + /** + * @return Api\RepositoryFiles + */ + public function repositoryFiles() + { + return new Api\RepositoryFiles($this); + } + /** * @return Api\Snippets */ diff --git a/lib/Gitlab/Model/Project.php b/lib/Gitlab/Model/Project.php index a468b565d..ee24893d7 100644 --- a/lib/Gitlab/Model/Project.php +++ b/lib/Gitlab/Model/Project.php @@ -582,7 +582,22 @@ public function getFile($sha, $filepath) */ public function createFile($file_path, $content, $branch_name, $commit_message, $author_email = null, $author_name = null) { - $data = $this->client->repositories()->createFile($this->id, $file_path, $content, $branch_name, $commit_message, null, $author_email, $author_name); + $parameters = [ + 'file_path' => $file_path, + 'branch' => $branch_name, + 'content' => $content, + 'commit_message' => $commit_message, + ]; + + if ($author_email !== null) { + $parameters['author_email'] = $author_email; + } + + if ($author_name !== null) { + $parameters['author_name'] = $author_name; + } + + $data = $this->client->repositoryFiles()->createFile($this->id, $parameters); return File::fromArray($this->getClient(), $this, $data); } @@ -598,7 +613,22 @@ public function createFile($file_path, $content, $branch_name, $commit_message, */ public function updateFile($file_path, $content, $branch_name, $commit_message, $author_email = null, $author_name = null) { - $data = $this->client->repositories()->updateFile($this->id, $file_path, $content, $branch_name, $commit_message, null, $author_email, $author_name); + $parameters = [ + 'file_path' => $file_path, + 'branch' => $branch_name, + 'content' => $content, + 'commit_message' => $commit_message, + ]; + + if ($author_email !== null) { + $parameters['author_email'] = $author_email; + } + + if ($author_name !== null) { + $parameters['author_name'] = $author_name; + } + + $data = $this->client->repositoryFiles()->updateFile($this->id, $parameters); return File::fromArray($this->getClient(), $this, $data); } @@ -613,7 +643,21 @@ public function updateFile($file_path, $content, $branch_name, $commit_message, */ public function deleteFile($file_path, $branch_name, $commit_message, $author_email = null, $author_name = null) { - $this->client->repositories()->deleteFile($this->id, $file_path, $branch_name, $commit_message, $author_email, $author_name); + $parameters = [ + 'file_path' => $file_path, + 'branch' => $branch_name, + 'commit_message' => $commit_message, + ]; + + if ($author_email !== null) { + $parameters['author_email'] = $author_email; + } + + if ($author_name !== null) { + $parameters['author_name'] = $author_name; + } + + $this->client->repositoryFiles()->deleteFile($this->id, $parameters); return true; } diff --git a/test/Gitlab/Tests/Api/RepositoriesTest.php b/test/Gitlab/Tests/Api/RepositoriesTest.php index 64cc8bc16..a041cc59b 100644 --- a/test/Gitlab/Tests/Api/RepositoriesTest.php +++ b/test/Gitlab/Tests/Api/RepositoriesTest.php @@ -447,236 +447,6 @@ public function shouldGetTreeWithParams() $this->assertEquals($expectedArray, $api->tree(1, array('path' => 'dir/', 'ref_name' => 'master'))); } - /** - * @test - */ - public function shouldGetBlob() - { - $expectedString = 'something in a file'; - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('projects/1/repository/files/dir%2Ffile1%2Etxt/raw', array('ref' => 'abcd1234')) - ->will($this->returnValue($expectedString)) - ; - - $this->assertEquals($expectedString, $api->blob(1, 'abcd1234', 'dir/file1.txt')); - } - - /** - * @test - */ - public function shouldGetFile() - { - $expectedArray = array('file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt'); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('get') - ->with('projects/1/repository/files/dir%2Ffile1%2Etxt', array('ref' => 'abcd1234')) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->getFile(1, 'dir/file1.txt', 'abcd1234')); - } - - /** - * @test - */ - public function shouldCreateFile() - { - $expectedArray = array('file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt'); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('post') - ->with('projects/1/repository/files', array( - 'file_path' => 'dir/file1.txt', - 'branch' => 'master', - 'encoding' => null, - 'content' => 'some contents', - 'commit_message' => 'Added new file', - 'author_email' => null, - 'author_name' => null, - )) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->createFile(1, 'dir/file1.txt', 'some contents', 'master', 'Added new file')); - } - - /** - * @test - */ - public function shouldCreateFileWithEncoding() - { - $expectedArray = array('file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt'); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('post') - ->with('projects/1/repository/files', array( - 'file_path' => 'dir/file1.txt', - 'branch' => 'master', - 'encoding' => 'text', - 'content' => 'some contents', - 'commit_message' => 'Added new file', - 'author_email' => null, - 'author_name' => null, - )) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->createFile(1, 'dir/file1.txt', 'some contents', 'master', 'Added new file', 'text')); - } - - /** - * @test - */ - public function shouldCreateFileWithAuthor() - { - $expectedArray = array('file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt'); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('post') - ->with('projects/1/repository/files', array( - 'file_path' => 'dir/file1.txt', - 'branch' => 'master', - 'encoding' => null, - 'content' => 'some contents', - 'commit_message' => 'Added new file', - 'author_email' => 'gitlab@example.com', - 'author_name' => 'GitLab User', - )) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->createFile(1, 'dir/file1.txt', 'some contents', 'master', 'Added new file', null, 'gitlab@example.com', 'GitLab User')); - } - - /** - * @test - */ - public function shouldUpdateFile() - { - $expectedArray = array('file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt'); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('put') - ->with('projects/1/repository/files', array( - 'file_path' => 'dir/file1.txt', - 'branch' => 'master', - 'encoding' => null, - 'content' => 'some new contents', - 'commit_message' => 'Updated new file', - 'author_email' => null, - 'author_name' => null, - )) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->updateFile(1, 'dir/file1.txt', 'some new contents', 'master', 'Updated new file')); - } - - /** - * @test - */ - public function shouldUpdateFileWithEncoding() - { - $expectedArray = array('file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt'); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('put') - ->with('projects/1/repository/files', array( - 'file_path' => 'dir/file1.txt', - 'branch' => 'master', - 'encoding' => 'base64', - 'content' => 'some new contents', - 'commit_message' => 'Updated file', - 'author_email' => null, - 'author_name' => null, - )) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->updateFile(1, 'dir/file1.txt', 'some new contents', 'master', 'Updated file', 'base64')); - } - - /** - * @test - */ - public function shouldUpdateFileWithAuthor() - { - $expectedArray = array('file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt'); - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('put') - ->with('projects/1/repository/files', array( - 'file_path' => 'dir/file1.txt', - 'branch' => 'master', - 'encoding' => null, - 'content' => 'some new contents', - 'commit_message' => 'Updated file', - 'author_email' => 'gitlab@example.com', - 'author_name' => 'GitLab User', - )) - ->will($this->returnValue($expectedArray)) - ; - - $this->assertEquals($expectedArray, $api->updateFile(1, 'dir/file1.txt', 'some new contents', 'master', 'Updated file', null, 'gitlab@example.com', 'GitLab User')); - } - - /** - * @test - */ - public function shouldDeleteFile() - { - $expectedBool = true; - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('delete') - ->with('projects/1/repository/files', array( - 'file_path' => 'dir/file1.txt', - 'branch' => 'master', - 'commit_message' => 'Deleted file', - 'author_email' => null, - 'author_name' => null, - )) - ->will($this->returnValue($expectedBool)) - ; - - $this->assertEquals($expectedBool, $api->deleteFile(1, 'dir/file1.txt', 'master', 'Deleted file')); - } - - /** - * @test - */ - public function shouldDeleteFileWithAuthor() - { - $expectedBool = true; - - $api = $this->getApiMock(); - $api->expects($this->once()) - ->method('delete') - ->with('projects/1/repository/files', array( - 'file_path' => 'dir/file1.txt', - 'branch' => 'master', - 'commit_message' => 'Deleted file', - 'author_email' => 'gitlab@example.com', - 'author_name' => 'GitLab User', - )) - ->will($this->returnValue($expectedBool)) - ; - - $this->assertEquals($expectedBool, $api->deleteFile(1, 'dir/file1.txt', 'master', 'Deleted file', 'gitlab@example.com', 'GitLab User')); - } - /** * @test */ diff --git a/test/Gitlab/Tests/Api/RepositoryFilesTest.php b/test/Gitlab/Tests/Api/RepositoryFilesTest.php new file mode 100644 index 000000000..d37b60f47 --- /dev/null +++ b/test/Gitlab/Tests/Api/RepositoryFilesTest.php @@ -0,0 +1,279 @@ +getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/repository/files/dir%2Ffile1%2Etxt/raw', array('ref' => 'abcd1234')) + ->will($this->returnValue($expectedString)) + ; + + $this->assertEquals($expectedString, $api->getRawFile(1, 'dir/file1.txt', 'abcd1234')); + } + + /** + * @test + */ + public function shouldGetFile() + { + $expectedArray = array('file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/repository/files/dir%2Ffile1%2Etxt', array('ref' => 'abcd1234')) + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->getFile(1, 'dir/file1.txt', 'abcd1234')); + } + + /** + * @test + */ + public function shouldCreateFile() + { + $expectedArray = array('file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/repository/files/dir%2Ffile1%2Etxt', array( + 'file_path' => 'dir/file1.txt', + 'branch' => 'master', + 'content' => 'some contents', + 'commit_message' => 'Added new file', + )) + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->createFile(1, [ + 'file_path' => 'dir/file1.txt', + 'content' => 'some contents', + 'branch' => 'master', + 'commit_message' => 'Added new file', + ])); + } + + /** + * @test + */ + public function shouldCreateFileWithEncoding() + { + $expectedArray = array('file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/repository/files/dir%2Ffile1%2Etxt', array( + 'file_path' => 'dir/file1.txt', + 'branch' => 'master', + 'encoding' => 'text', + 'content' => 'some contents', + 'commit_message' => 'Added new file', + )) + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->createFile(1, [ + 'file_path' => 'dir/file1.txt', + 'content' => 'some contents', + 'branch' => 'master', + 'commit_message' => 'Added new file', + 'encoding' => 'text', + ])); + } + + /** + * @test + */ + public function shouldCreateFileWithAuthor() + { + $expectedArray = array('file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/repository/files/dir%2Ffile1%2Etxt', array( + 'file_path' => 'dir/file1.txt', + 'branch' => 'master', + 'content' => 'some contents', + 'commit_message' => 'Added new file', + 'author_email' => 'gitlab@example.com', + 'author_name' => 'GitLab User', + )) + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->createFile(1, [ + 'file_path' => 'dir/file1.txt', + 'content' => 'some contents', + 'branch' => 'master', + 'commit_message' => 'Added new file', + 'author_email' => 'gitlab@example.com', + 'author_name' => 'GitLab User', + ])); + } + + /** + * @test + */ + public function shouldUpdateFile() + { + $expectedArray = array('file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('put') + ->with('projects/1/repository/files/dir%2Ffile1%2Etxt', array( + 'file_path' => 'dir/file1.txt', + 'branch' => 'master', + 'content' => 'some new contents', + 'commit_message' => 'Updated new file', + )) + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->updateFile(1, [ + 'file_path' => 'dir/file1.txt', + 'content' => 'some new contents', + 'branch' => 'master', + 'commit_message' => 'Updated new file', + ])); + } + + /** + * @test + */ + public function shouldUpdateFileWithEncoding() + { + $expectedArray = array('file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('put') + ->with('projects/1/repository/files/dir%2Ffile1%2Etxt', array( + 'file_path' => 'dir/file1.txt', + 'branch' => 'master', + 'encoding' => 'base64', + 'content' => 'c29tZSBuZXcgY29udGVudHM=', + 'commit_message' => 'Updated file', + )) + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->updateFile(1, [ + 'file_path' => 'dir/file1.txt', + 'content' => 'c29tZSBuZXcgY29udGVudHM=', + 'branch' => 'master', + 'commit_message' => 'Updated file', + 'encoding' => 'base64', + ])); + } + + /** + * @test + */ + public function shouldUpdateFileWithAuthor() + { + $expectedArray = array('file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('put') + ->with('projects/1/repository/files/dir%2Ffile1%2Etxt', array( + 'file_path' => 'dir/file1.txt', + 'branch' => 'master', + 'content' => 'some new contents', + 'commit_message' => 'Updated file', + 'author_email' => 'gitlab@example.com', + 'author_name' => 'GitLab User', + )) + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->updateFile(1, [ + 'file_path' => 'dir/file1.txt', + 'content' => 'some new contents', + 'branch' => 'master', + 'commit_message' => 'Updated file', + 'author_email' => 'gitlab@example.com', + 'author_name' => 'GitLab User', + ])); + } + + /** + * @test + */ + public function shouldDeleteFile() + { + $expectedArray = ["file_name" => "app/project.rb", "branch" => "master"]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('projects/1/repository/files/dir%2Ffile1%2Etxt', array( + 'file_path' => 'dir/file1.txt', + 'branch' => 'master', + 'commit_message' => 'Deleted file', + )) + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->deleteFile(1, [ + 'file_path' => 'dir/file1.txt', + 'branch' => 'master', + 'commit_message' => 'Deleted file' + ])); + } + + /** + * @test + */ + public function shouldDeleteFileWithAuthor() + { + $expectedArray = ["file_name" => "app/project.rb", "branch" => "master"]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('projects/1/repository/files/dir%2Ffile1%2Etxt', array( + 'file_path' => 'dir/file1.txt', + 'branch' => 'master', + 'commit_message' => 'Deleted file', + 'author_email' => 'gitlab@example.com', + 'author_name' => 'GitLab User', + )) + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->deleteFile(1, [ + 'file_path' => 'dir/file1.txt', + 'branch' => 'master', + 'commit_message' => 'Deleted file', + 'author_email' => 'gitlab@example.com', + 'author_name' => 'GitLab User', + ])); + } + + /** + * @return string + */ + protected function getApiClass() + { + return RepositoryFiles::class; + } +} From 275a5d48fe1cf3978cfb20681d242f5e2917e6d0 Mon Sep 17 00:00:00 2001 From: Kyle Wiering Date: Thu, 7 Sep 2017 15:42:04 -0500 Subject: [PATCH 78/83] #242 Gitlab/Model/MergeRequest methods fails on incorrect id usage * Adjusted the model to use the iid instead of id. --- lib/Gitlab/Model/MergeRequest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Gitlab/Model/MergeRequest.php b/lib/Gitlab/Model/MergeRequest.php index 49e88017b..f22d6f1f2 100644 --- a/lib/Gitlab/Model/MergeRequest.php +++ b/lib/Gitlab/Model/MergeRequest.php @@ -105,7 +105,7 @@ public function __construct(Project $project, $id = null, Client $client = null) */ public function show() { - $data = $this->client->mergeRequests()->show($this->project->id, $this->id); + $data = $this->client->mergeRequests()->show($this->project->id, $this->iid); return static::fromArray($this->getClient(), $this->project, $data); } @@ -116,7 +116,7 @@ public function show() */ public function update(array $params) { - $data = $this->client->mergeRequests()->update($this->project->id, $this->id, $params); + $data = $this->client->mergeRequests()->update($this->project->id, $this->iid, $params); return static::fromArray($this->getClient(), $this->project, $data); } @@ -160,7 +160,7 @@ public function open() */ public function merge($message = null) { - $data = $this->client->mergeRequests()->merge($this->project->id, $this->id, array( + $data = $this->client->mergeRequests()->merge($this->project->id, $this->iid, array( 'merge_commit_message' => $message )); @@ -183,7 +183,7 @@ public function merged() */ public function addComment($comment) { - $data = $this->client->mergeRequests()->addComment($this->project->id, $this->id, $comment); + $data = $this->client->mergeRequests()->addComment($this->project->id, $this->iid, $comment); return Note::fromArray($this->getClient(), $this, $data); } @@ -194,7 +194,7 @@ public function addComment($comment) public function showComments() { $notes = array(); - $data = $this->client->mergeRequests()->showComments($this->project->id, $this->id); + $data = $this->client->mergeRequests()->showComments($this->project->id, $this->iid); foreach ($data as $note) { $notes[] = Note::fromArray($this->getClient(), $this, $note); @@ -220,7 +220,7 @@ public function isClosed() */ public function changes() { - $data = $this->client->mergeRequests()->changes($this->project->id, $this->id); + $data = $this->client->mergeRequests()->changes($this->project->id, $this->iid); return static::fromArray($this->getClient(), $this->project, $data); } From 41bc13f1622ee34ed6b25fd98f09265692cec45b Mon Sep 17 00:00:00 2001 From: Kyle Wiering Date: Fri, 8 Sep 2017 08:52:14 -0500 Subject: [PATCH 79/83] #242 Gitlab/Model/MergeRequest methods fails on incorrect id usage * Adjusted the model to use the iid instead of id. --- lib/Gitlab/Model/MergeRequest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Gitlab/Model/MergeRequest.php b/lib/Gitlab/Model/MergeRequest.php index f22d6f1f2..03251f3b0 100644 --- a/lib/Gitlab/Model/MergeRequest.php +++ b/lib/Gitlab/Model/MergeRequest.php @@ -90,14 +90,14 @@ public static function fromArray(Client $client, Project $project, array $data) /** * @param Project $project - * @param int $id + * @param int $iid * @param Client $client */ - public function __construct(Project $project, $id = null, Client $client = null) + public function __construct(Project $project, $iid = null, Client $client = null) { $this->setClient($client); $this->setData('project', $project); - $this->setData('id', $id); + $this->setData('iid', $iid); } /** From bf83136e00b92deb52fd2c3b3133523ffe03fcc1 Mon Sep 17 00:00:00 2001 From: Romain Gautier Date: Tue, 29 Aug 2017 09:59:37 +0200 Subject: [PATCH 80/83] add award_emoji API's --- lib/Gitlab/Api/Issues.php | 11 +++++++++++ lib/Gitlab/Api/MergeRequests.php | 11 +++++++++++ lib/Gitlab/Api/Snippets.php | 11 +++++++++++ 3 files changed, 33 insertions(+) diff --git a/lib/Gitlab/Api/Issues.php b/lib/Gitlab/Api/Issues.php index 9eb7e67a4..9952ccea0 100644 --- a/lib/Gitlab/Api/Issues.php +++ b/lib/Gitlab/Api/Issues.php @@ -198,4 +198,15 @@ public function getTimeStats($project_id, $issue_iid) { return $this->get($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_iid) .'/time_stats')); } + + /** + * @param int $project_id + * @param int $issue_iid + * + * @return mixed + */ + public function awardEmoji($project_id, $issue_iid) + { + return $this->get($this->getProjectPath($project_id, 'issues/'.$this->encodePath($issue_iid).'/award_emoji')); + } } diff --git a/lib/Gitlab/Api/MergeRequests.php b/lib/Gitlab/Api/MergeRequests.php index 691ca393e..0cdc602dd 100644 --- a/lib/Gitlab/Api/MergeRequests.php +++ b/lib/Gitlab/Api/MergeRequests.php @@ -242,4 +242,15 @@ public function unapprove($project_id, $merge_request_iid) { return $this->post($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($merge_request_iid).'/unapprove')); } + + /** + * @param int $project_id + * @param int $merge_request_iid + * + * @return mixed + */ + public function awardEmoji($project_id, $merge_request_iid) + { + return $this->get($this->getProjectPath($project_id, 'merge_requests/'.$this->encodePath($merge_request_iid).'/award_emoji')); + } } diff --git a/lib/Gitlab/Api/Snippets.php b/lib/Gitlab/Api/Snippets.php index 00921128c..e17c0cba7 100644 --- a/lib/Gitlab/Api/Snippets.php +++ b/lib/Gitlab/Api/Snippets.php @@ -67,4 +67,15 @@ public function remove($project_id, $snippet_id) { return $this->delete($this->getProjectPath($project_id, 'snippets/'.$this->encodePath($snippet_id))); } + + /** + * @param int $project_id + * @param int $snippet_id + * + * @return mixed + */ + public function awardEmoji($project_id, $snippet_id) + { + return $this->get($this->getProjectPath($project_id, 'snippets/'.$this->encodePath($snippet_id).'/award_emoji')); + } } From 0545bcaac709b4f807e6cbdbd04b7b887f4662b9 Mon Sep 17 00:00:00 2001 From: Romain Gautier Date: Mon, 11 Sep 2017 11:43:51 +0200 Subject: [PATCH 81/83] add tests --- test/Gitlab/Tests/Api/IssuesTest.php | 20 ++++++++++++++++++++ test/Gitlab/Tests/Api/MergeRequestsTest.php | 19 +++++++++++++++++++ test/Gitlab/Tests/Api/SnippetsTest.php | 20 ++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/test/Gitlab/Tests/Api/IssuesTest.php b/test/Gitlab/Tests/Api/IssuesTest.php index 0bd9e66fa..727897b37 100644 --- a/test/Gitlab/Tests/Api/IssuesTest.php +++ b/test/Gitlab/Tests/Api/IssuesTest.php @@ -270,6 +270,26 @@ public function shouldGetIssueTimeStats() $this->assertEquals($expectedArray, $api->getTimeStats(1, 2)); } + /** + * @test + */ + public function shouldGetIssueAwardEmoji() + { + $expectedArray = array( + array('id' => 1, 'name' => 'sparkles'), + array('id' => 2, 'name' => 'heart_eyes'), + ); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/issues/2/award_emoji') + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->awardEmoji(1, 2)); + } + protected function getApiClass() { return 'Gitlab\Api\Issues'; diff --git a/test/Gitlab/Tests/Api/MergeRequestsTest.php b/test/Gitlab/Tests/Api/MergeRequestsTest.php index 6605c7ea4..e13a0aebd 100644 --- a/test/Gitlab/Tests/Api/MergeRequestsTest.php +++ b/test/Gitlab/Tests/Api/MergeRequestsTest.php @@ -266,6 +266,25 @@ public function shouldGetMergeRequestApprovals() $this->assertEquals($expectedArray, $api->all(1, ['iids' => [2]])); } + /** + * @test + */ + public function shouldGetMergeRequestAwardEmoji() + { + $expectedArray = array( + array('id' => 1, 'name' => 'sparkles'), + array('id' => 2, 'name' => 'heart_eyes'), + ); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/merge_requests/2/award_emoji') + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->awardEmoji(1, 2)); + } protected function getMultipleMergeRequestsData() { diff --git a/test/Gitlab/Tests/Api/SnippetsTest.php b/test/Gitlab/Tests/Api/SnippetsTest.php index 5a7c97922..f6782607f 100644 --- a/test/Gitlab/Tests/Api/SnippetsTest.php +++ b/test/Gitlab/Tests/Api/SnippetsTest.php @@ -107,6 +107,26 @@ public function shouldRemoveSnippet() $this->assertEquals($expectedBool, $api->remove(1, 3)); } + /** + * @test + */ + public function shouldGetSnippetAwardEmoji() + { + $expectedArray = array( + array('id' => 1, 'name' => 'sparkles'), + array('id' => 2, 'name' => 'heart_eyes'), + ); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/snippets/2/award_emoji') + ->will($this->returnValue($expectedArray)) + ; + + $this->assertEquals($expectedArray, $api->awardEmoji(1, 2)); + } + protected function getApiClass() { return 'Gitlab\Api\Snippets'; From 65eb6702d39fc2c2076356e2ded6649d1fb89509 Mon Sep 17 00:00:00 2001 From: fireraccoon Date: Thu, 14 Sep 2017 01:19:23 -0400 Subject: [PATCH 82/83] Issues API: Add support for 'scope' parameter --- lib/Gitlab/Api/Issues.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/Gitlab/Api/Issues.php b/lib/Gitlab/Api/Issues.php index 9952ccea0..55fcd2e85 100644 --- a/lib/Gitlab/Api/Issues.php +++ b/lib/Gitlab/Api/Issues.php @@ -10,6 +10,7 @@ class Issues extends AbstractApi * @var string $labels Comma-separated list of label names, issues must have all labels to be returned. * No+Label lists all issues with no labels. * @var string $milestone The milestone title. + * @var string scope Return issues for the given scope: created-by-me, assigned-to-me or all. Defaults to created-by-me * @var int[] $iids Return only the issues having the given iid. * @var string $order_by Return requests ordered by created_at or updated_at fields. Default is created_at. * @var string $sort Return requests sorted in asc or desc order. Default is desc. @@ -33,6 +34,9 @@ public function all($project_id = null, array $parameters = []) return count($value) == count(array_filter($value, 'is_int')); }) ; + $resolver->setDefined('scope') + ->setAllowedValues('scope', ['created-by-me', 'assigned-to-me', 'all']) + ; $resolver->setDefined('order_by') ->setAllowedValues('order_by', ['created_at', 'updated_at']) ; From 38cf0ed8e80e97643a3284640c7ddb24854edb58 Mon Sep 17 00:00:00 2001 From: Stanislav Gamayunov Date: Mon, 18 Sep 2017 12:40:55 +0500 Subject: [PATCH 83/83] Added missing property 'start_date' to Milestone model --- lib/Gitlab/Model/Milestone.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/Gitlab/Model/Milestone.php b/lib/Gitlab/Model/Milestone.php index 8f749417b..8b07d38af 100644 --- a/lib/Gitlab/Model/Milestone.php +++ b/lib/Gitlab/Model/Milestone.php @@ -11,6 +11,7 @@ * @property-read string $title * @property-read string $description * @property-read string $due_date + * @property-read string $start_date * @property-read string $state * @property-read bool $closed * @property-read string $updated_at @@ -30,6 +31,7 @@ class Milestone extends AbstractModel 'title', 'description', 'due_date', + 'start_date', 'state', 'closed', 'updated_at',