← Back to team overview

configglue team mailing list archive

[Merge] lp:~ricardokirkner/configglue/app-override-op into lp:configglue

 

Ricardo Kirkner has proposed merging lp:~ricardokirkner/configglue/app-override-op into lp:configglue.

Requested reviews:
  Configglue developers (configglue)

For more details, see:
https://code.launchpad.net/~ricardokirkner/configglue/app-override-op/+merge/68970

Overview
========

This branch allows users of the App base class to override the default option parser to define custom options for command line integration.
-- 
https://code.launchpad.net/~ricardokirkner/configglue/app-override-op/+merge/68970
Your team Configglue developers is requested to review the proposed merge of lp:~ricardokirkner/configglue/app-override-op into lp:configglue.
=== modified file 'configglue/app/base.py'
--- configglue/app/base.py	2011-07-22 15:44:24 +0000
+++ configglue/app/base.py	2011-07-23 20:31:20 +0000
@@ -37,13 +37,9 @@
         schemas = [app.schema] + app.plugins.schemas
         self.schema = merge(*schemas)
 
-        # create OptionParser with default options
-        parser = OptionParser()
-        parser.add_option('--validate', dest='validate', action='store_true',
-            help="validate configuration")
         # initialize config
         config_files = self.get_config_files(app)
-        self.glue = configglue(self.schema, config_files, op=parser)
+        self.glue = configglue(self.schema, config_files, op=app.parser)
 
     def get_config_files(self, app):
         config_files = []
@@ -64,7 +60,8 @@
     schema = Schema
     plugin_manager = PluginManager
 
-    def __init__(self, schema=None, plugin_manager=None, name=None):
+    def __init__(self, schema=None, plugin_manager=None, name=None,
+            parser=None):
         # initialize app name
         if name is None:
             name = os.path.splitext(os.path.basename(sys.argv[0]))[0]
@@ -75,7 +72,14 @@
             self.plugins = self.plugin_manager()
         else:
             self.plugins = plugin_manager
-        # setup config
+        # setup schema
         if schema is not None:
             self.schema = schema
+        # setup option parser
+        if parser is None:
+            parser = OptionParser()
+            parser.add_option('--validate', dest='validate', default=False,
+                action='store_true', help="validate configuration")
+        self.parser = parser
+        # setup config
         self.config = Config(self)

=== modified file 'configglue/tests/app/test_base.py'
--- configglue/tests/app/test_base.py	2011-07-22 15:44:24 +0000
+++ configglue/tests/app/test_base.py	2011-07-23 20:31:20 +0000
@@ -15,6 +15,7 @@
 ###############################################################################
 import os
 import user
+from optparse import OptionParser
 from unittest import TestCase
 
 from mock import (
@@ -36,7 +37,8 @@
 )
 
 
-def make_app(name=None, schema=None, plugin_manager=None, validate=False):
+def make_app(name=None, schema=None, plugin_manager=None, validate=False,
+        parser=None):
     # patch sys.argv so that nose can be run with extra options
     # without conflicting with the schema validation
     # patch sys.stderr to prevent spurious output
@@ -46,7 +48,8 @@
         mock_sys.argv.append('--validate')
     with patch('configglue.glue.sys', mock_sys):
         with patch('configglue.app.base.sys.stderr'):
-            app = App(name=name, schema=schema, plugin_manager=plugin_manager)
+            app = App(name=name, schema=schema, plugin_manager=plugin_manager,
+                parser=parser)
     return app
 
 
@@ -70,20 +73,20 @@
             os.environ.get('XDG_CONFIG_DIRS', '/etc/xdg').split(':'))
         return xdg_config_dirs
 
-    @patch('configglue.app.base.OptionParser')
     @patch('configglue.app.base.merge')
     @patch('configglue.app.base.Config.get_config_files')
     @patch('configglue.app.base.configglue')
     def test_constructor(self, mock_configglue,
-        mock_get_config_files, mock_merge, mock_parser):
+        mock_get_config_files, mock_merge):
 
-        config = Config(App())
+        app = App()
+        config = Config(app)
 
         self.assertEqual(config.schema, mock_merge.return_value)
         self.assertEqual(config.glue, mock_configglue.return_value)
         mock_configglue.assert_called_with(
             mock_merge.return_value, mock_get_config_files.return_value,
-            op=mock_parser.return_value)
+            op=app.parser)
 
     def test_glue_valid_config(self):
         config = make_config()
@@ -93,7 +96,8 @@
         class MySchema(Schema):
             foo = IntOption(fatal=True)
 
-        self.assertRaises(SystemExit, make_app, schema=MySchema, validate=True)
+        self.assertRaises(SystemExit, make_app, schema=MySchema,
+            validate=True)
 
     def test_glue_no_validate_invalid_config(self):
         class MySchema(Schema):
@@ -165,3 +169,19 @@
     def test_config(self, mock_config):
         app = make_app()
         self.assertEqual(app.config, mock_config.return_value)
+
+    def test_default_parser(self):
+        app = make_app()
+        # parser is configured
+        self.assertNotEqual(app.parser, None)
+        self.assertEqual(app.config.glue.option_parser, app.parser)
+        # there is only one option by default: --validate
+        self.assertEqual(app.parser.values.__dict__, {'validate': False})
+
+    def test_custom_parser(self):
+        custom_parser = OptionParser()
+        custom_parser.add_option('-f', '--foo')
+        app = make_app(parser=custom_parser)
+        # parser is configured
+        self.assertEqual(app.parser, custom_parser)
+        self.assertEqual(app.config.glue.option_parser, custom_parser)

=== modified file 'configglue/tests/test_schemaconfig.py'
--- configglue/tests/test_schemaconfig.py	2011-07-23 19:10:49 +0000
+++ configglue/tests/test_schemaconfig.py	2011-07-23 20:31:20 +0000
@@ -220,6 +220,20 @@
             finally:
                 sys.argv = _argv
 
+    def test_glue_environ_precedence_fatal_option(self):
+        class MySchema(Schema):
+            foo = IntOption(fatal=True)
+
+        parser = SchemaConfigParser(MySchema())
+
+        with patch.object(os, 'environ', {'CONFIGGLUE_FOO': '42'}):
+            _argv, sys.argv = sys.argv, ['prognam']
+            try:
+                op, options, args = schemaconfigglue(parser)
+                self.assertEqual(parser.get('__main__', 'foo'), 42)
+            finally:
+                sys.argv = _argv
+
     def test_ambiguous_option(self):
         """Test schemaconfigglue when an ambiguous option is specified."""
         class MySchema(Schema):


Follow ups