Add a tool to print out the entire codebase (!) as a PDF

(imported from commit 51199eb81735137a66a2e441d0392b142ce197d0)
This commit is contained in:
Keegan McAllister 2012-10-24 23:47:55 -04:00
parent 652c524777
commit 3f9cf64eba
4 changed files with 272 additions and 0 deletions

163
tools/print-all/print-all Executable file
View File

@ -0,0 +1,163 @@
#!/usr/bin/env python
import sh
import os
import re
import sys
from os import path
# Prepare a PDF of the entire codebase, ready for printing.
#
# Depends on:
#
# - Python 'sh' module: http://amoffat.github.com/sh/
# - pygmentize (Debian: python-pygments)
# - A reasonably complete LaTeX install including pdflatex
# - pdfnup (Debian: texlive-extra-utils)
# I'd like to keep these exclude lists small.
#
# We print some things that "obviously" aren't security-revelant --
# but we might be surprised down the line.
#
# I only exclude things that are huge, or completely useless to print
# (binary files, minified third-party JS).
exclude_trees = """
zephyr/static/third
servers/puppet/modules
certs
""".split()
exclude_files = """
zephyr/management/commands/test_messages.txt
tools/usability_testing/humbug_usability_test_data
servers/puppet/files/wiki/static/img/logo.png
tools/jslint/jslint.js
""".split()
extensions = dict(
py = 'python',
rb = 'ruby',
js = 'javascript',
css = 'css',
html = 'html',
sh = 'sh',
tex = 'latex')
os.chdir(path.join(path.dirname(__file__), '../..'))
orig_cwd = os.getcwd()
try:
sh.git('diff-files', '--quiet')
sh.git('diff-index', '--cached', '--quiet', 'HEAD')
except sh.ErrorReturnCode:
sys.stderr.write('Your Git repository is not clean!\n\n')
os.system('git status') # output to terminal
sys.exit(1)
with open('tools/print-all/tex/preamble.tex', 'w') as f:
f.write(r'''
\begin{center}
{\Huge Humbug, Inc. code printout}\\[1cm]
{\Large Generated on \today\\[1cm]
branch \texttt{%s}\\[1cm]
commit \texttt{%s}
}
\end{center}
''' % ('/'.join(sh.git('symbolic-ref', 'HEAD').split('/')[2:]),
sh.git('rev-parse', 'HEAD')))
notfile = []
empty = []
excluded = []
doc = file('tools/print-all/tex/all_code.tex', 'w')
doc.write(r'''
\input{header}
\begin{document}
\input{preamble}
''')
for fil in sh.git('ls-files', _iter=True):
fil = fil.strip()
if (not path.isfile(fil)) or path.islink(fil):
notfile.append(fil)
continue
if os.stat(fil).st_size == 0:
empty.append(fil)
continue
if (fil in exclude_files) or any(fil.startswith(d+'/') for d in exclude_trees):
excluded.append(fil)
continue
filetype = None
try:
filetype = extensions[path.basename(fil).split('.')[1]]
except (KeyError, IndexError):
with open(fil, 'rb') as f:
header = f.readline()
if re.match(r'^#!.*\bpython', header):
filetype = 'python'
elif re.match(r'^#!/.*\b(ba)?sh', header):
filetype = 'sh'
if filetype == 'html' and fil.startswith('templates/'):
filetype = 'html+django'
print 'Scanning', fil
outname = fil.replace('_', '_u_').replace('.', '_d_').replace('/', '_s_')
sh.pygmentize(
'-l', (filetype if filetype else 'text'),
'-f', 'tex',
'-o', path.join('tools/print-all/tex/files', outname+'.tex'),
fil)
doc.write('\\section{%s}\n\\input{files/%s}\n\n' % (fil.replace('_', r'\_'), outname))
doc.write(r'''
\input{epilogue}
\end{document}
''')
doc.close()
with file('tools/print-all/tex/epilogue.tex', 'w') as f:
def print_list(title, xs):
f.write('\\section*{%s}\n\n' % (title,))
for x in xs:
f.write('%s\n\n' % (x.replace('_', r'\_'),))
print_list('Empty files', empty)
print_list('Not regular files', notfile)
print_list('Explicitly excluded', excluded)
print
print 'Rendering PDF...'
os.chdir('tools/print-all/tex')
if not path.exists('utf-8.def'):
# Fix up some TeX installation issue by copying files from where Debian puts them
utf8_dir = lambda p: path.join('/usr/share/doc/texlive-doc/generic/t2/etc/utf-8', p)
sh.cp(utf8_dir('utf-8.def'), '.')
sh.zcat(utf8_dir('utfcyr.def.gz'), _out='utfcyr.def')
sh.zcat(utf8_dir('utflat.def.gz'), _out='utflat.def')
try:
sh.pdflatex('all_code.tex', _in='/dev/null')
except sh.ErrorReturnCode as exn:
print exn.stdout
sys.exit(1)
print 'Converting to 2-up...'
sh.pdfnup('--nup', '2x1', 'all_code.pdf')
os.chdir(orig_cwd)
print
print sh.file('tools/print-all/tex/all_code-nup.pdf')

