Skip to content

Commit

Permalink
More type annotations (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
tkf committed Sep 17, 2020
1 parent fd462a6 commit 0d3d20b
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 27 deletions.
4 changes: 2 additions & 2 deletions src/vcslinks/api.py
Expand Up @@ -88,7 +88,7 @@ def root(*, path: Pathish = ".", **kwargs) -> str:
return analyze(path, **kwargs).rooturl


def pull_request(path: Pathish = ".", **kwargs) -> str:
def pull_request(path: Pathish = ".", **kwargs) -> Optional[str]:
"""
Get a URL to the web page for submitting a PR.
Expand Down Expand Up @@ -266,7 +266,7 @@ def tree(
revision: Optional[str] = None,
permalink: bool = False,
**kwargs,
):
) -> str:
"""
Get a URL to tree page.
Expand Down
43 changes: 23 additions & 20 deletions src/vcslinks/git.py
@@ -1,35 +1,38 @@
import subprocess
from pathlib import Path
from typing import List, Optional
from subprocess import CompletedProcess
from typing import TYPE_CHECKING, List, Optional, Sequence

from .base import ApplicationError, BaseRepoAnalyzer, Pathish
from .weburl import WebURL

if TYPE_CHECKING:
from typing import Final


class NoRemoteError(ApplicationError):
def __init__(self, branch: str):
self.branch = branch
self.branch: "Final[str]" = branch

def __str__(self):
def __str__(self) -> str:
return f"Branch `{self.branch}` does not have remote."


class GitRepoAnalyzer(BaseRepoAnalyzer):
cwd: Path
root: Path

@classmethod
def from_path(cls, path: Pathish) -> "GitRepoAnalyzer":
cwd = Path(path)
if not cwd.is_dir():
cwd = cwd.parent
return cls(cwd=cwd)

def __init__(self, cwd):
self.cwd = Path(cwd)
self.root = Path(self.git("rev-parse", "--show-toplevel").stdout.strip())
def __init__(self, cwd: Pathish):
self.cwd: "Final[Path]" = Path(cwd)
self.root: "Final[Path]" = Path(
self.git("rev-parse", "--show-toplevel").stdout.strip()
)

def run(self, *args, **options):
def run(self, *args: str, **options) -> CompletedProcess:
kwargs = dict(
cwd=str(self.cwd),
check=True,
Expand All @@ -40,9 +43,9 @@ def run(self, *args, **options):
universal_newlines=True,
)
kwargs.update(options)
return subprocess.run(args, **kwargs)
return subprocess.run(args, **kwargs) # type: ignore

def git(self, *args, **options):
def git(self, *args: str, **options) -> CompletedProcess:
return self.run("git", *args, **options)

def git_config(self, config: str) -> str:
Expand All @@ -54,11 +57,11 @@ def try_git_config(self, config: str) -> Optional[str]:
except subprocess.CalledProcessError:
return None

def resolve_revision(self, revision):
def resolve_revision(self, revision: str) -> str:
return self.git("rev-parse", "--verify", revision).stdout.strip()

@staticmethod
def choose_url(url_list):
def choose_url(url_list: Sequence[str]) -> str:
for host in ["gitlab", "github", "bitbucket"]:
for url in url_list:
if host in url:
Expand All @@ -81,20 +84,20 @@ def remote_all_urls(self, branch: str = "master") -> List[str]:
except subprocess.CalledProcessError:
raise NoRemoteError(branch)

def remote_url(self, **kwargs):
return self.choose_url(self.remote_all_urls(**kwargs))
def remote_url(self, branch: str = "master") -> str:
return self.choose_url(self.remote_all_urls(branch))

def remote_branch(self, branch):
def remote_branch(self, branch: str) -> str:
ref = self.try_git_config(f"branch.{branch}.merge")
if not ref:
return branch # assuming `pushRemote`
assert ref.startswith("refs/heads/")
return ref[len("refs/heads/") :]

def current_branch(self):
def current_branch(self) -> str:
return self.git("rev-parse", "--abbrev-ref", "HEAD").stdout.rstrip()

def need_pull_request(self, branch):
def need_pull_request(self, branch: str) -> bool:
return not (branch == "master" or self.remote_of_branch(branch) == "origin")

def relpath(self, path: Pathish) -> Path:
Expand Down Expand Up @@ -126,7 +129,7 @@ def weburl(self) -> WebURL:
return WebURL(self)


def is_supported_url(url):
def is_supported_url(url: str) -> bool:
# TODO: improve!
for host in ["gitlab", "github", "bitbucket"]:
if host in url:
Expand Down
11 changes: 6 additions & 5 deletions src/vcslinks/weburl.py
Expand Up @@ -17,7 +17,7 @@ def __str__(self):
return f"Unsupported URL: {self.url}"


def rooturl(url):
def rooturl(url: str) -> str:
"""
Turn Git `url` to something web browsers recognize.
Expand All @@ -41,7 +41,7 @@ def rooturl(url):
return _specialurl(_rooturl(url))


def _rooturl(url):
def _rooturl(url: str) -> str:
match = re.match(r"^https?://(.*?)(.git)?$", url)
if match:
return f"https://{match.group(1)}"
Expand All @@ -59,7 +59,7 @@ def _rooturl(url):
return f"https://{host}/{path}"


def _specialurl(url):
def _specialurl(url: str) -> str:
host, path = url.split("://", 1)[1].split("/", 1)
if "gitlab" in host and path.endswith(".wiki"):
return f"https://{host}/{path[:-len('.wiki')]}/wikis"
Expand Down Expand Up @@ -111,7 +111,7 @@ def is_github(self):
def is_gitlab_wiki(self):
return re.search(r"//gitlab\.com/[^/]+/[^/]+/wikis", self.rooturl)

def pull_request(self):
def pull_request(self) -> Optional[str]:
"""
Get a URL to the web page for submitting a PR.
Expand Down Expand Up @@ -142,6 +142,7 @@ def pull_request(self):
elif self.is_bitbucket():
# https://bitbucket.org/{user}/{repo}/pull-requests/new?source={branch}
return self.rooturl + "/pull-requests/new?source=" + branch
return None

def commit(self, revision: str) -> str:
"""
Expand Down Expand Up @@ -294,7 +295,7 @@ def tree(
directory: Optional[Pathish] = None,
revision: Optional[str] = None,
permalink: bool = False,
):
) -> str:
"""
Get a URL to tree page.
"""
Expand Down

0 comments on commit 0d3d20b

Please sign in to comment.