grim/hgwebplus

e6b801778490
Parents 0f32d55b41fb
Children b5d44784e27b
Add doc comments for all of the functions in the extension
--- a/src/hgwebplus.py Fri Apr 10 18:49:59 2020 -0500
+++ b/src/hgwebplus.py Fri Apr 10 18:50:13 2020 -0500
@@ -39,10 +39,23 @@
@templatefilter(b'md5', intype=bytes)
def md5(text):
+ """ md5 is a template filter that will return an MD5 hash for whatever text
+ was given to it. This is typically used to generate gravatar URLs.
+ """
return hashlib_md5(text).hexdigest().encode('ascii')
def _diffstattmplgen(orig, context, ctx, statgen, parity):
+ """ This is a reimplementation of hgweb.webutil._diffstattmplgen. It adds
+ the number lines add and removed as well as if the file is binary or
+ not.
+
+ This allows you to output something like the following instead of just
+ having percentages.
+
+ file1.txt +10 -2
+ file2.txt +20 -0
+ """
stats, maxname, maxtotal, addtotal, removetotal, binary = next(statgen)
files = ctx.files()
@@ -73,12 +86,23 @@
yield context.process(template, data)
-# right now we just capture the starting line numbers as that's all we need
+# This regular expression captures the start line numbers from the hunk token
+# for a diff.
RE_DIFF = re.compile(r'^@@ -(\d+),\d+ \+(\d+),\d+ @@')
def _prettyprintdifflines(context, lines, blockno, lineidprefix, filea, reva,
fileb, revb):
+ """ This function is an updated version of
+ hgweb.webutil._prettyprintdifflines. It maintains backwards
+ compatibility but adds a lot of new features. This is not directly
+ wrapped, but is instead called from _diffsgen below, which is wrapped.
+
+ This version provides additional details about each file. The filenames
+ are in filea, and fileb; The line number that's being displayed for both
+ filea and fileb are in linea and lineb. And finally the revision of
+ each file is available in reva and revb.
+ """
linea = 0
lineb = 0
@@ -162,6 +186,14 @@
linerange,
lineidprefix,
):
+ """ this is a updated version of hgweb.webutil._diffsgen. It maintains
+ backwards compatibility but adds some additional values to the template
+ context. They are change type, filea, fileb, reva, revb.
+
+ change type is one of modified, added, removed, or renamed. filea and
+ fileb are the respective file names. Likewise, reva and revb are the
+ respective revisions.
+ """
if files:
m = match.exact(files)
else:
@@ -218,28 +250,40 @@
yield data
+def readme(context, mapping):
+ """ readme is a template keyword that will attempt to render a readme file
+ that is available in the repository. It currently supports github
+ flavored markdown and plain text.
+ """
+
+ ctx = context.resource(mapping, b'ctx')
+
+ # we iterate the files instead of a fileset, because we want to
+ # deterministically render readmes in the same order if there are more
+ # than one in a repository. With the fileset, we'd have to run through
+ # the generator and call .lower on each item again, and then we'd lose
+ # the ability to fallback if the prioritized one failed to render.
+ for filename in ctx:
+ lower = filename.lower()
+ if lower == b'readme.md':
+ raw_utf8 = ctx[filename].data().decode('utf-8')
+ return cmarkgfm.markdown_to_html(raw_utf8).encode('utf-8')
+
+ if lower in [b'readme.txt', b'readme', b'readme.md']:
+ return ctx[filename].data().replace(b'\n', b'<br/>\n')
+
+
def repo_custom_templater(orig, self, req):
+ """ this function is a wrapper of hgweb_mod.requestcontext.templater. This
+ is done to be able to add custom keywords into hgweb. This is not an
+ ideal solution, and in fact feels very hacky. However, at the time of
+ this writing, it appears to be the only way to do this.
+ """
templater = orig(self, req)
templatekeyword = registrar.templatekeyword(templater._proc._defaults)
- @templatekeyword(b'readme', requires={b'ctx', b'repo'})
- def readme(context, mapping):
- ctx = context.resource(mapping, b'ctx')
-
- # we iterate the files instead of a fileset, because we want to
- # deterministically render readmes in the same order if there are more
- # than one in a repository. With the fileset, we'd have to run through
- # the generator and call .lower on each item again, and then we'd lose
- # the ability to fallback if the prioritized one failed to render.
- for filename in ctx:
- lower = filename.lower()
- if lower == b'readme.md':
- raw_utf8 = ctx[filename].data().decode('utf-8')
- return cmarkgfm.markdown_to_html(raw_utf8).encode('utf-8')
-
- if lower in [b'readme.txt', b'readme', b'readme.md']:
- return ctx[filename].data().replace(b'\n', b'<br/>\n')
+ templatekeyword(b'readme', requires={b'ctx', b'repo'})(readme)
return templater