chiark / gitweb /
Make stgit.config use git-repo-config.
authorYann Dirson <ydirson@altern.org>
Wed, 31 Jan 2007 23:15:38 +0000 (23:15 +0000)
committerCatalin Marinas <catalin.marinas@gmail.com>
Wed, 31 Jan 2007 23:15:38 +0000 (23:15 +0000)
This is an initial implementation without any sort of caching.  If we
want that, we could do it with this new API.  We could even just
simply generalize the use of ConfigOption instead.

I just copypasted __run from stgit.git to avoid too much work, but
it's definitely something to cleanup.

Signed-off-by: Yann Dirson <ydirson@altern.org>
stgit/commands/common.py
stgit/commands/mail.py
stgit/commands/pull.py
stgit/commands/refresh.py
stgit/commands/series.py
stgit/config.py
stgit/git.py
stgit/gitmergeonefile.py
stgit/stack.py

index 2e57824a42c1834095e36b2ea6f202c08c92e98c..432edcef99e88f134b20e670c9f53e4557688339 100644 (file)
@@ -311,9 +311,10 @@ def address_or_alias(addr_str):
         if addr.find('@') >= 0:
             # it's an e-mail address
             return addr
-        if config.has_option('mail "alias"', addr):
+        alias = config.get('mail.alias.'+addr)
+        if alias:
             # it's an alias
-            return config.get('mail "alias"', addr)
+            return alias
 
         raise CmdException, 'unknown e-mail alias: %s' % addr
 
index 6f61b83d2e66bc428742c562db505c5c868b07c5..7f20f13760cd273ecaa66ac0219ff04a01563d79 100644 (file)
@@ -129,9 +129,8 @@ def __get_sender():
     """Return the 'authname <authemail>' string as read from the
     configuration file
     """
-    if config.has_option('stgit', 'sender'):
-        sender = config.get('stgit', 'sender')
-    else:
+    sender=config.get('stgit.sender')
+    if not sender:
         try:
             sender = str(git.user())
         except git.GitException:
@@ -207,10 +206,7 @@ def __build_address_headers(msg, options, extra_cc = []):
     cc_addr = ''
     bcc_addr = ''
 
-    if config.has_option('stgit', 'autobcc'):
-        autobcc = config.get('stgit', 'autobcc')
-    else:
-        autobcc = ''
+    autobcc = config.get('stgit.autobcc') or ''
 
     if options.to:
         to_addr = ', '.join(options.to)
@@ -283,8 +279,9 @@ def __edit_message(msg):
     f.close()
 
     # the editor
-    if config.has_option('stgit', 'editor'):
-        editor = config.get('stgit', 'editor')
+    editor = config.get('stgit.editor')
+    if editor:
+        pass
     elif 'EDITOR' in os.environ:
         editor = os.environ['EDITOR']
     else:
@@ -469,14 +466,7 @@ def func(parser, options, args):
     """Send the patches by e-mail using the patchmail.tmpl file as
     a template
     """
-    smtpserver = config.get('stgit', 'smtpserver')
-
-    smtpuser = None
-    smtppassword = None
-    if config.has_option('stgit', 'smtpuser'):
-        smtpuser = config.get('stgit', 'smtpuser')
-    if config.has_option('stgit', 'smtppassword'):
-        smtppassword = config.get('stgit', 'smtppassword')
+    smtpserver = config.get('stgit.smtpserver')
 
     applied = crt_series.get_applied()
 
@@ -488,11 +478,8 @@ def func(parser, options, args):
     else:
         raise CmdException, 'Incorrect options. Unknown patches to send'
 
-    if options.smtp_password:
-        smtppassword = options.smtp_password
-
-    if options.smtp_user:
-        smtpuser = options.smtp_user
+    smtppassword = options.smtp_password or config.get('stgit.smtppassword')
+    smtpuser = options.smtp_user or config.get('stgit.smtpuser')
 
     if (smtppassword and not smtpuser):
         raise CmdException, 'SMTP password supplied, username needed'
