Back to index

plone3  3.1.7
lint.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2003-2005 Kupu Contributors. All rights reserved.
00004 #
00005 # This software is distributed under the terms of the Kupu
00006 # License. See LICENSE.txt for license text. For a list of Kupu
00007 # Contributors see CREDITS.txt.
00008 #
00009 ##############################################################################
00010 # Run jslint over modified javascript files
00011 import os, sys, glob, time
00012 import cPickle
00013 from Queue import Queue
00014 import threading
00015 
00016 COMPILE_COMMAND = "java org.mozilla.javascript.tools.shell.Main %(lint)s --options %(options)s %(file)s"
00017 ERRORS = (IOError, )
00018 if sys.platform=='win32':
00019     COMPILE_COMMAND = "cscript /NoLogo %(lint)s --options %(options)s %(file)s"
00020     ERRORS = (IOError, WindowsError)
00021 
00022 def lint(name):
00023     cmd = COMPILE_COMMAND % dict(lint=LINT, file=name, options=OPTIONS)
00024     stream = os.popen(cmd)
00025     data = stream.read()
00026     rc = stream.close()
00027     return data, rc
00028 
00029 def scriptrelative(relative):
00030     """Find absolute path of file relative to this script"""
00031     base = os.path.dirname(os.path.abspath(__file__))
00032     return os.path.join(base, relative)
00033 
00034 LINT = scriptrelative('jslint.js')
00035 OPTIONS = scriptrelative('jslint.opts')
00036 STATUSFILE = scriptrelative('lint.record')
00037 
00038 def filelist(*patterns, **kw):
00039     for p in patterns:
00040         names = glob.glob(scriptrelative(p))
00041         exclude = kw.get('exclude', [])
00042         for n in names:
00043             if os.path.basename(n) in exclude:
00044                 continue
00045             yield os.path.normpath(n)
00046 
00047 def newfiles(status, *patterns, **kw):
00048     for n in filelist(*patterns, **kw):
00049         mtime = os.stat(n).st_mtime
00050         if n in status and status[n] == mtime:
00051             continue
00052         status[n] = mtime
00053         yield n
00054 
00055 def basetime(marker):
00056     try:
00057         mtime = os.stat(marker).st_mtime
00058     except ERRORS:
00059         mtime = 0.0
00060     return mtime
00061 
00062 def loadstatus(name):
00063     try:
00064         f = open(name, 'rb')
00065     except ERRORS:
00066         return {}
00067     try:
00068         try:
00069             data = cPickle.load(f)
00070         except EOFError:
00071             return {}
00072     finally:
00073         f.close()
00074     return data
00075 
00076 def savestatus(name, status):
00077     f = open(name, 'wb')
00078     cPickle.dump(status, f)
00079     f.close()
00080 
00081 # Thread pool code.
00082 class Pool:
00083     def __init__(self, nThreads):
00084         self.nThreads = nThreads
00085         self.requestQueue = Queue()
00086         self.responseQueue = Queue()
00087         self.exitcode = 0
00088         self.thread_pool = [
00089                 threading.Thread(target=self.run)
00090                 for i in range(nThreads)]
00091         for t in self.thread_pool:
00092             t.start()
00093 
00094     def run(self):
00095         for item in iter(self.requestQueue.get, None):
00096             if not self.exitcode:
00097                 self.responseQueue.put([item, lint(item)])
00098             else:
00099                 # Error state, just ignore this item
00100                 self.responseQueue.put([item, ("skipped %s" % item, 1)])
00101 
00102     def handleResponse(self, item, data, rc):
00103         if rc is not None:
00104             if item in status:
00105                 del status[item]
00106             self.exitcode = max(self.exitcode, rc)
00107         print data
00108 
00109     def process(self, items):
00110         items = list(items)
00111         for item in items:
00112             
00113              self.requestQueue.put(item)
00114         for dummy in items:
00115             item, (data, rc) = self.responseQueue.get()
00116             self.handleResponse(item, data, rc)
00117 
00118     def shutdown(self):
00119         # and then to shut down the threads when you've finished:
00120         for t in self.thread_pool:
00121             self.requestQueue.put(None)
00122         for t in self.thread_pool:
00123              t.join()
00124 
00125 if __name__=='__main__':
00126     status = loadstatus(STATUSFILE)
00127     exitcode = None
00128     threads = Pool(4)
00129     work = newfiles(status, 'common/*.js', 'plone/kupu_plone_layer/*.js',
00130         exclude=['diff_match_patch.js'])
00131     threads.process(work)
00132     threads.shutdown()
00133     savestatus(STATUSFILE, status)
00134     sys.exit(exitcode)