diff --git a/gunicorn/config.py b/gunicorn/config.py index 2468872c..d777e9a3 100644 --- a/gunicorn/config.py +++ b/gunicorn/config.py @@ -368,6 +368,14 @@ def validate_string(val): return val.strip() +def validate_file_exists(val): + if val is None: + return None + if not os.path.exists(val): + raise ValueError("File %s does not exists." % val) + return val + + def validate_list_string(val): if not val: return [] @@ -379,6 +387,10 @@ def validate_list_string(val): return [validate_string(v) for v in val] +def validate_list_of_existing_files(val): + return [validate_file_exists(v) for v in validate_list_string(val)] + + def validate_string_to_list(val): val = validate_string(val) @@ -857,6 +869,20 @@ class ReloadEngine(Setting): """ +class ReloadExtraFiles(Setting): + name = "reload_extra_files" + action = "append" + section = "Debugging" + cli = ["--reload-extra-file"] + meta = "FILES" + validator = validate_list_of_existing_files + default = [] + desc = """\ + Extends --reload option to also watch and reload on additional files + (e.g., templates, configurations, specifications, etc.). + """ + + class Spew(Setting): name = "spew" section = "Debugging" diff --git a/gunicorn/reloader.py b/gunicorn/reloader.py index e8a00675..4a4dae49 100644 --- a/gunicorn/reloader.py +++ b/gunicorn/reloader.py @@ -81,6 +81,9 @@ if has_inotify: self._dirs = set() self._watcher = Inotify() + for extra_file in extra_files: + self.add_extra_file(extra_file) + def add_extra_file(self, filename): dirname = os.path.dirname(filename) diff --git a/gunicorn/workers/base.py b/gunicorn/workers/base.py index 92df19d4..5781916a 100644 --- a/gunicorn/workers/base.py +++ b/gunicorn/workers/base.py @@ -120,7 +120,8 @@ class Worker(object): sys.exit(0) reloader_cls = reloader_engines[self.cfg.reload_engine] - self.reloader = reloader_cls(callback=changed) + self.reloader = reloader_cls(extra_files=self.cfg.reload_extra_files, + callback=changed) self.reloader.start() self.load_wsgi()