aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberto Bertogli <albertito@blitiri.com.ar>2020-05-24 15:20:56 +0200
committerAlberto Bertogli <albertito@blitiri.com.ar>2020-05-24 17:04:24 +0200
commit20b99ee568fd15ca2897f995e9775861ef293544 (patch)
tree4d1ad17d066f2e05a7927245136b78188d32f79e
parentad950208bf19d49e8f825007ba267ca3c43b8390 (diff)
downloadgit-arr-fork-20b99ee568fd15ca2897f995e9775861ef293544.zip
Introduce type annotations
This patch introduces type annotations, which can be checked with mypy. The coverage is not very comprehensive for now, but it is a starting point and will be expanded in later patches.
-rwxr-xr-xgit-arr13
-rw-r--r--git.py40
-rw-r--r--utils.py42
3 files changed, 53 insertions, 42 deletions
diff --git a/git-arr b/git-arr
index 05ac171..b109f23 100755
--- a/git-arr
+++ b/git-arr
@@ -9,8 +9,9 @@ import optparse
import os
import re
import sys
+from typing import Union
-import bottle
+import bottle # type: ignore
import git
import utils
@@ -328,10 +329,10 @@ def is_404(e):
return e.status_code == 404
-def generate(output, only=None):
+def generate(output: str, only=None):
"""Generate static html to the output directory."""
- def write_to(path, func_or_str, args=(), mtime=None):
+ def write_to(path: str, func_or_str, args=(), mtime=None):
path = output + "/" + path
dirname = os.path.dirname(path)
@@ -339,7 +340,7 @@ def generate(output, only=None):
os.makedirs(dirname)
if mtime:
- path_mtime = 0
+ path_mtime: Union[float, int] = 0
if os.path.exists(path):
path_mtime = os.stat(path).st_mtime
@@ -380,8 +381,8 @@ def generate(output, only=None):
print(from_path, "->", to_path)
os.symlink(to_path, from_path)
- def write_tree(r, bn, mtime):
- t = r.tree(bn)
+ def write_tree(r: git.Repo, bn: str, mtime):
+ t: git.Tree = r.tree(bn)
write_to("r/%s/b/%s/t/index.html" % (r.name, bn), tree, (r, bn), mtime)
diff --git a/git.py b/git.py
index 3b2b5b7..846c1a6 100644
--- a/git.py
+++ b/git.py
@@ -14,13 +14,16 @@ import email.utils
import datetime
import urllib.request, urllib.parse, urllib.error
from html import escape
+from typing import Any, Dict, IO, Iterable, List, Optional, Tuple, Union
# Path to the git binary.
GIT_BIN = "git"
-def run_git(repo_path, params, stdin=None, silent_stderr=False, raw=False):
+def run_git(
+ repo_path: str, params, stdin: bytes = None, silent_stderr=False, raw=False
+) -> Union[IO[str], IO[bytes]]:
"""Invokes git with the given parameters.
This function invokes git with the given parameters, and returns a
@@ -44,9 +47,12 @@ def run_git(repo_path, params, stdin=None, silent_stderr=False, raw=False):
stderr=stderr,
)
+ assert p.stdin is not None
p.stdin.write(stdin)
p.stdin.close()
+ assert p.stdout is not None
+
if raw:
return p.stdout
@@ -58,13 +64,13 @@ def run_git(repo_path, params, stdin=None, silent_stderr=False, raw=False):
class GitCommand(object):
"""Convenient way of invoking git."""
- def __init__(self, path, cmd, *args, **kwargs):
+ def __init__(self, path: str, cmd: str, *args, **kwargs):
self._override = True
self._path = path
self._cmd = cmd
- self._args = list(args)
- self._kwargs = {}
- self._stdin_buf = None
+ self._args: List[str] = list(args)
+ self._kwargs: Dict[str, str] = {}
+ self._stdin_buf: Optional[bytes] = None
self._raw = False
self._override = False
for k, v in kwargs:
@@ -77,17 +83,17 @@ class GitCommand(object):
k = k.replace("_", "-")
self._kwargs[k] = v
- def arg(self, a):
+ def arg(self, a: str):
"""Adds an argument."""
self._args.append(a)
- def raw(self, b):
+ def raw(self, b: bool):
"""Request raw rather than utf8-encoded command output."""
self._override = True
self._raw = b
self._override = False
- def stdin(self, s):
+ def stdin(self, s: Union[str, bytes]):
"""Sets the contents we will send in stdin."""
self._override = True
if isinstance(s, str):
@@ -130,14 +136,14 @@ class smstr:
.html -> an HTML-embeddable representation.
"""
- def __init__(self, raw):
+ def __init__(self, raw: str):
if not isinstance(raw, (str, bytes)):
raise TypeError(
"The raw string must be instance of 'str', not %s" % type(raw)
)
self.raw = raw
if isinstance(raw, bytes):
- self.unicode = raw.decode("utf8", errors="backslashreplace")
+ self.unicode: str = raw.decode("utf8", errors="backslashreplace")
else:
self.unicode = raw
self.url = urllib.request.pathname2url(raw)
@@ -177,7 +183,7 @@ class smstr:
return html
-def unquote(s):
+def unquote(s: str):
"""Git can return quoted file names, unquote them. Always return a str."""
if not (s[0] == '"' and s[-1] == '"'):
# Unquoted strings are always safe, no need to mess with them
@@ -204,10 +210,10 @@ def unquote(s):
class Repo:
"""A git repository."""
- def __init__(self, path, name=None, info=None):
+ def __init__(self, path: str, name=None, info=None):
self.path = path
self.name = name
- self.info = info or SimpleNamespace()
+ self.info: Any = info or SimpleNamespace()
def cmd(self, cmd):
"""Returns a GitCommand() on our path."""
@@ -535,11 +541,13 @@ class Diff:
class Tree:
""" A git tree."""
- def __init__(self, repo, ref):
+ def __init__(self, repo: Repo, ref: str):
self.repo = repo
self.ref = ref
- def ls(self, path, recursive=False):
+ def ls(
+ self, path, recursive=False
+ ) -> Iterable[Tuple[str, smstr, Optional[int]]]:
"""Generates (type, name, size) for each file in path."""
cmd = self.repo.cmd("ls-tree")
cmd.long = None
@@ -575,7 +583,7 @@ class Tree:
class Blob:
"""A git blob."""
- def __init__(self, raw_content):
+ def __init__(self, raw_content: bytes):
self.raw_content = raw_content
self._utf8_content = None
diff --git a/utils.py b/utils.py
index 0f25be1..9c2c45a 100644
--- a/utils.py
+++ b/utils.py
@@ -5,16 +5,16 @@ These are mostly used in templates, for presentation purposes.
"""
try:
- import pygments
- from pygments import highlight
- from pygments import lexers
- from pygments.formatters import HtmlFormatter
+ import pygments # type: ignore
+ from pygments import highlight # type: ignore
+ from pygments import lexers # type: ignore
+ from pygments.formatters import HtmlFormatter # type: ignore
except ImportError:
pygments = None
try:
- import markdown
- import markdown.treeprocessors
+ import markdown # type: ignore
+ import markdown.treeprocessors # type: ignore
except ImportError:
markdown = None
@@ -23,14 +23,16 @@ import mimetypes
import string
import os.path
+import git
-def shorten(s, width=60):
+
+def shorten(s: str, width=60):
if len(s) < 60:
return s
return s[:57] + "..."
-def can_colorize(s):
+def can_colorize(s: str):
"""True if we can colorize the string, False otherwise."""
if pygments is None:
return False
@@ -54,7 +56,7 @@ def can_colorize(s):
return True
-def can_markdown(repo, fname):
+def can_markdown(repo: git.Repo, fname: str):
"""True if we can process file through markdown, False otherwise."""
if markdown is None:
return False
@@ -75,14 +77,14 @@ def can_embed_image(repo, fname):
)
-def colorize_diff(s):
+def colorize_diff(s: str) -> str:
lexer = lexers.DiffLexer(encoding="utf-8")
formatter = HtmlFormatter(encoding="utf-8", cssclass="source_code")
return highlight(s, lexer, formatter)
-def colorize_blob(fname, s):
+def colorize_blob(fname, s: str) -> str:
try:
lexer = lexers.guess_lexer_for_filename(fname, s, encoding="utf-8")
except lexers.ClassNotFound:
@@ -107,7 +109,7 @@ def colorize_blob(fname, s):
return highlight(s, lexer, formatter)
-def markdown_blob(s):
+def markdown_blob(s: str) -> str:
extensions = [
"markdown.extensions.fenced_code",
"markdown.extensions.tables",
@@ -116,7 +118,7 @@ def markdown_blob(s):
return markdown.markdown(s, extensions=extensions)
-def embed_image_blob(fname, image_data):
+def embed_image_blob(fname: str, image_data: bytes) -> str:
mimetype = mimetypes.guess_type(fname)[0]
b64img = base64.b64encode(image_data).decode("ascii")
return '<img style="max-width:100%;" src="data:{0};base64,{1}" />'.format(
@@ -124,22 +126,22 @@ def embed_image_blob(fname, image_data):
)
-def is_binary(s):
+def is_binary(b: bytes):
# Git considers a blob binary if NUL in first ~8KB, so do the same.
- return b"\0" in s[:8192]
+ return b"\0" in b[:8192]
-def hexdump(s):
+def hexdump(s: bytes):
graph = string.ascii_letters + string.digits + string.punctuation + " "
- s = s.decode("latin1")
+ b = s.decode("latin1")
offset = 0
- while s:
- t = s[:16]
+ while b:
+ t = b[:16]
hexvals = ["%.2x" % ord(c) for c in t]
text = "".join(c if c in graph else "." for c in t)
yield offset, " ".join(hexvals[:8]), " ".join(hexvals[8:]), text
offset += 16
- s = s[16:]
+ b = b[16:]
if markdown: