Some more work on pecan serve --reload.
Now the app and config directories are monitored (instead of cwd()).
This commit is contained in:
@@ -38,9 +38,12 @@ class ServeCommand(BaseCommand):
|
||||
stdout=sys.stdout, stderr=sys.stderr
|
||||
)
|
||||
|
||||
def watch_and_spawn(self):
|
||||
def watch_and_spawn(self, conf):
|
||||
from watchdog.observers import Observer
|
||||
from watchdog.events import FileSystemEventHandler
|
||||
from watchdog.events import (
|
||||
FileSystemEventHandler, FileSystemMovedEvent, FileModifiedEvent,
|
||||
DirModifiedEvent
|
||||
)
|
||||
|
||||
print 'Monitoring for changes...'
|
||||
self.create_subprocess()
|
||||
@@ -48,24 +51,31 @@ class ServeCommand(BaseCommand):
|
||||
parent = self
|
||||
|
||||
class AggressiveEventHandler(FileSystemEventHandler):
|
||||
def should_reload(self, path):
|
||||
extension = os.path.splitext(path)[1]
|
||||
if extension in (
|
||||
'.py', '.pyc', '.html', '.mak',
|
||||
'.mako', '.xml'
|
||||
def should_reload(self, event):
|
||||
for t in (
|
||||
FileSystemMovedEvent, FileModifiedEvent, DirModifiedEvent
|
||||
):
|
||||
return True
|
||||
if isinstance(event, t):
|
||||
return True
|
||||
return False
|
||||
|
||||
def on_modified(self, event):
|
||||
if self.should_reload(getattr(event, 'src_path', '')):
|
||||
if self.should_reload(event):
|
||||
parent.server_process.kill()
|
||||
parent.create_subprocess()
|
||||
|
||||
# Determine a list of file paths to monitor
|
||||
paths = self.paths_to_monitor(conf)
|
||||
|
||||
event_handler = AggressiveEventHandler()
|
||||
observer = Observer()
|
||||
observer.schedule(event_handler, path=os.getcwd(), recursive=True)
|
||||
observer.start()
|
||||
for path, recurse in paths:
|
||||
observer = Observer()
|
||||
observer.schedule(
|
||||
event_handler,
|
||||
path=path,
|
||||
recursive=recurse
|
||||
)
|
||||
observer.start()
|
||||
|
||||
try:
|
||||
while True:
|
||||
@@ -73,6 +83,22 @@ class ServeCommand(BaseCommand):
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
def paths_to_monitor(self, conf):
|
||||
paths = []
|
||||
|
||||
for package_name in getattr(conf.app, 'modules', []):
|
||||
module = __import__(package_name, fromlist=['app'])
|
||||
if hasattr(module, 'app') and hasattr(module.app, 'setup_app'):
|
||||
paths.append((
|
||||
os.path.dirname(module.__file__),
|
||||
True
|
||||
))
|
||||
break
|
||||
|
||||
paths.append((os.path.dirname(conf.__file__), False))
|
||||
return paths
|
||||
|
||||
|
||||
def _serve(self, app, conf):
|
||||
from wsgiref.simple_server import make_server
|
||||
|
||||
@@ -100,7 +126,7 @@ class ServeCommand(BaseCommand):
|
||||
|
||||
if self.args.reload:
|
||||
try:
|
||||
self.watch_and_spawn()
|
||||
self.watch_and_spawn(conf)
|
||||
except ImportError:
|
||||
print('The `--reload` option requires `watchdog` to be '
|
||||
'installed.')
|
||||
|
||||
@@ -161,7 +161,6 @@ def conf_from_dict(conf_dict):
|
||||
|
||||
:param conf_dict: The configuration dictionary.
|
||||
'''
|
||||
|
||||
conf = Config(filename=conf_dict.get('__file__', ''))
|
||||
|
||||
for k, v in conf_dict.iteritems():
|
||||
@@ -195,7 +194,10 @@ def set_config(config, overwrite=False):
|
||||
_runtime_conf.empty()
|
||||
|
||||
if isinstance(config, basestring):
|
||||
_runtime_conf.update(conf_from_file(config))
|
||||
config = conf_from_file(config)
|
||||
_runtime_conf.update(config)
|
||||
if config.__file__:
|
||||
_runtime_conf.__file__ = config.__file__
|
||||
elif isinstance(config, dict):
|
||||
_runtime_conf.update(conf_from_dict(config))
|
||||
else:
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from configuration import _runtime_conf, set_config
|
||||
from templating import RendererFactory
|
||||
from routing import lookup_controller, NonCanonicalPath
|
||||
from util import _cfg, encode_if_needed
|
||||
@@ -141,6 +140,7 @@ def load_app(config):
|
||||
which represents a (relative) configuration filename.
|
||||
:returns a pecan.Pecan object
|
||||
'''
|
||||
from configuration import _runtime_conf, set_config
|
||||
set_config(config, overwrite=True)
|
||||
|
||||
for package_name in getattr(_runtime_conf.app, 'modules', []):
|
||||
|
||||
Reference in New Issue
Block a user