9
tools/print-all/tex/.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
*.aux
*.log
*.pdf
/all_code.tex
/preamble.tex
/epilogue.tex
/utf*.def

1
tools/print-all/tex/files/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/*.tex

View File

@ -0,0 +1,99 @@
\documentclass[9pt]{extarticle}
\usepackage{fancyvrb}
\usepackage{color}
\usepackage{textcomp}
\usepackage{indentfirst}
\usepackage[hmargin=1cm,vmargin=1cm]{geometry}
\usepackage[utf-8]{inputenc}
\makeatletter
\def\PY@reset{\let\PY@it=\relax \let\PY@bf=\relax%
\let\PY@ul=\relax \let\PY@tc=\relax%
\let\PY@bc=\relax \let\PY@ff=\relax}
\def\PY@tok#1{\csname PY@tok@#1\endcsname}
\def\PY@toks#1+{\ifx\relax#1\empty\else%
\PY@tok{#1}\expandafter\PY@toks\fi}
\def\PY@do#1{\PY@bc{\PY@tc{\PY@ul{%
\PY@it{\PY@bf{\PY@ff{#1}}}}}}}
\def\PY#1#2{\PY@reset\PY@toks#1+\relax+\PY@do{#2}}
\expandafter\def\csname PY@tok@gd\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}}
\expandafter\def\csname PY@tok@gu\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}}
\expandafter\def\csname PY@tok@gt\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.25,0.82}{##1}}}
\expandafter\def\csname PY@tok@gs\endcsname{\let\PY@bf=\textbf}
\expandafter\def\csname PY@tok@gr\endcsname{\def\PY@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}}
\expandafter\def\csname PY@tok@cm\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@vg\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@m\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@mh\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@go\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.50,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@ge\endcsname{\let\PY@it=\textit}
\expandafter\def\csname PY@tok@vc\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@il\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@cs\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@cp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.74,0.48,0.00}{##1}}}
\expandafter\def\csname PY@tok@gi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}}
\expandafter\def\csname PY@tok@gh\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
\expandafter\def\csname PY@tok@ni\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.60,0.60,0.60}{##1}}}
\expandafter\def\csname PY@tok@nl\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.00}{##1}}}
\expandafter\def\csname PY@tok@nn\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
\expandafter\def\csname PY@tok@no\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.53,0.00,0.00}{##1}}}
\expandafter\def\csname PY@tok@na\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.49,0.56,0.16}{##1}}}
\expandafter\def\csname PY@tok@nb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@nc\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
\expandafter\def\csname PY@tok@nd\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.67,0.13,1.00}{##1}}}
\expandafter\def\csname PY@tok@ne\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.82,0.25,0.23}{##1}}}
\expandafter\def\csname PY@tok@nf\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
\expandafter\def\csname PY@tok@si\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.53}{##1}}}
\expandafter\def\csname PY@tok@s2\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@vi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@nt\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@nv\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@s1\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@sh\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@sc\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@sx\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@bp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@c1\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@kc\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@c\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@mf\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@err\endcsname{\def\PY@bc##1{\setlength{\fboxsep}{0pt}\fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{\strut ##1}}}
\expandafter\def\csname PY@tok@kd\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@ss\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@sr\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.53}{##1}}}
\expandafter\def\csname PY@tok@mo\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@kn\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@mi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@gp\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
\expandafter\def\csname PY@tok@o\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@kr\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@s\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@kp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@w\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}}
\expandafter\def\csname PY@tok@kt\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.69,0.00,0.25}{##1}}}
\expandafter\def\csname PY@tok@ow\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.67,0.13,1.00}{##1}}}
\expandafter\def\csname PY@tok@sb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@k\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@se\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.13}{##1}}}
\expandafter\def\csname PY@tok@sd\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\def\PYZbs{\char`\\}
\def\PYZus{\char`\_}
\def\PYZob{\char`\{}
\def\PYZcb{\char`\}}
\def\PYZca{\char`\^}
\def\PYZam{\char`\&}
\def\PYZlt{\char`\<}
\def\PYZgt{\char`\>}
\def\PYZsh{\char`\#}
\def\PYZpc{\char`\%}
\def\PYZdl{\char`\$}
\def\PYZti{\char`\~}
% for compatibility with earlier versions
\def\PYZat{@}
\def\PYZlb{[}
\def\PYZrb{]}
\makeatother