Parse an Azure DevOps repository git url into its parts
(url)
| 44 | |
| 45 | |
| 46 | def _parse_devops_url(url) -> dict: |
| 47 | '''Parse an Azure DevOps repository git url into its parts''' |
| 48 | # examples: |
| 49 | # https://dev.azure.com/colbylwilliams/MyProject/_git/devbox-images |
| 50 | # https://colbylwilliams.visualstudio.com/DefaultCollection/MyProject/_git/devbox-images |
| 51 | # https://colbylwilliams@dev.azure.com/colbylwilliams/MyProject/_git/devbox-images |
| 52 | |
| 53 | if not _is_devops(url): |
| 54 | raise ValueError(f'{url} is not a valid Azure DevOps respository url') |
| 55 | |
| 56 | url = url.lower().replace('git@ssh', 'https://').replace(':v3/', '/') |
| 57 | |
| 58 | if '@dev.azure.com' in url: |
| 59 | url = 'https://dev.azure.com' + url.split('@dev.azure.com')[1] |
| 60 | |
| 61 | if url.endswith('.git'): |
| 62 | url = url[:-4] |
| 63 | |
| 64 | parts = url.split('/') |
| 65 | |
| 66 | index = next((i for i, part in enumerate(parts) if 'dev.azure.com' in part or 'visualstudio.com' in part), -1) |
| 67 | |
| 68 | if index == -1: |
| 69 | raise ValueError(f'{url} is not a valid Azure DevOps respository url') |
| 70 | |
| 71 | if '_git' in parts: |
| 72 | parts.pop(parts.index('_git')) |
| 73 | else: |
| 74 | last = parts[-1] |
| 75 | url = url.replace(f'/{last}', f'/_git/{last}') |
| 76 | |
| 77 | if 'dev.azure.com' in parts[index]: |
| 78 | index += 1 |
| 79 | |
| 80 | if len(parts) < index + 3: |
| 81 | raise ValueError(f'{url} is not a valid Azure DevOps respository url') |
| 82 | |
| 83 | repo = { |
| 84 | 'provider': 'devops', |
| 85 | 'url': url, |
| 86 | 'org': parts[index].replace('.visualstudio.com', '') |
| 87 | } |
| 88 | |
| 89 | if parts[index + 1] == 'defaultcollection': |
| 90 | index += 1 |
| 91 | |
| 92 | repo['project'] = parts[index + 1] |
| 93 | repo['repo'] = parts[index + 2] |
| 94 | |
| 95 | return repo |
| 96 | |
| 97 | |
| 98 | def parse_url(url) -> dict: |
no test coverage detected