Skip to content

Commit 6a7e688

Browse files
committed
🚒 Made requests creation work more appropriately for github
fixes #94 Signed-off-by: Guyzmo <[email protected]>
1 parent b72374f commit 6a7e688

File tree

5 files changed

+53
-25
lines changed

5 files changed

+53
-25
lines changed

git_repo/repo.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -169,26 +169,29 @@ def init(self): # pragma: no cover
169169
if 'GIT_WORK_TREE' in os.environ.keys() or 'GIT_DIR' in os.environ.keys():
170170
del os.environ['GIT_WORK_TREE']
171171

172-
def _guess_repo_slug(self, repository, service):
172+
def _guess_repo_slug(self, repository, service, resolve_targets=None):
173173
config = repository.config_reader()
174-
target = service.name
174+
if resolve_targets:
175+
targets = [target.format(service=service.name) for target in resolve_targets]
176+
else:
177+
targets = (service.name, 'upstream', 'origin')
175178
for remote in repository.remotes:
176-
if remote.name in (target, 'upstream', 'origin'):
179+
if remote.name in targets:
177180
for url in remote.urls:
178181
if url.startswith('https'):
179182
if url.endswith('.git'):
180183
url = url[:-4]
181184
*_, user, name = url.split('/')
182185
self.set_repo_slug('/'.join([user, name]))
183-
break
186+
return
184187
elif url.startswith('git@'):
185188
if url.endswith('.git'):
186189
url = url[:-4]
187190
_, repo_slug = url.split(':')
188191
self.set_repo_slug(repo_slug)
189-
break
192+
return
190193

191-
def get_service(self, lookup_repository=True):
194+
def get_service(self, lookup_repository=True, resolve_targets=None):
192195
if not lookup_repository:
193196
service = RepositoryService.get_service(None, self.target)
194197
service.connect()
@@ -203,7 +206,7 @@ def get_service(self, lookup_repository=True):
203206
raise FileNotFoundError('Cannot find path to the repository.')
204207
service = RepositoryService.get_service(repository, self.target)
205208
if not self.repo_name:
206-
self._guess_repo_slug(repository, service)
209+
self._guess_repo_slug(repository, service, resolve_targets)
207210
return service
208211

209212
'''Argument storage'''
@@ -408,13 +411,14 @@ def do_request_list(self):
408411

