|
2 | 2 |
|
3 | 3 | '''
|
4 | 4 | Usage:
|
5 |
| - {self} [--path=<path>] [-v...] <target> fork [<branch>] [--clone] |
| 5 | + {self} [--path=<path>] [-v...] <target> fork [--branch=<branch>] |
6 | 6 | {self} [--path=<path>] [-v...] <target> create [--add]
|
7 | 7 | {self} [--path=<path>] [-v...] <target> delete [-f]
|
8 | 8 | {self} [--path=<path>] [-v...] <target> open
|
9 |
| - {self} [--path=<path>] [-v...] <target> fork <user>/<repo> [<branch>] [--clone] |
| 9 | + {self} [--path=<path>] [-v...] <target> fork <user>/<repo> [--branch=<branch>] |
| 10 | + {self} [--path=<path>] [-v...] <target> fork <user>/<repo> <repo> [--branch=<branch>] |
10 | 11 | {self} [--path=<path>] [-v...] <target> create <user>/<repo> [--add]
|
11 | 12 | {self} [--path=<path>] [-v...] <target> delete <user>/<repo> [-f]
|
12 | 13 | {self} [--path=<path>] [-v...] <target> open <user>/<repo>
|
13 |
| - {self} [--path=<path>] [-v...] <target> clone <user>/<repo> [<branch>] |
| 14 | + {self} [--path=<path>] [-v...] <target> clone <user>/<repo> [<repo> [<branch>]] |
14 | 15 | {self} [--path=<path>] [-v...] <target> add <user>/<repo> [<name>] [--tracking=<branch>] [-a]
|
15 | 16 | {self} [--path=<path>] [-v...] <target> request (list|ls)
|
16 | 17 | {self} [--path=<path>] [-v...] <target> request fetch <request>
|
|
55 | 56 | -t,--tracking=<branch> Makes this remote tracking for the current branch
|
56 | 57 | -a,--alone Does not add the remote to the 'all' remote
|
57 | 58 |
|
58 |
| -Options for fork and clone: |
59 |
| - <branch> Branch to pull (when cloning) [default: master] |
60 |
| - --clone Clone locally after fork |
| 59 | +Option for both clone and fork: |
| 60 | + <repo> Name of the local workspace directory |
| 61 | +
|
| 62 | +Options for clone: |
| 63 | + <branch> Branch to pull [default: master] |
| 64 | +
|
| 65 | +Options for fork: |
| 66 | + --branch=<branch> Branch to pull [default: master] |
61 | 67 |
|
62 | 68 | Options for create:
|
63 | 69 | --add Add to local repository after creation
|
@@ -159,19 +165,20 @@ def _guess_repo_slug(self, repository, service):
|
159 | 165 | config = repository.config_reader()
|
160 | 166 | target = service.name
|
161 | 167 | for remote in repository.remotes:
|
162 |
| - for url in remote.urls: |
163 |
| - if url.startswith('https'): |
164 |
| - if '.git' in url: |
165 |
| - url = url[:-4] |
166 |
| - *_, user, name = url.split('/') |
167 |
| - self.set_repo_slug('/'.join([user, name])) |
168 |
| - break |
169 |
| - elif url.startswith('git@'): |
170 |
| - if '.git' in url: |
171 |
| - url = url[:-4] |
172 |
| - _, repo_slug = url.split(':') |
173 |
| - self.set_repo_slug(repo_slug) |
174 |
| - break |
| 168 | + if remote.name in (target, 'upstream', 'origin'): |
| 169 | + for url in remote.urls: |
| 170 | + if url.startswith('https'): |
| 171 | + if '.git' in url: |
| 172 | + url = url[:-4] |
| 173 | + *_, user, name = url.split('/') |
| 174 | + self.set_repo_slug('/'.join([user, name])) |
| 175 | + break |
| 176 | + elif url.startswith('git@'): |
| 177 | + if '.git' in url: |
| 178 | + url = url[:-4] |
| 179 | + _, repo_slug = url.split(':') |
| 180 | + self.set_repo_slug(repo_slug) |
| 181 | + break |
175 | 182 |
|
176 | 183 | def get_service(self, lookup_repository=True):
|
177 | 184 | if not lookup_repository:
|
@@ -243,6 +250,19 @@ def set_branch(self, branch):
|
243 | 250 |
|
244 | 251 | self.branch = branch
|
245 | 252 |
|
| 253 | + @store_parameter('<branch>') |
| 254 | + @store_parameter('--branch') |
| 255 | + def set_branch(self, branch): |
| 256 | + # FIXME workaround for default value that is not correctly parsed in docopt |
| 257 | + if branch == None: |
| 258 | + branch = 'master' |
| 259 | + |
| 260 | + self.branch = branch |
| 261 | + |
| 262 | + @store_parameter('<repo>') |
| 263 | + def set_target_repo(self, repo): |
| 264 | + self.target_repo = repo |
| 265 | + |
246 | 266 | @store_parameter('<name>')
|
247 | 267 | def set_name(self, name):
|
248 | 268 | self.remote_name = name
|
@@ -272,69 +292,61 @@ def do_remote_add(self):
|
272 | 292 |
|
273 | 293 | @register_action('fork')
|
274 | 294 | def do_fork(self):
|
275 |
| - def clone_repo(): |
276 |
| - try: |
277 |
| - repo_path = os.path.join(self.path, self.repo_name) |
278 |
| - repository = Repo(repo_path) |
279 |
| - except (InvalidGitRepositoryError, NoSuchPathError): |
280 |
| - repo_path = os.path.join(self.path, self.repo_name) |
281 |
| - repository = Repo.init(repo_path) |
282 |
| - return repository, repo_path |
283 |
| - |
284 |
| - def lookup_repo(): |
| 295 | + if not self.repo_slug: |
| 296 | + service = self.get_service(lookup_repository=True) |
285 | 297 | try:
|
286 | 298 | repo_path = self.path
|
287 | 299 | repository = Repo(repo_path)
|
288 | 300 | except (InvalidGitRepositoryError, NoSuchPathError):
|
| 301 | + raise ArgumentError('Path {} is not a git repository'.format(self.path)) |
| 302 | + |
| 303 | + else: |
| 304 | + # git <target> fork <user>/<repo> |
| 305 | + if not self.target_repo: |
| 306 | + if not self.user_name: |
| 307 | + raise ArgumentError('Cannot clone repository, ' |
| 308 | + 'you shall provide either a <user>/<repo> parameter ' |
| 309 | + 'or no parameters to fork current repository!') |
| 310 | + service = self.get_service(None) |
| 311 | + |
| 312 | + # git <target> fork <user>/<repo> <path> |
| 313 | + else: |
| 314 | + repo_path = os.path.join(self.path, self.target_repo) |
289 | 315 | try:
|
290 |
| - repo_path = os.path.join(self.path, self.repo_name) |
291 |
| - repository = Repo(repo_path) |
| 316 | + service = RepositoryService.get_service(Repo(repo_path), self.target) |
292 | 317 | except (InvalidGitRepositoryError, NoSuchPathError):
|
293 |
| - return None, None |
294 |
| - return repository, repo_path |
| 318 | + service = self.get_service(lookup_repository=False) |
| 319 | + # if the repository does not exists at given path, clone upstream into that path |
| 320 | + self.do_clone(service, repo_path) |
295 | 321 |
|
296 |
| - service = self.get_service(lookup_repository=self.repo_slug == None) |
297 |
| - if not self.repo_name and not self.user_name: |
298 |
| - raise ArgumentError('Cannot clone repository, ' |
299 |
| - 'you shall provide the <user>/<repo> parameter ' |
300 |
| - 'or run the command from a git repository!') |
301 |
| - if not self.clone: |
302 |
| - repository, repo_path = lookup_repo() |
303 |
| - if repository == None: |
304 |
| - repository, repo_path = clone_repo() |
305 |
| - self.clone = True |
306 |
| - else: |
307 |
| - repository, repo_path = clone_repo() |
308 |
| - service = RepositoryService.get_service(repository, self.target) |
309 |
| - service.fork(self.user_name, self.repo_name, branch=self.branch, clone=self.clone) |
310 |
| - if self.clone: |
311 |
| - log.info('Successfully cloned repository {} in {}'.format( |
312 |
| - self.repo_slug, |
313 |
| - repo_path) |
314 |
| - ) |
315 |
| - else: |
316 |
| - log.info('Successfully added repository {} as a remote to {}'.format( |
317 |
| - self.repo_slug, |
318 |
| - repo_path) |
319 |
| - ) |
| 322 | + service.run_fork(self.user_name, self.repo_name, branch=self.branch) |
| 323 | + |
| 324 | + if not self.repo_slug or self.target_repo: |
| 325 | + log.info('Successfully forked {} as {} within {}.'.format( |
| 326 | + self.repo_slug, '/'.join([service.username, self.repo_name]), repo_path)) |
320 | 327 |
|
321 | 328 | return 0
|
322 | 329 |
|
323 | 330 | @register_action('clone')
|
324 |
| - def do_clone(self): |
325 |
| - service = self.get_service(lookup_repository=False) |
326 |
| - repo_path = os.path.join(self.path, self.repo_name) |
| 331 | + def do_clone(self, service=None, repo_path=None): |
| 332 | + service = service or self.get_service(lookup_repository=False) |
| 333 | + repo_path = repo_path or os.path.join(self.path, self.target_repo or self.repo_name) |
327 | 334 | if os.path.exists(repo_path):
|
328 | 335 | raise FileExistsError('Cannot clone repository, '
|
329 | 336 | 'a folder named {} already exists!'.format(repo_path))
|
330 |
| - repository = Repo.init(repo_path) |
331 |
| - service = RepositoryService.get_service(repository, self.target) |
332 |
| - service.clone(self.user_name, self.repo_name, self.branch) |
333 |
| - log.info('Successfully cloned `{}` into `{}`!'.format( |
334 |
| - service.format_path(self.repo_slug), |
335 |
| - repo_path) |
336 |
| - ) |
337 |
| - return 0 |
| 337 | + try: |
| 338 | + repository = Repo.init(repo_path) |
| 339 | + service = RepositoryService.get_service(repository, self.target) |
| 340 | + service.clone(self.user_name, self.repo_name, self.branch) |
| 341 | + log.info('Successfully cloned `{}` into `{}`!'.format( |
| 342 | + service.format_path(self.repo_slug), |
| 343 | + repo_path) |
| 344 | + ) |
| 345 | + return 0 |
| 346 | + except Exception as err: |
| 347 | + if os.path.exists(repo_path): |
| 348 | + os.removedirs(repo_path) |
| 349 | + raise err from err |
338 | 350 |
|
339 | 351 | @register_action('create')
|
340 | 352 | def do_create(self):
|
|
0 commit comments