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