From 963825d10776e24bd1d1d5921093e7189f166660 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 21 Feb 2020 10:31:59 -0500 Subject: [PATCH] Attach annotations to a specific commit sha See git.sr.ht#267 When a new commit is pushed which updates some blobs, but not others, cross-references between them will be broken. We could technically associate this with the top-level tree sha, but this would be wrong for subtrees and it's not obvious how to avoid this. Since one commit is guaranteed to be associated with a toplevel tree, attaching it to the commit solves this without much compromise. --- gitsrht/blueprints/api.py | 25 +++++++++++++++++++++---- gitsrht/blueprints/repo.py | 8 +++++--- gitsrht/templates/blob.html | 3 ++- scss/main.scss | 1 + 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/gitsrht/blueprints/api.py b/gitsrht/blueprints/api.py index d533840..9eea653 100644 --- a/gitsrht/blueprints/api.py +++ b/gitsrht/blueprints/api.py @@ -200,15 +200,32 @@ def repo_tree_GET(username, reponame, ref, path): abort(404) return tree_to_dict(tree) -@data.route("/api/repos//annotate", methods=["PUT"]) -@data.route("/api//repos//annotate", methods=["PUT"]) +# TODO: remove fallback routes +@data.route("/api/repos//annotate", methods=["PUT"], + defaults={"username": None, "commit": "master"}) +@data.route("/api//repos//annotate", methods=["PUT"], + defaults={"commit": "master"}) +@data.route("/api/repos///annotate", methods=["PUT"], + defaults={"username": None}) +@data.route("/api//repos///annotate", methods=["PUT"]) @oauth("repo:write") -def repo_annotate_PUT(username, reponame): +def repo_annotate_PUT(username, reponame, commit): user = get_user(username) repo = get_repo(user, reponame, needs=UserAccess.manage) valid = Validation(request) + with GitRepository(repo.path) as git_repo: + try: + commit = git_repo.revparse_single(commit) + except KeyError: + abort(404) + except ValueError: + abort(404) + if not isinstance(commit, pygit2.Commit): + abort(400) + commit = commit.id.hex + nblobs = 0 for oid, annotations in valid.source.items(): valid.expect(isinstance(oid, str), "blob keys must be strings") @@ -220,7 +237,7 @@ def repo_annotate_PUT(username, reponame): validate_annotation(valid, anno) if not valid.ok: return valid.response - redis.set(f"git.sr.ht:git:annotations:{repo.id}:{oid}", + redis.set(f"git.sr.ht:git:annotations:{repo.id}:{oid}:{commit}", json.dumps(annotations)) # Invalidate rendered markup cache redis.delete(f"git.sr.ht:git:highlight:{oid}") diff --git a/gitsrht/blueprints/repo.py b/gitsrht/blueprints/repo.py index d1fcca4..954f019 100644 --- a/gitsrht/blueprints/repo.py +++ b/gitsrht/blueprints/repo.py @@ -52,9 +52,10 @@ def get_readme(repo, tip, link_prefix=None): return get_formatted_readme("git.sr.ht:git", file_finder, content_getter, link_prefix=link_prefix) -def _highlight_file(repo, ref, name, data, blob_id): +def _highlight_file(repo, ref, name, data, blob_id, commit_id): def get_annos(): - annotations = redis.get(f"git.sr.ht:git:annotations:{repo.id}:{blob_id}") + annotations = redis.get("git.sr.ht:git:annotations:" + + f"{repo.id}:{blob_id}:{commit_id}") if annotations: return json.loads(annotations.decode()) return None @@ -195,6 +196,7 @@ def tree(owner, repo, ref, path): commit, ref, path = lookup_ref(git_repo, ref, path) if isinstance(commit, pygit2.Tag): commit = git_repo.get(commit.target) + orig_commit = commit tree = commit.tree if not tree: @@ -225,7 +227,7 @@ def tree(owner, repo, ref, path): force_source = "view-source" in request.args return render_template("blob.html", view="blob", owner=owner, repo=repo, ref=ref, path=path, entry=entry, - blob=blob, data=data, commit=commit, + blob=blob, data=data, commit=orig_commit, highlight_file=_highlight_file, editorconfig=editorconfig, markdown=markdown, force_source=force_source) diff --git a/gitsrht/templates/blob.html b/gitsrht/templates/blob.html index 9f3c9cb..793afb0 100644 --- a/gitsrht/templates/blob.html +++ b/gitsrht/templates/blob.html @@ -101,7 +101,8 @@ pre, body { id="L{{loop.index}}" >{{loop.index}}{% if not loop.last %} {% endif %}{% endfor %} - {{ highlight_file(repo, ref, entry.name, data, blob.id.hex) }} + {{ highlight_file(repo, ref, entry.name, + data, blob.id.hex, commit.id.hex) }} {% else %}
diff --git a/scss/main.scss b/scss/main.scss index cb76329..36f0679 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -182,6 +182,7 @@ img { color: inherit; background: lighten($primary, 45); border-bottom: 1px dotted $gray-800; + text-decoration: none; &:hover { text-decoration: none; -- 2.38.4