From 579f9bc915697b0aca883f22e31ddf37d4455116 Mon Sep 17 00:00:00 2001 From: Vincent Jacques Date: Sat, 8 Sep 2012 14:30:06 +0200 Subject: [PATCH] Repository.merge (issue #69) --- .../description.human_readable.json | 20 +++++++ .../description.normalized.json | 56 +++++++++++++++++++ doc/ReferenceOfApis.md | 2 +- doc/ReferenceOfClasses.md | 7 +++ github/Repository.py | 21 +++++++ .../Repository.testMergeWithConflict.txt | 5 ++ .../Repository.testMergeWithMessage.txt | 5 ++ .../Repository.testMergeWithNothingToDo.txt | 5 ++ .../Repository.testMergeWithoutMessage.txt | 5 ++ test/Repository.py | 20 +++++++ 10 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 test/ReplayData/Repository.testMergeWithConflict.txt create mode 100644 test/ReplayData/Repository.testMergeWithMessage.txt create mode 100644 test/ReplayData/Repository.testMergeWithNothingToDo.txt create mode 100644 test/ReplayData/Repository.testMergeWithoutMessage.txt diff --git a/codegen/JsonDescriptionOfGithubApiV3/description.human_readable.json b/codegen/JsonDescriptionOfGithubApiV3/description.human_readable.json index e79a54f9..485f3476 100644 --- a/codegen/JsonDescriptionOfGithubApiV3/description.human_readable.json +++ b/codegen/JsonDescriptionOfGithubApiV3/description.human_readable.json @@ -1920,6 +1920,26 @@ ] } }, + { + "name": [ "merge" ], + "type": "Commit", + "group": "merging", + "mandatoryParameters": [ + { "name": "base", "type": "string" }, + { "name": "head", "type": "string" } + ], + "optionalParameters": [ + { "name": "commit_message", "type": "string" } + ], + "request": { + "verb": "POST", + "url": [ + { "type": "attribute", "value": [ "url" ] }, + { "type": "constant", "value": "/merges" } + ], + "postParameters": true + } + }, { "name": [ "compare" ], "type": "Comparison", diff --git a/codegen/JsonDescriptionOfGithubApiV3/description.normalized.json b/codegen/JsonDescriptionOfGithubApiV3/description.normalized.json index 4a6151ac..c1b80fca 100644 --- a/codegen/JsonDescriptionOfGithubApiV3/description.normalized.json +++ b/codegen/JsonDescriptionOfGithubApiV3/description.normalized.json @@ -11129,6 +11129,62 @@ "name": "string" } }, + { + "group": "merging", + "name": [ + "merge" + ], + "mandatoryParameters": [ + { + "type": { + "simple": true, + "cardinality": "scalar", + "name": "string" + }, + "name": "base" + }, + { + "type": { + "simple": true, + "cardinality": "scalar", + "name": "string" + }, + "name": "head" + } + ], + "request": { + "url": [ + { + "type": "attribute", + "value": [ + "url" + ] + }, + { + "type": "constant", + "value": "/merges" + } + ], + "postParameters": true, + "verb": "POST" + }, + "isMutation": false, + "optionalParameters": [ + { + "type": { + "simple": true, + "cardinality": "scalar", + "name": "string" + }, + "name": "commit_message" + } + ], + "type": { + "simple": false, + "cardinality": "scalar", + "name": "Commit" + } + }, { "group": "Comparison", "name": [ diff --git a/doc/ReferenceOfApis.md b/doc/ReferenceOfApis.md index 5a3fe1c5..651c21fc 100644 --- a/doc/ReferenceOfApis.md +++ b/doc/ReferenceOfApis.md @@ -347,7 +347,7 @@ API `/repos/:user/:repo/languages` API `/repos/:user/:repo/merges` =============================== -* POST: (TODO) +* POST: `Repository.merge` API `/repos/:user/:repo/milestones` =================================== diff --git a/doc/ReferenceOfClasses.md b/doc/ReferenceOfClasses.md index b13336ff..b8024f78 100644 --- a/doc/ReferenceOfClasses.md +++ b/doc/ReferenceOfClasses.md @@ -1323,6 +1323,13 @@ Languages --------- * `get_languages()`: dict of string to integer +Merging +------- +* `merge( base, head, [commit_message] )`: `Commit` + * `base`: string + * `head`: string + * `commit_message`: string + Milestones ---------- * `create_milestone( title, [state, description, due_on] )`: `Milestone` diff --git a/github/Repository.py b/github/Repository.py index bbae4e1f..4703ff7f 100644 --- a/github/Repository.py +++ b/github/Repository.py @@ -1112,6 +1112,27 @@ class Repository( GithubObject.GithubObject ): for element in data[ "issues" ] ] + def merge( self, base, head, commit_message = GithubObject.NotSet ): + assert isinstance( base, ( str, unicode ) ), base + assert isinstance( head, ( str, unicode ) ), head + assert commit_message is GithubObject.NotSet or isinstance( commit_message, ( str, unicode ) ), commit_message + post_parameters = { + "base": base, + "head": head, + } + if commit_message is not GithubObject.NotSet: + post_parameters[ "commit_message" ] = commit_message + headers, data = self._requester.requestAndCheck( + "POST", + self.url + "/merges", + None, + post_parameters + ) + if data is None: + return None + else: + return Commit.Commit( self._requester, data, completed = True ) + def remove_from_collaborators( self, collaborator ): assert isinstance( collaborator, NamedUser.NamedUser ), collaborator headers, data = self._requester.requestAndCheck( diff --git a/test/ReplayData/Repository.testMergeWithConflict.txt b/test/ReplayData/Repository.testMergeWithConflict.txt new file mode 100644 index 00000000..8ae52174 --- /dev/null +++ b/test/ReplayData/Repository.testMergeWithConflict.txt @@ -0,0 +1,5 @@ +https POST api.github.com None /repos/jacquev6/PyGithub/merges {'Authorization': 'Basic login_and_password_removed'} {"head": "branchForHead", "base": "branchForBase"} +409 +[('status', '409 Conflict'), ('content-length', '28'), ('x-github-media-type', 'github.beta; format=json'), ('x-content-type-options', 'nosniff'), ('x-ratelimit-remaining', '4980'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('cache-control', ''), ('date', 'Sat, 08 Sep 2012 12:29:28 GMT'), ('content-type', 'application/json; charset=utf-8')] +{"message":"Merge conflict"} + diff --git a/test/ReplayData/Repository.testMergeWithMessage.txt b/test/ReplayData/Repository.testMergeWithMessage.txt new file mode 100644 index 00000000..9420c78c --- /dev/null +++ b/test/ReplayData/Repository.testMergeWithMessage.txt @@ -0,0 +1,5 @@ +https POST api.github.com None /repos/jacquev6/PyGithub/merges {'Authorization': 'Basic login_and_password_removed'} {"commit_message": "Commit message created by PyGithub", "head": "branchForHead", "base": "branchForBase"} +201 +[('status', '201 Created'), ('x-ratelimit-remaining', '4988'), ('x-github-media-type', 'github.beta; format=json'), ('x-content-type-options', 'nosniff'), ('x-ratelimit-limit', '5000'), ('content-length', '1670'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('etag', '"f31a393604d4a8295a461319eb518495"'), ('location', 'https://api.github.com/repos/jacquev6/PyGithub/commits/231ab813ab5ccbdc102ee12e663c491794ccc32f'), ('cache-control', 'max-age=0, private, must-revalidate'), ('date', 'Sat, 08 Sep 2012 12:21:08 GMT'), ('content-type', 'application/json; charset=utf-8')] +{"sha":"231ab813ab5ccbdc102ee12e663c491794ccc32f","author":{"gravatar_id":"b68de5ae38616c296fa345d2b9df2225","login":"jacquev6","url":"https://api.github.com/users/jacquev6","avatar_url":"https://secure.gravatar.com/avatar/b68de5ae38616c296fa345d2b9df2225?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png","id":327146},"commit":{"message":"Commit message created by PyGithub","author":{"email":"vincent@vincent-jacques.net","name":"Vincent Jacques","date":"2012-09-08T05:21:08-07:00"},"comment_count":0,"url":"https://api.github.com/repos/jacquev6/PyGithub/git/commits/231ab813ab5ccbdc102ee12e663c491794ccc32f","tree":{"sha":"97223b0c33ab29dd9aa038248dc982354f7d69a1","url":"https://api.github.com/repos/jacquev6/PyGithub/git/trees/97223b0c33ab29dd9aa038248dc982354f7d69a1"},"committer":{"email":"vincent@vincent-jacques.net","name":"Vincent Jacques","date":"2012-09-08T05:21:08-07:00"}},"url":"https://api.github.com/repos/jacquev6/PyGithub/commits/231ab813ab5ccbdc102ee12e663c491794ccc32f","parents":[{"sha":"3be2e82b400f3398c05b68f00a4427604e74c7c5","url":"https://api.github.com/repos/jacquev6/PyGithub/commits/3be2e82b400f3398c05b68f00a4427604e74c7c5"},{"sha":"7a19732ca92cd80fd9da31fa590d67729d6b44df","url":"https://api.github.com/repos/jacquev6/PyGithub/commits/7a19732ca92cd80fd9da31fa590d67729d6b44df"}],"committer":{"gravatar_id":"b68de5ae38616c296fa345d2b9df2225","login":"jacquev6","url":"https://api.github.com/users/jacquev6","avatar_url":"https://secure.gravatar.com/avatar/b68de5ae38616c296fa345d2b9df2225?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png","id":327146}} + diff --git a/test/ReplayData/Repository.testMergeWithNothingToDo.txt b/test/ReplayData/Repository.testMergeWithNothingToDo.txt new file mode 100644 index 00000000..977cae04 --- /dev/null +++ b/test/ReplayData/Repository.testMergeWithNothingToDo.txt @@ -0,0 +1,5 @@ +https POST api.github.com None /repos/jacquev6/PyGithub/merges {'Authorization': 'Basic login_and_password_removed'} {"commit_message": "Commit message created by PyGithub", "head": "branchForHead", "base": "branchForBase"} +204 +[('status', '204 No Content'), ('x-ratelimit-remaining', '4985'), ('x-github-media-type', 'github.beta; format=json'), ('x-content-type-options', 'nosniff'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('cache-control', ''), ('date', 'Sat, 08 Sep 2012 12:22:53 GMT')] + + diff --git a/test/ReplayData/Repository.testMergeWithoutMessage.txt b/test/ReplayData/Repository.testMergeWithoutMessage.txt new file mode 100644 index 00000000..94b604ec --- /dev/null +++ b/test/ReplayData/Repository.testMergeWithoutMessage.txt @@ -0,0 +1,5 @@ +https POST api.github.com None /repos/jacquev6/PyGithub/merges {'Authorization': 'Basic login_and_password_removed'} {"head": "branchForHead", "base": "branchForBase"} +201 +[('status', '201 Created'), ('x-ratelimit-remaining', '4991'), ('x-ratelimit-limit', '5000'), ('x-content-type-options', 'nosniff'), ('content-length', '1674'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('etag', '"9a4000ce96f4c4d47922c7c8896d894f"'), ('location', 'https://api.github.com/repos/jacquev6/PyGithub/commits/a01fa060858e3aced1fe4ad74798295376e76fd4'), ('cache-control', 'max-age=0, private, must-revalidate'), ('date', 'Sat, 08 Sep 2012 12:19:40 GMT'), ('x-github-media-type', 'github.beta; format=json'), ('content-type', 'application/json; charset=utf-8')] +{"sha":"a01fa060858e3aced1fe4ad74798295376e76fd4","committer":{"avatar_url":"https://secure.gravatar.com/avatar/b68de5ae38616c296fa345d2b9df2225?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png","gravatar_id":"b68de5ae38616c296fa345d2b9df2225","url":"https://api.github.com/users/jacquev6","login":"jacquev6","id":327146},"author":{"avatar_url":"https://secure.gravatar.com/avatar/b68de5ae38616c296fa345d2b9df2225?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png","gravatar_id":"b68de5ae38616c296fa345d2b9df2225","url":"https://api.github.com/users/jacquev6","login":"jacquev6","id":327146},"parents":[{"sha":"3be2e82b400f3398c05b68f00a4427604e74c7c5","url":"https://api.github.com/repos/jacquev6/PyGithub/commits/3be2e82b400f3398c05b68f00a4427604e74c7c5"},{"sha":"7a19732ca92cd80fd9da31fa590d67729d6b44df","url":"https://api.github.com/repos/jacquev6/PyGithub/commits/7a19732ca92cd80fd9da31fa590d67729d6b44df"}],"url":"https://api.github.com/repos/jacquev6/PyGithub/commits/a01fa060858e3aced1fe4ad74798295376e76fd4","commit":{"committer":{"email":"vincent@vincent-jacques.net","date":"2012-09-08T05:19:40-07:00","name":"Vincent Jacques"},"author":{"email":"vincent@vincent-jacques.net","date":"2012-09-08T05:19:40-07:00","name":"Vincent Jacques"},"message":"Merge branchForHead into branchForBase","tree":{"sha":"97223b0c33ab29dd9aa038248dc982354f7d69a1","url":"https://api.github.com/repos/jacquev6/PyGithub/git/trees/97223b0c33ab29dd9aa038248dc982354f7d69a1"},"url":"https://api.github.com/repos/jacquev6/PyGithub/git/commits/a01fa060858e3aced1fe4ad74798295376e76fd4","comment_count":0}} + diff --git a/test/Repository.py b/test/Repository.py index a0ffffca..5a7835d1 100644 --- a/test/Repository.py +++ b/test/Repository.py @@ -370,3 +370,23 @@ class Repository( Framework.TestCase ): def testGetBranch( self ): branch = self.repo.get_branch( "develop" ) self.assertEqual( branch.commit.sha, "03058a36164d2a7d946db205f25538434fa27d94" ) + + def testMergeWithoutMessage( self ): + commit = self.repo.merge( "branchForBase", "branchForHead" ) + self.assertEqual( commit.commit.message, "Merge branchForHead into branchForBase" ) + + def testMergeWithMessage( self ): + commit = self.repo.merge( "branchForBase", "branchForHead", "Commit message created by PyGithub" ) + self.assertEqual( commit.commit.message, "Commit message created by PyGithub" ) + + def testMergeWithNothingToDo( self ): + commit = self.repo.merge( "branchForBase", "branchForHead", "Commit message created by PyGithub" ) + self.assertEqual( commit, None ) + + def testMergeWithConflict( self ): + try: + commit = self.repo.merge( "branchForBase", "branchForHead" ) + self.fail( "Should have raised" ) + except github.GithubException, exception: + self.assertEqual( exception.status, 409 ) + self.assertEqual( exception.data, { "message": "Merge conflict" } )