From 54b4ffb68ef667443ed73578781be66a17d72b1d Mon Sep 17 00:00:00 2001 From: Jorge Niedbalski Date: Mon, 17 Jun 2013 16:44:02 -0300 Subject: [PATCH 1/4] try to use cwd() + gunicorn.conf.py as default config if no file is specified . see #52 --- gunicorn/app/base.py | 17 +++++++++-------- gunicorn/config.py | 11 ++++++++--- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/gunicorn/app/base.py b/gunicorn/app/base.py index 4a708de9..88e49000 100644 --- a/gunicorn/app/base.py +++ b/gunicorn/app/base.py @@ -52,6 +52,15 @@ class Application(object): for k, v in cfg.items(): self.cfg.set(k.lower(), v) + # Lastly, update the configuration with any command line + # settings. + for k, v in args.__dict__.items(): + if v is None: + continue + if k == "args": + continue + self.cfg.set(k.lower(), v) + # Load up the config file if its found. if args.config: if not os.path.exists(args.config): @@ -81,14 +90,6 @@ class Application(object): sys.stderr.write("Invalid value for %s: %s\n\n" % (k, v)) raise - # Lastly, update the configuration with any command line - # settings. - for k, v in args.__dict__.items(): - if v is None: - continue - if k == "args": - continue - self.cfg.set(k.lower(), v) def init(self, parser, opts, args): raise NotImplementedError diff --git a/gunicorn/config.py b/gunicorn/config.py index 1ce7e46b..4c481021 100644 --- a/gunicorn/config.py +++ b/gunicorn/config.py @@ -199,7 +199,7 @@ class Setting(object): "dest": self.name, "action": self.action or "store", "type": self.type or str, - "default": None, + "default": self.default or None, "help": help_txt } @@ -367,6 +367,12 @@ def validate_post_request(val): else: raise TypeError("Value must have an arity of: 4") +def get_default_config_file(): + config_path = os.path.join(os.path.abspath(os.getcwd()), 'gunicorn.conf.py') + if os.path.exists(config_path): + return config_path + return None + class ConfigFile(Setting): name = "config" @@ -374,7 +380,7 @@ class ConfigFile(Setting): cli = ["-c", "--config"] meta = "FILE" validator = validate_string - default = None + default = get_default_config_file() desc = """\ The path to a Gunicorn config file. @@ -382,7 +388,6 @@ class ConfigFile(Setting): application specific configuration. """ - class Bind(Setting): name = "bind" action = "append" From cf6e765323c427e6ad751dea137e6c6fe091e4be Mon Sep 17 00:00:00 2001 From: Jorge Niedbalski Date: Fri, 21 Jun 2013 15:30:31 -0300 Subject: [PATCH 2/4] [gunicorn] added ```gunicorn.conf.py``` as default in case of no -c is specified --- docs/source/settings.rst | 3 +- gunicorn/app/base.py | 70 ++++++++++++++++++++++------------------ gunicorn/config.py | 4 +-- 3 files changed, 43 insertions(+), 34 deletions(-) diff --git a/docs/source/settings.rst b/docs/source/settings.rst index 66dfebd6..c39750bc 100644 --- a/docs/source/settings.rst +++ b/docs/source/settings.rst @@ -14,7 +14,8 @@ config ~~~~~~ * ``-c FILE, --config FILE`` -* ``None`` +* ``gunicorn.conf.py`` if the file exists on the current directory otherwise + ``None`` is used. The path to a Gunicorn config file. diff --git a/gunicorn/app/base.py b/gunicorn/app/base.py index 88e49000..66778170 100644 --- a/gunicorn/app/base.py +++ b/gunicorn/app/base.py @@ -9,7 +9,7 @@ import traceback from gunicorn import util from gunicorn.arbiter import Arbiter -from gunicorn.config import Config +from gunicorn.config import Config, get_default_config_file from gunicorn import debug from gunicorn.six import execfile_ @@ -36,6 +36,37 @@ class Application(object): sys.stderr.flush() sys.exit(1) + def load_config_from_file(self, filename): + + if not os.path.exists(filename): + raise RuntimeError("%r doesn't exist" % filename) + + cfg = { + "__builtins__": __builtins__, + "__name__": "__config__", + "__file__": filename, + "__doc__": None, + "__package__": None + } + try: + execfile_(filename, cfg, cfg) + except Exception: + print("Failed to read config file: %s" % filename) + traceback.print_exc() + sys.exit(1) + + for k, v in cfg.items(): + # Ignore unknown names + if k not in self.cfg.settings: + continue + try: + self.cfg.set(k.lower(), v) + except: + sys.stderr.write("Invalid value for %s: %s\n\n" % (k, v)) + raise + + return cfg + def load_config(self): # init configuration self.cfg = Config(self.usage, prog=self.prog) @@ -52,6 +83,13 @@ class Application(object): for k, v in cfg.items(): self.cfg.set(k.lower(), v) + default_config = get_default_config_file() + + if args.config: + self.load_config_from_file(args.config) + elif default_config is not None: + self.load_config_from_file(default_config) + # Lastly, update the configuration with any command line # settings. for k, v in args.__dict__.items(): @@ -61,36 +99,6 @@ class Application(object): continue self.cfg.set(k.lower(), v) - # Load up the config file if its found. - if args.config: - if not os.path.exists(args.config): - raise RuntimeError("%r doesn't exist" % args.config) - - cfg = { - "__builtins__": __builtins__, - "__name__": "__config__", - "__file__": args.config, - "__doc__": None, - "__package__": None - } - try: - execfile_(args.config, cfg, cfg) - except Exception: - print("Failed to read config file: %s" % args.config) - traceback.print_exc() - sys.exit(1) - - for k, v in cfg.items(): - # Ignore unknown names - if k not in self.cfg.settings: - continue - try: - self.cfg.set(k.lower(), v) - except: - sys.stderr.write("Invalid value for %s: %s\n\n" % (k, v)) - raise - - def init(self, parser, opts, args): raise NotImplementedError diff --git a/gunicorn/config.py b/gunicorn/config.py index 4c481021..f6c284e8 100644 --- a/gunicorn/config.py +++ b/gunicorn/config.py @@ -199,7 +199,7 @@ class Setting(object): "dest": self.name, "action": self.action or "store", "type": self.type or str, - "default": self.default or None, + "default": None, "help": help_txt } @@ -380,7 +380,7 @@ class ConfigFile(Setting): cli = ["-c", "--config"] meta = "FILE" validator = validate_string - default = get_default_config_file() + default = None desc = """\ The path to a Gunicorn config file. From c218792fa457335eb9d0a825148ca2b3aaf1e22a Mon Sep 17 00:00:00 2001 From: Jorge Niedbalski R Date: Sat, 22 Jun 2013 06:48:01 -0700 Subject: [PATCH 3/4] prevent call get_default_config_file if args.config exists --- gunicorn/app/base.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gunicorn/app/base.py b/gunicorn/app/base.py index 66778170..c2ced986 100644 --- a/gunicorn/app/base.py +++ b/gunicorn/app/base.py @@ -83,12 +83,12 @@ class Application(object): for k, v in cfg.items(): self.cfg.set(k.lower(), v) - default_config = get_default_config_file() - if args.config: self.load_config_from_file(args.config) - elif default_config is not None: - self.load_config_from_file(default_config) + else: + default_config = get_default_config_file() + if default_config is not None: + self.load_config_from_file(default_config) # Lastly, update the configuration with any command line # settings. From a716285ed0bed5012554e13e15eea5d1ba21ca24 Mon Sep 17 00:00:00 2001 From: Jorge Niedbalski R Date: Sat, 22 Jun 2013 07:14:08 -0700 Subject: [PATCH 4/4] Added coverage for get_default_config_file, also a test for default config overrides --- tests/test_003-config.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/test_003-config.py b/tests/test_003-config.py index d4865de5..6fcc317c 100644 --- a/tests/test_003-config.py +++ b/tests/test_003-config.py @@ -193,6 +193,19 @@ def test_cli_overrides_config(): t.eq(app.cfg.bind, ["blarney"]) t.eq(app.cfg.proc_name, "fooey") +def test_default_config_file(): + default_config = os.path.join(os.path.abspath(os.getcwd()), + 'gunicorn.conf.py') + with open(default_config, 'w+') as default: + default.write("bind='0.0.0.0:9090'") + + t.eq(config.get_default_config_file(), default_config) + + with AltArgs(["prog_name"]): + app = NoConfigApp() + t.eq(app.cfg.bind, ["0.0.0.0:9090"]) + + os.unlink(default_config) def test_post_request(): c = config.Config()