409412
@register_action('request', 'create')
410413
def do_request_create(self):
411-
service = self.get_service()
414+
service = self.get_service(resolve_targets=('upstream', '{service}', 'origin'))
412415
new_request = service.request_create(self.user_name,
413416
self.repo_name,
414417
self.local_branch,
415418
self.remote_branch,
416419
self.title,
417-
self.message)
420+
self.message,
421+
self.repo_slug != None)
418422
log.info('Successfully created request of `{local}` onto `{}:{remote}`, with id `{ref}`!'.format(
419423
'/'.join([self.user_name, self.repo_name]),
420424
**new_request)

git_repo/services/ext/github.py

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -231,29 +231,50 @@ def gist_delete(self, gist_id):
231231
raise ResourceNotFoundError('Could not find gist')
232232
gist.delete()
233233

234-
def request_create(self, user, repo, local_branch, remote_branch, title, description=None):
234+
def request_create(self, user, repo, from_branch, onto_branch, title, description=None, auto_slug=False):
235235
repository = self.gh.repository(user, repo)
236236
if not repository:
237237
raise ResourceNotFoundError('Could not find repository `{}/{}`!'.format(user, repo))
238-
if not remote_branch:
239-
remote_branch = self.repository.active_branch.name
240-
if not local_branch:
241-
local_branch = repository.master_branch or 'master'
238+
# when no repo slug has been given to `git-repo X request create`
239+
if auto_slug:
240+
# then chances are current repository is a fork of the target
241+
# repository we want to push to
242+
if repository.fork:
243+
user = repository.parent.owner.login
244+
repo = repository.parent.name
245+
from_branch = from_branch or repository.parent.default_branch
246+
# if no onto branch has been defined, take the default one
247+
# with a fallback on master
248+
if not from_branch:
249+
from_branch = self.repository.active_branch.name
250+
# if no from branch has been defined, chances are we want to push
251+
# the branch we're currently working on
252+
if not onto_branch:
253+
onto_branch = repository.default_branch or 'master'
254+
if self.username != repository.owner.login:
255+
from_branch = ':'.join([self.username, from_branch])
242256
try:
243257
request = repository.create_pull(title,
244-
base=local_branch,
245-
head=':'.join([user, remote_branch]),
258+
base=onto_branch,
259+
head=from_branch,
246260
body=description)
247261
except github3.models.GitHubError as err:
248262
if err.code == 422:
249263
if err.message == 'Validation Failed':
250264
for error in err.errors:
251265
if 'message' in error:
252266
raise ResourceError(error['message'])
267+
if error.get('code', '') == 'invalid':
268+
if error.get('field', '') == 'head':
269+
raise ResourceError(
270+
'Invalid source branch. ' \
271+
'Check it has been pushed first.')
272+
if error.get('field', '') == 'base':
273+
raise ResourceError( 'Invalid target branch.')
253274
raise ResourceError("Unhandled formatting error: {}".format(err.errors))
254275
raise ResourceError(err.message)
255276

256-
return {'local': local_branch, 'remote': remote_branch, 'ref': request.number}
277+
return {'local': from_branch, 'remote': onto_branch, 'ref': request.number}
257278

258279
def request_list(self, user, repo):
259280
repository = self.gh.repository(user, repo)

git_repo/services/ext/gitlab.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ def gist_delete(self, snippet):
267267

268268
return snippet.delete()
269269

270-
def request_create(self, user, repo, local_branch, remote_branch, title, description=None):
270+
def request_create(self, user, repo, local_branch, remote_branch, title, description=None, auto_slug=False):
271271
try:
272272
repository = self.gl.projects.get('/'.join([user, repo]))
273273
if not repository:

git_repo/services/service.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,9 @@ def request_fetch(self, user, repo, request, pull=False): #pragma: no cover
429429
'''
430430
raise NotImplementedError
431431

432+
def request_create(self, user, repo, from_branch, onto_branch, title, description=None, auto_slug=False):
433+
raise NotImplementedError
434+
432435
@property
433436
def user(self): #pragma: no cover
434437
raise NotImplementedError

tests/integration/test_main.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ def test_request_create(self, capsys, caplog):
409409
'--message': 'This is a test'
410410
})
411411
out, err = capsys.readouterr()
412-
assert ('guyzmo', 'test', 'pr-test', 'base-test', 'This is a test', 'This is a test') == seen_args
412+
assert ('guyzmo', 'test', 'pr-test', 'base-test', 'This is a test', 'This is a test', True) == seen_args
413413
assert {} == extra_args
414414
assert out == ''
415415
assert 'Successfully created request of `pr-test` onto `guyzmo/test:base-test`, with id `42`!' in caplog.text
@@ -424,7 +424,7 @@ def test_request_create__no_description(self, capsys, caplog):
424424
'<title>': 'This is a test',
425425
})
426426
out, err = capsys.readouterr()
427-
assert ('guyzmo', 'test', 'pr-test', 'base-test', 'This is a test', None) == seen_args
427+
assert ('guyzmo', 'test', 'pr-test', 'base-test', 'This is a test', None, True) == seen_args
428428
assert {} == extra_args
429429
assert out == ''
430430
assert 'Successfully created request of `pr-test` onto `guyzmo/test:base-test`, with id `42`!' in caplog.text
@@ -440,7 +440,7 @@ def test_request_create__bad_local_branch(self, capsys, caplog):
440440
'--message': 'This is a test'
441441
})
442442
out, err = capsys.readouterr()
443-
assert ('guyzmo', 'test', 'bad', 'base-test', 'This is a test', 'This is a test') == seen_args
443+
assert ('guyzmo', 'test', 'bad', 'base-test', 'This is a test', 'This is a test', True) == seen_args
444444
assert {} == extra_args
445445
assert out == ''
446446
assert 'Fatal error: bad branch to request!' in caplog.text
@@ -456,7 +456,7 @@ def test_request_create__bad_remote_branch(self, capsys, caplog):
456456
'--message': 'This is a test'
457457
})
458458
out, err = capsys.readouterr()
459-
assert ('guyzmo', 'test', 'pr-test', 'bad', 'This is a test', 'This is a test') == seen_args
459+
assert ('guyzmo', 'test', 'pr-test', 'bad', 'This is a test', 'This is a test', True) == seen_args
460460
assert {} == extra_args
461461
assert out == ''
462462
assert 'Fatal error: bad branch to request!' in caplog.text
@@ -471,7 +471,7 @@ def test_request_create__no_local_branch(self, capsys, caplog):
471471
'--message': 'This is a test'
472472
})
473473
out, err = capsys.readouterr()
474-
assert ('guyzmo', 'test', None, 'base-test', 'This is a test', 'This is a test') == seen_args
474+
assert ('guyzmo', 'test', None, 'base-test', 'This is a test', 'This is a test', True) == seen_args
475475
assert {} == extra_args
476476
assert out == ''
477477
assert 'Successfully created request of `pr-test` onto `guyzmo/test:base-test`, with id `42`!' in caplog.text
@@ -486,7 +486,7 @@ def test_request_create__no_remote_branch(self, capsys, caplog):
486486
'--message': 'This is a test'
487487
})
488488
out, err = capsys.readouterr()
489-
assert ('guyzmo', 'test', 'pr-test', None, 'This is a test', 'This is a test') == seen_args
489+
assert ('guyzmo', 'test', 'pr-test', None, 'This is a test', 'This is a test', True) == seen_args
490490
assert {} == extra_args
491491
assert out == ''
492492
assert 'Successfully created request of `pr-test` onto `guyzmo/test:base-test`, with id `42`!' in caplog.text
@@ -562,7 +562,7 @@ def test_request_create__no_repo_slug(self, capsys, caplog):
562562
'--message': 'This is a test'
563563
})
564564
out, err = capsys.readouterr()
565-
assert ('guyzmo', 'git-repo', 'pr-test', 'base-test', 'This is a test', 'This is a test') == seen_args
565+
assert ('guyzmo', 'git-repo', 'pr-test', 'base-test', 'This is a test', 'This is a test', True) == seen_args
566566
assert {} == extra_args
567567
assert out == ''
568568
assert 'Successfully created request of `pr-test` onto `guyzmo/git-repo:base-test`, with id `42`!' in caplog.text

0 commit comments

Comments
 (0)