Skip to content

Instantly share code, notes, and snippets.

@olleolleolle
Created March 11, 2010 16:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save olleolleolle/329280 to your computer and use it in GitHub Desktop.
Save olleolleolle/329280 to your computer and use it in GitHub Desktop.
jslint.py: Here is my take on bash scripting: using Python's subprocess module.
#!/usr/bin/env python
import subprocess
import fnmatch
import os
import os.path
from string import Template
from optparse import OptionParser
import webbrowser
import string
import datetime
import xml.sax.saxutils
usage = """
%prog [options]
Requirements:
sudo gem install juicer
juicer install jslint
"""
parser = OptionParser(usage=usage)
parser.add_option("-p", "--path", dest="basepath", default="/Users/olle/eos/web/scripts/",
help="Read JavaScript files from this absolute path, including slash")
parser.add_option("-o", "--out", dest="output_file_path", default="/tmp/jslint_results.html",
help="Filename of output HTML file")
parser.add_option("-v", "--verbose", help="Opens a browser with HTML report when done", action="store_true", dest="verbose", default=True)
parser.add_option("-q", "--quiet", help="No console output", action="store_false", dest="verbose")
(options, args) = parser.parse_args()
files_to_lint = []
for root, dirs, files in os.walk(options.basepath):
if '.svn' in dirs:
dirs.remove('.svn')
if 'mochikit' in dirs:
dirs.remove('mochikit')
if 'img' in dirs:
dirs.remove('img')
filelist = fnmatch.filter(files, '*.js')
for fi in filelist:
if fi.startswith("jquery"): continue;
files_to_lint.append(os.path.join(root, fi))
if not files_to_lint:
parser.print_help()
quit()
htmlTemplate = Template('''<!DOCTYPE html>
<html>
<head>
<title>jslint results</title>
<style>
body, p, td, li, h1,h2,h3,h4,h5,h6 {font-family:"Trebuchet MS", sans-serif;}
.lint-item { padding: 2em 0;}
.focused-item {background: tan;}
.when {color:gray;}
.still-have-errors {background-color:pink;}
.no-errors {background-color:lightgreen;}
</style>
<script src="http://code.jquery.com/jquery-1.4.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
jQuery(function() {
jQuery(".lint-item h2").hover(function() {
jQuery(this).addClass('focused-item');
}, function() {
jQuery(this).removeClass('focused-item');
});
jQuery(".lint-item h2").click(function() {
jQuery(this).parent().find("div").toggle();
});
});
</script>
</head>
<body>
<h1>jslint: collected report</h1>
<p class="when">Generated $today</p>
<p class="how-many $resultClass">Total number of errors: $totalErrors</p>
$blocks
</body>
</html>
'''
)
blockTemplate = Template('''
<div class='lint-item'>
<h2 title="$filename">$shortFilename ($nErrors)</h2>
<div style="display:none;">
<p><a title="Open this file in TextMate" href="txmt://open?url=file://${filename}">$filename</a></p>
<pre>$warnings</pre>
</div>
</div>
''')
totalErrors = 0
blocks = ''
for f in files_to_lint:
p = subprocess.Popen(["juicer verify %s" % f], shell=True, bufsize=16000,
stdin=subprocess.PIPE, stdout=subprocess.PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)
lines = child_stdout.readlines()[2:] # Skipping introductory text
nErrors = (len(lines)) / 2
settings = dict(
warnings=xml.sax.saxutils.escape("".join(lines)),
filename=f,
shortFilename=string.replace(f, options.basepath, ''),
nErrors=nErrors
)
blocks += blockTemplate.substitute(settings)
totalErrors += nErrors
output_file = file(options.output_file_path, 'w')
if totalErrors > 0:
resultClass = 'still-have-errors'
else:
resultClass = 'no-errors'
data = dict(
blocks=blocks,
today=datetime.datetime.today(),
totalErrors=totalErrors,
resultClass=resultClass,
)
output_file.write(htmlTemplate.substitute(data))
output_file.close()
if options.verbose:
webbrowser.open_new_tab("file://%s" % options.output_file_path)
print "Done! Now openening file://%s in a web browser." % options.output_file_path
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment