Commits

Eric Larson  committed acbaff0 Draft

Initial commit

  • Participants

Comments (0)

Files changed (3)

+=============
+ AutoRebuild
+=============
+
+AutoRebuild is a really simple CherryPy plugin that provides a hook
+point that is triggered when certain files change. It is similar to
+the Autoreloader plugin with the primary difference that it does not
+restart the engine and instead calls a function.
+
+
+Usage
+=====
+
+Here is a simple example provided in the code: ::
+
+  import cherrypy
+  from autorebuild import AutoRebuild
+  from subprocess import call
+
+  from myapp import MyApp
+
+  def build_css():
+      call(['make', 'css'])
+
+  # Create our plugin and attach it to the engine object so we can
+  # configure it with the cherrypy.config
+  cherrypy.engine.autorebuild = AutoRebuild(cherrypy.engine)
+  cherrypy.engine.autorebuild.subscribe()
+
+  # Update our config with a glob expression to find some sass css
+  # files and call our build command defined in a make file to rebuild
+  # them
+  cherrypy.config.update({
+          'engine.autorebuild.on': True,
+          'engine.autorebuild.taskmap': {'*.scss': build_css}})
+
+  # Start things up
+  cherrypy.tree.mount(MyApp(), '/')
+  cherrypy.engine.start()
+  cherrypy.engine.block()
+
+Pretty simple.
+
+
+History
+=======
+
+A developer asked me if there was a good way to force CherryPy to
+restart and rebuild some sass_ files when the files changed. Knowing
+that the Autoreloader plugin already existed it seemed trivial to
+implement. The immediate solution was to simply use the sass command
+line watcher script in a foreman procfile, but thinking about it, it
+seemed pretty silly when you could do it in CherryPy relatively easily
+and avoid having to depend on something like foreman all together.
+
+I then realized there were tools like CodeKit_ people were actually
+selling to do this for you and it seemed ridiculous that this isn't
+built in.
+
+
+.. _sass: http://sass-lang.com
+.. _CodeKit: http://incident57.com/codekit/
+
+

File autorebuild.py

+"""
+AutoRebuild
+===========
+
+A plugin that will perform a rebuild when a file changes.
+"""
+import os
+import glob
+
+from cherrypy.process.plugins import Autoreloader
+
+
+class AutoRebuild(Autoreloader):
+
+    taskmap = {}
+
+    def tasks(self):
+        """
+        See if any files have changed for a certain task.
+        """
+        tasks = []
+        for regex, task in self.taskmap.iteritems():
+            changed = []
+            for filename in glob.iglob(regex):
+                oldtime = self.mtimes.get(filename, 0)
+                if oldtime is None:
+                    continue
+
+                try:
+                    mtime = os.stat(filename).st_mtime
+                except OSError:
+                    mtime = None
+
+                self.mtimes[filename] = mtime
+
+                if mtime is None or mtime > oldtime:
+                    changed.append(filename)
+
+            if changed:
+                tasks.append((task, changed))
+        return tasks
+
+    def run(self):
+        for task, changed in self.tasks():
+            self.bus.log('Executing %s. These changed: %s' % (task, changed))
+            task()
+
+
+if __name__ == '__main__':
+    import cherrypy
+    from subprocess import call
+
+    class Root(object):
+        def index(self):
+            return 'Hello World!'
+        index.exposed = True
+
+    def build_css():
+        call(['make', 'css'])
+
+    cherrypy.engine.autorebuild = AutoRebuild(cherrypy.engine)
+    cherrypy.engine.autorebuild.subscribe()
+
+    cherrypy.config.update({
+            'engine.autorebuild.on': True,
+            'engine.autorebuild.taskmap': {'*.less': build_css}})
+
+    cherrypy.tree.mount(Root(), '/')
+    cherrypy.engine.start()
+    cherrypy.engine.block()
+from setuptools import setup
+
+
+setup_params = dict(
+    name='AutoRebuild',
+    author='Eric Larson',
+    author_email='eric@ionrock.org',
+    url='http://bitbucket.org/elarson/autorebuild',
+    version='0.8',
+    install_requires=[
+        'cherrypy',
+    ]
+)
+
+if __name__ == '__main__':
+    setup(**setup_params)