@@ -508,10 +495,7 @@ def func(parser, options, args):
     else:
         ref_id = options.refid
 
-    if options.sleep != None:
-        sleep = options.sleep
-    else:
-        sleep = config.getint('stgit', 'smtpdelay')
+    sleep = options.sleep or config.getint('stgit.smtpdelay')
 
     # send the cover message (if any)
     if options.cover or options.edit_cover:
index 7c5db221349827239aaeed5c752cb177874292bc..e47858a732159d70c8d0bfb58b85ac02c9b75d48 100644 (file)
@@ -53,11 +53,7 @@ def func(parser, options, args):
     if len(args) >= 1:
         repository = args[0]
     else:
-        section = 'branch "%s"' % git.get_head_file()
-        if config.has_option(section, 'remote'):
-            repository = config.get(section, 'remote')
-        else:
-            repository = 'origin'
+        repository = config.get('branch.%s.remote' % git.get_head_file()) or 'origin'
 
     refspec = None
     if len(args) == 2:
@@ -88,8 +84,7 @@ def func(parser, options, args):
         push_patches(applied, options.merged)
 
     # maybe tidy up
-    repack = config.get('stgit', 'keepoptimized')
-    if repack == 'yes':
+    if config.get('stgit.keepoptimized') == 'yes':
         git.repack()
 
     print_crt_patch()
