Files
@ e54ddaa52fee
Branch filter:
Location: kallithea/scripts/docs-headings.py - annotation
e54ddaa52fee
2.6 KiB
text/x-python
hooks: parse incoming git refs correctly
Hooks receive a line of the following format on standard input:
<old-value> SP <new-value> SP <ref-name> LF
where <old-value> is the old object name stored in the ref,
<new-value> is the new object name to be stored in the ref
and <ref-name> is the full name of the ref.
This means, we have to strip at least the LF in order to have a
correct version of the ref name after the split. Also, when
parsing the ref name itself, use all components but first instead
of just second, as a ref name may have slashes in it.
Previously, failure to parse ref name correctly would lead to the
following behaviour. A newly created repository with no commits pushed
has HEAD set to refs/heads/master by default, even though there's no
such ref in the repository yet. Upon first push, Kallithea rewrites
this symbolic reference with a reference to a real branch.
However, due to a bug in ref name parsing, if a ref name had a slash,
Kallithea would update HEAD to an invalid reference:
git push origin feature/branch
would rewrite HEAD to refs/heads/feature. All future attempts to work
with this repository would fail because dulwich would complain it can't
read HEAD as it is a directory.
Hooks receive a line of the following format on standard input:
<old-value> SP <new-value> SP <ref-name> LF
where <old-value> is the old object name stored in the ref,
<new-value> is the new object name to be stored in the ref
and <ref-name> is the full name of the ref.
This means, we have to strip at least the LF in order to have a
correct version of the ref name after the split. Also, when
parsing the ref name itself, use all components but first instead
of just second, as a ref name may have slashes in it.
Previously, failure to parse ref name correctly would lead to the
following behaviour. A newly created repository with no commits pushed
has HEAD set to refs/heads/master by default, even though there's no
such ref in the repository yet. Upon first push, Kallithea rewrites
this symbolic reference with a reference to a real branch.
However, due to a bug in ref name parsing, if a ref name had a slash,
Kallithea would update HEAD to an invalid reference:
git push origin feature/branch
would rewrite HEAD to refs/heads/feature. All future attempts to work
with this repository would fail because dulwich would complain it can't
read HEAD as it is a directory.
f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 ed2fb6e84a02 ed2fb6e84a02 ed2fb6e84a02 ed2fb6e84a02 ed2fb6e84a02 ed2fb6e84a02 ed2fb6e84a02 ed2fb6e84a02 ed2fb6e84a02 ed2fb6e84a02 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 ed2fb6e84a02 ed2fb6e84a02 ed2fb6e84a02 ed2fb6e84a02 ed2fb6e84a02 ed2fb6e84a02 ed2fb6e84a02 ed2fb6e84a02 ed2fb6e84a02 ed2fb6e84a02 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 f38b50f8a6a6 | #!/usr/bin/env python2
"""
Consistent formatting of rst section titles
"""
import re
import subprocess
spaces = [
(0, 1), # we assume this is a over-and-underlined header
(2, 1),
(1, 1),
(1, 0),
(1, 0),
]
# http://sphinx-doc.org/rest.html :
# for the Python documentation, this convention is used which you may follow:
# # with overline, for parts
# * with overline, for chapters
# =, for sections
# -, for subsections
# ^, for subsubsections
# ", for paragraphs
pystyles = ['#', '*', '=', '-', '^', '"']
# match on a header line underlined with one of the valid characters
headermatch = re.compile(r'''\n*(.+)\n([][!"#$%&'()*+,./:;<=>?@\\^_`{|}~-])\2{2,}\n+''', flags=re.MULTILINE)
def main():
for fn in subprocess.check_output(['hg', 'loc', 'set:**.rst+kallithea/i18n/how_to']).splitlines():
print 'processing %s:' % fn
s = file(fn).read()
# find levels and their styles
lastpos = 0
styles = []
for markup in headermatch.findall(s):
style = markup[1]
if style in styles:
stylepos = styles.index(style)
if stylepos > lastpos + 1:
print 'bad style %r with level %s - was at %s' % (style, stylepos, lastpos)
else:
stylepos = len(styles)
if stylepos > lastpos + 1:
print 'bad new style %r - expected %r' % (style, styles[lastpos + 1])
else:
styles.append(style)
lastpos = stylepos
# remove superfluous spacing (may however be restored by header spacing)
s = re.sub(r'''(\n\n)\n*''', r'\1', s, flags=re.MULTILINE)
if styles:
newstyles = pystyles[pystyles.index(styles[0]):]
def subf(m):
title, style = m.groups()
level = styles.index(style)
before, after = spaces[level]
newstyle = newstyles[level]
return '\n' * (before + 1) + title + '\n' + newstyle * len(title) + '\n' * (after + 1)
s = headermatch.sub(subf, s)
# remove superfluous spacing when headers are adjacent
s = re.sub(r'''(\n.+\n([][!"#$%&'()*+,./:;<=>?@\\^_`{|}~-])\2{2,}\n\n\n)\n*''', r'\1', s, flags=re.MULTILINE)
# fix trailing space and spacing before link sections
s = s.strip() + '\n'
s = re.sub(r'''\n+((?:\.\. _[^\n]*\n)+)$''', r'\n\n\n\1', s)
file(fn, 'w').write(s)
print subprocess.check_output(['hg', 'diff', fn])
print
if __name__ == '__main__':
main()
|