[Downloader] Parse tree URLs when cloning repos (#2119)

* [Downloader] Parse tree URLs when cloning repos

Signed-off-by: Toby <tobyharradine@gmail.com>

* Only match GitHub and GitLab URLs

Signed-off-by: Toby Harradine <tobyharradine@gmail.com>
This commit is contained in:
Toby Harradine 2018-09-12 10:03:15 +10:00 committed by GitHub
parent 8096cd803e
commit 54baf687ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 3 deletions

View File

@ -2,11 +2,12 @@ import asyncio
import functools import functools
import os import os
import pkgutil import pkgutil
import re
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
from pathlib import Path from pathlib import Path
from subprocess import run as sp_run, PIPE from subprocess import run as sp_run, PIPE
from sys import executable from sys import executable
from typing import Tuple, MutableMapping, Union from typing import Tuple, MutableMapping, Union, Optional
from redbot.core import data_manager, commands from redbot.core import data_manager, commands
from redbot.core.utils import safe_delete from redbot.core.utils import safe_delete
@ -489,8 +490,11 @@ class Repo(RepoJSONMixin):
class RepoManager: class RepoManager:
def __init__(self):
GITHUB_OR_GITLAB_RE = re.compile("https?://git(?:hub)|(?:lab)\.com/")
TREE_URL_RE = re.compile(r"(?P<tree>/tree)/(?P<branch>\S+)$")
def __init__(self):
self._repos = {} self._repos = {}
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
@ -510,7 +514,7 @@ class RepoManager:
raise InvalidRepoName("Not a valid Python variable name.") raise InvalidRepoName("Not a valid Python variable name.")
return name.lower() return name.lower()
async def add_repo(self, url: str, name: str, branch: str = "master") -> Repo: async def add_repo(self, url: str, name: str, branch: Optional[str] = None) -> Repo:
"""Add and clone a git repository. """Add and clone a git repository.
Parameters Parameters
@ -533,6 +537,8 @@ class RepoManager:
"That repo name you provided already exists. Please choose another." "That repo name you provided already exists. Please choose another."
) )
url, branch = self._parse_url(url, branch)
# noinspection PyTypeChecker # noinspection PyTypeChecker
r = Repo(url=url, name=name, branch=branch, folder_path=self.repos_folder / name) r = Repo(url=url, name=name, branch=branch, folder_path=self.repos_folder / name)
await r.clone() await r.clone()
@ -630,3 +636,12 @@ class RepoManager:
if set: if set:
self._repos = ret self._repos = ret
return ret return ret
def _parse_url(self, url: str, branch: Optional[str]) -> Tuple[str, Optional[str]]:
if self.GITHUB_OR_GITLAB_RE.match(url):
tree_url_match = self.TREE_URL_RE.search(url)
if tree_url_match:
url = url[: tree_url_match.start("tree")]
if branch is None:
branch = tree_url_match["branch"]
return url, branch

View File

@ -94,3 +94,27 @@ async def test_existing_repo(repo_manager):
await repo_manager.add_repo("http://test.com", "test") await repo_manager.add_repo("http://test.com", "test")
repo_manager.does_repo_exist.assert_called_once_with("test") repo_manager.does_repo_exist.assert_called_once_with("test")
def test_tree_url_parse(repo_manager):
cases = [
{
"input": ("https://github.com/Tobotimus/Tobo-Cogs", None),
"expected": ("https://github.com/Tobotimus/Tobo-Cogs", None),
},
{
"input": ("https://github.com/Tobotimus/Tobo-Cogs", "V3"),
"expected": ("https://github.com/Tobotimus/Tobo-Cogs", "V3"),
},
{
"input": ("https://github.com/Tobotimus/Tobo-Cogs/tree/V3", None),
"expected": ("https://github.com/Tobotimus/Tobo-Cogs", "V3"),
},
{
"input": ("https://github.com/Tobotimus/Tobo-Cogs/tree/V3", "V4"),
"expected": ("https://github.com/Tobotimus/Tobo-Cogs", "V4"),
},
]
for test_case in cases:
assert test_case["expected"] == repo_manager._parse_url(*test_case["input"])