index 0efe1df0984a00d906558f6af17410d52b4f58ec..7a9bf7db9a5b903dcfd2e4e4de83a171a4022091 100644 (file)
@@ -77,7 +77,7 @@ options = [make_option('-f', '--force',
 
 
 def func(parser, options, args):
-    autoresolved = config.get('stgit', 'autoresolved')
+    autoresolved = config.get('stgit.autoresolved')
 
     if autoresolved != 'yes':
         check_conflicts()
index 4a12d75e8c91d71f072dc24913aa89b398f42730..31ce5cb02b302b2ebc978598078107b0815b9928 100644 (file)
@@ -135,7 +135,7 @@ def func(parser, options, args):
     unapplied = [p for p in unapplied if p in show_patches]
 
     if options.short:
-        nr = int(config.get('stgit', 'shortnr'))
+        nr = int(config.get('stgit.shortnr'))
         if len(applied) > nr:
             applied = applied[-(nr+1):]
         if len(unapplied) > nr:
index a6afbfd057acde62f6e83ce96baa17736ca3f733..d42754bec25da90ab9ea6b7c4be3510e88033ec2 100644 (file)
@@ -18,91 +18,97 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 """
 
-import os, ConfigParser
-from StringIO import StringIO
+import os, re
 from stgit import basedir
 
-config = ConfigParser.RawConfigParser()
-
-def git_config(filename):
-    """Open a git config file and convert it to be understood by
-    Python."""
-    try:
-        f = file(filename)
-        cont = False
-        lines = []
-        for line in f:
-            line = line.strip()
-
-            if cont:
-                # continued line, add a space at the beginning
-                line = ' ' + line
-
-            if line and line[-1] == '\\':
-                line = line[:-1].rstrip()
-                cont = True
-            else:
-                line = line + '\n'
-                cont = False
-
-            lines.append(line)
-
-        f.close()
-        cfg_str = ''.join(lines)
-    except IOError:
-        cfg_str = ''
-
-    strio = StringIO(cfg_str)
-    strio.name = filename
-
-    return strio
+class GitConfigException(Exception):
+    pass
+
+class GitConfig:
+    __defaults={
+        'stgit.autoresolved':  'no',
+        'stgit.smtpserver':    'localhost:25',
+        'stgit.smtpdelay':     '5',
+        'stgit.pullcmd':       'git-pull',
+        'stgit.merger':                'diff3 -L current -L ancestor -L patched -m -E ' \
+                               '"%(branch1)s" "%(ancestor)s" "%(branch2)s" > "%(output)s"',
+        'stgit.autoimerge':    'no',
+        'stgit.keeporig':      'yes',
+        'stgit.keepoptimized': 'no',
+        'stgit.extensions':    '.ancestor .current .patched',
+        'stgit.shortnr':        '5'
+        }
+
+    def __run(self, cmd, args=None):
+        """__run: runs cmd using spawnvp.
+    
+        Runs cmd using spawnvp.  The shell is avoided so it won't mess up
+        our arguments.  If args is very large, the command is run multiple
+        times; args is split xargs style: cmd is passed on each
+        invocation.  Unlike xargs, returns immediately if any non-zero
+        return code is received.  
+        """
+        
+        args_l=cmd.split()
+        if args is None:
+            args = []
+        for i in range(0, len(args)+1, 100):
+            r=os.spawnvp(os.P_WAIT, args_l[0], args_l + args[i:min(i+100, len(args))])
+        if r:
+            return r
+        return 0
+    
+    def get(self, name):
+        stream = os.popen('git repo-config --get %s' % name, 'r')
+        value = stream.readline().strip()
+        stream.close()
+        if len(value) > 0:
+            return value
+        elif (self.__defaults.has_key(name)):
+            return self.__defaults[name]
+        else:
+            return None
+
+    def getall(self, name):
+        stream = os.popen('git repo-config --get-all %s' % name, 'r')
+        values = [line.strip() for line in stream]
+        stream.close()
+        return values
+
+    def getint(self, name):
+        value = self.get(name)
+        if value.isdigit():
+            return int(value)
+        else:
+            raise GitConfigException, 'Value for "%s" is not an integer: "%s"' % (name, value)
+
+    def set(self, name, value):
+        self.__run('git-repo-config', [name, value])
+
+    def sections_matching(self, regexp):
+        """Takes a regexp with a single group, matches it against all
+        config variables, and returns a list whose members are the
+        group contents, for all variable names matching the regexp.
+        """
+        result = []
+        stream = os.popen('git repo-config --get-regexp "^%s$"' % regexp, 'r')
+        for line in stream:
+            m = re.match('^%s ' % regexp, line)
+            if m:
+                result.append(m.group(1))
+        stream.close()
+        return result
+        
+config=GitConfig()
 
 def config_setup():
     global config
 
-    # Set the defaults
-    config.add_section('stgit')
-    config.set('stgit', 'autoresolved', 'no')
-    config.set('stgit', 'smtpserver', 'localhost:25')
-    config.set('stgit', 'smtpdelay', '5')
-    config.set('stgit', 'pullcmd', 'git-pull')
-    config.set('stgit', 'merger',
-               'diff3 -L current -L ancestor -L patched -m -E ' \
-               '"%(branch1)s" "%(ancestor)s" "%(branch2)s" > "%(output)s"')
-    config.set('stgit', 'autoimerge', 'no')
-    config.set('stgit', 'keeporig', 'yes')
-    config.set('stgit', 'keepoptimized', 'no')
-    config.set('stgit', 'extensions', '.ancestor .current .patched')
-    config.set('stgit', 'shortnr', '5')
-
-    # Read the configuration files (if any) and override the default settings
-    # stgitrc are read for backward compatibility
-    config.read('/etc/stgitrc')
-    config.read(os.path.expanduser('~/.stgitrc'))
-    config.read(os.path.join(basedir.get(), 'stgitrc'))
-
-    # GIT configuration files can have a [stgit] section
-    try:
-        global_config = os.environ['GIT_CONFIG']
-    except KeyError:
-        global_config = os.path.expanduser('~/.gitconfig')
-    try:
-        local_config = os.environ['GIT_CONFIG_LOCAL']
-    except KeyError:
-        local_config = os.path.join(basedir.get(), 'config')
-    config.readfp(git_config(global_config))
-    config.readfp(git_config(local_config))
-
     # Set the PAGER environment to the config value (if any)
-    if config.has_option('stgit', 'pager'):
-        os.environ['PAGER'] = config.get('stgit', 'pager')
-
-    # [gitmergeonefile] section is deprecated. In case it exists copy the
-    # options/values to the [stgit] one
-    if config.has_section('gitmergeonefile'):
-        for option, value in config.items('gitmergeonefile'):
-            config.set('stgit', option, value)
-
+    pager = config.get('stgit.pager')
+    if pager:
+        os.environ['PAGER'] = pager
+    # FIXME: handle EDITOR the same way ?
 
 class ConfigOption:
     """Delayed cached reading of a configuration option.
@@ -114,7 +120,7 @@ class ConfigOption:
 
     def __str__(self):
         if not self.__value:
-            self.__value = config.get(self.__section, self.__option)
+            self.__value = config.get(self.__section + '.' + self.__option)
         return self.__value
 
 
@@ -127,7 +133,7 @@ def file_extensions():
     global __extensions
 
     if not __extensions:
-        cfg_ext = config.get('stgit', 'extensions').split()
+        cfg_ext = config.get('stgit.extensions').split()
         if len(cfg_ext) != 3:
             raise CmdException, '"extensions" configuration error'
 
index 7d99338fb9b3b4b7ee0ebe5f1445af1bd4656f59..249080ea2135f485033ed98133c25bd45db86f30 100644 (file)
@@ -449,10 +449,10 @@ def user():
     """
     global __user
     if not __user:
-        if config.has_option('user', 'name') \
-               and config.has_option('user', 'email'):
-            __user = Person(config.get('user', 'name'),
-                            config.get('user', 'email'))
+        name=config.get('user.name')
+        email=config.get('user.email')
+        if name and email:
+            __user = Person(name, email)
         else:
             raise GitException, 'unknown user details'
     return __user;
@@ -818,7 +818,7 @@ def pull(repository = 'origin', refspec = None):
     if refspec:
         args.append(refspec)
 
-    if __run(config.get('stgit', 'pullcmd'), args) != 0:
+    if __run(config.get('stgit.pullcmd'), args) != 0:
         raise GitException, 'Failed "git-pull %s"' % repository
 
 def repack():
index 587c8c46cd626e9eddcacb665d7406e7780bd4d6..b9d02aa21288380362c999a0e54647b346702783 100644 (file)
@@ -102,9 +102,8 @@ def interactive_merge(filename):
     """Run the interactive merger on the given file. Note that the
     index should not have any conflicts.
     """
-    try:
-        imerger = config.get('stgit', 'imerger')
-    except Exception, err:
+    imerger = config.get('stgit.imerger')
+    if not imerger:
         raise GitMergeException, 'Configuration error: %s' % err
 
     extensions = file_extensions()
@@ -185,7 +184,7 @@ def merge(orig_hash, file1_hash, file2_hash,
                     os.system('git-update-index --cacheinfo %s %s %s'
                               % (file1_mode, file1_hash, path))
 
-                    if config.get('stgit', 'autoimerge') == 'yes':
+                    if config.get('stgit.autoimerge') == 'yes':
                         print >> sys.stderr, \
                               'Trying the interactive merge'
                         try:
index 5237084ce04bf00e893599df0aacbb7a9ff0840b..6281f368b2b3668bcec21f7ca7124052e1cee6f1 100644 (file)
@@ -92,8 +92,9 @@ def edit_file(series, line, comment, show_patch = True):
     f.close()
 
     # the editor
-    if config.has_option('stgit', 'editor'):
-        editor = config.get('stgit', 'editor')
+    editor = config.get('stgit.editor')
+    if editor:
+        pass
     elif 'EDITOR' in os.environ:
         editor = os.environ['EDITOR']
     else: