Ask git for author and committer name
authorKarl Hasselström <kha@treskal.com>
Tue, 5 Dec 2006 22:07:23 +0000 (22:07 +0000)
committerCatalin Marinas <catalin.marinas@gmail.com>
Tue, 5 Dec 2006 22:07:23 +0000 (22:07 +0000)
(patch modified by Catalin Marinas)

Consistently do the following to get hold of default user, author and
committer:

  1. Use the value specified on the command line, if any.

  2. Otherwise, use the environment variables, if any.

  3. Otherwise, read the configuration files

Signed-off-by: Karl Hasselström <kha@treskal.com>
Signed-off-by: Catalin Marinas <catalin.marinas@gmail.com>
examples/gitconfig
stgit/commands/mail.py
stgit/config.py
stgit/git.py
stgit/main.py
stgit/stack.py

index 9a5cd07..42e6296 100644 (file)
@@ -1,14 +1,13 @@
 # StGIT configuration file. Copy it to any of ~/.gitconfig or
-# .git/gitconfig and modify as needed. Note that the latter overrides
+# .git/config and modify as needed. Note that the latter overrides
 # the former. The "git repo-config" command can be used as well
 
-[stgit]
-# Default author/committer details
-#authname = Your Name
-#authemail = your.name@yourcompany.com
-#commname = Your Name
-#commemail = your.name@yourcompany.com
+[user]
+# Default author/committer details (standard GIT variables)
+#name = Your Name
+#email = your.name@yourcompany.com
 
+[stgit]
 # E-mail sender (added to the "From: " header)
 #sender = Your Name <your.name@yourcompany.com>
 
index 176d7a2..5d71657 100644 (file)
@@ -127,14 +127,18 @@ def __get_sender():
     configuration file
     """
     if config.has_option('stgit', 'sender'):
-        return config.get('stgit', 'sender')
-    elif config.has_option('stgit', 'authname') \
-             and config.has_option('stgit', 'authemail'):
-        return '%s <%s>' % (config.get('stgit', 'authname'),
-                            config.get('stgit', 'authemail'))
+        sender = config.get('stgit', 'sender')
     else:
+        try:
+            sender = str(git.user())
+        except git.GitException:
+            sender = str(git.author())
+
+    if not sender:
         raise CmdException, 'unknown sender details'
 
+    return sender
+
 def __parse_addresses(addresses):
     """Return a two elements tuple: (from, [to])
     """
index b56ab1b..2174f09 100644 (file)
@@ -80,8 +80,16 @@ def config_setup():
     config.read(os.path.join(basedir.get(), 'stgitrc'))
 
     # GIT configuration files can have a [stgit] section
-    config.readfp(git_config(os.path.expanduser('~/.gitconfig')))
-    config.readfp(git_config(os.path.join(basedir.get(), 'config')))
+    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'):
index 984b749..13f7b87 100644 (file)
@@ -33,6 +33,38 @@ class GitException(Exception):
 #
 # Classes
 #
+
+class Person:
+    """An author, committer, etc."""
+    def __init__(self, name = None, email = None, date = '',
+                 desc = None):
+        if name or email or date:
+            assert not desc
+            self.name = name
+            self.email = email
+            self.date = date
+        elif desc:
+            assert not (name or email or date)
+            def parse_desc(s):
+                m = re.match(r'^(.+)<(.+)>(.*)$', s)
+                assert m
+                return [x.strip() or None for x in m.groups()]
+            self.name, self.email, self.date = parse_desc(desc)
+    def set_name(self, val):
+        if val:
+            self.name = val
+    def set_email(self, val):
+        if val:
+            self.email = val
+    def set_date(self, val):
+        if val:
+            self.date = val
+    def __str__(self):
+        if self.name and self.email:
+            return '%s <%s>' % (self.name, self.email)
+        else:
+            raise GitException, 'not enough identity data'
+
 class Commit:
     """Handle the commit objects
     """
@@ -402,6 +434,60 @@ def rm(files, force = False):
         if files:
             __run('git-update-index --force-remove --', files)
 
+# Persons caching
+__user = None
+__author = None
+__committer = None
+
+def user():
+    """Return the user information.
+    """
+    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'))
+        else:
+            raise GitException, 'unknown user details'
+    return __user;
+
+def author():
+    """Return the author information.
+    """
+    global __author
+    if not __author:
+        try:
+            # the environment variables take priority over config
+            try:
+                date = os.environ['GIT_AUTHOR_DATE']
+            except KeyError:
+                date = ''
+            __author = Person(os.environ['GIT_AUTHOR_NAME'],
+                              os.environ['GIT_AUTHOR_EMAIL'],
+                              date)
+        except KeyError:
+            __author = user()
+    return __author
+
+def committer():
+    """Return the author information.
+    """
+    global __committer
+    if not __committer:
+        try:
+            # the environment variables take priority over config
+            try:
+                date = os.environ['GIT_COMMITTER_DATE']
+            except KeyError:
+                date = ''
+            __committer = Person(os.environ['GIT_COMMITTER_NAME'],
+                                 os.environ['GIT_COMMITTER_EMAIL'],
+                                 date)
+        except KeyError:
+            __committer = user()
+    return __committer
+
 def update_cache(files = None, force = False):
     """Update the cache information for the given files
     """
index c2797c9..c2af585 100644 (file)
@@ -221,7 +221,7 @@ def main():
     # These modules are only used from this point onwards and do not
     # need to be imported earlier
     from stgit.config import config_setup
-    from ConfigParser import ParsingError
+    from ConfigParser import ParsingError, NoSectionError
     from stgit.stack import Series, StackException
     from stgit.git import GitException
     from stgit.commands.common import CmdException
@@ -240,8 +240,8 @@ def main():
             stgit.commands.common.crt_series = command.crt_series
 
         command.func(parser, options, args)
-    except (IOError, ParsingError, CmdException, StackException, GitException,
-            GitMergeException), err:
+    except (IOError, ParsingError, NoSectionError, CmdException,
+            StackException, GitException, GitMergeException), err:
         print >> sys.stderr, '%s %s: %s' % (prog, cmd, err)
         sys.exit(2)
     except KeyboardInterrupt:
index 8fa3846..4df306a 100644 (file)
@@ -238,53 +238,31 @@ class Patch:
         return self.__get_field('authname')
 
     def set_authname(self, name):
-        if not name:
-            if config.has_option('stgit', 'authname'):
-                name = config.get('stgit', 'authname')
-            elif 'GIT_AUTHOR_NAME' in os.environ:
-                name = os.environ['GIT_AUTHOR_NAME']
-        self.__set_field('authname', name)
+        self.__set_field('authname', name or git.author().name)
 
     def get_authemail(self):
         return self.__get_field('authemail')
 
-    def set_authemail(self, address):
-        if not address:
-            if config.has_option('stgit', 'authemail'):
-                address = config.get('stgit', 'authemail')
-            elif 'GIT_AUTHOR_EMAIL' in os.environ:
-                address = os.environ['GIT_AUTHOR_EMAIL']
-        self.__set_field('authemail', address)
+    def set_authemail(self, email):
+        self.__set_field('authemail', email or git.author().email)
 
     def get_authdate(self):
         return self.__get_field('authdate')
 
     def set_authdate(self, date):
-        if not date and 'GIT_AUTHOR_DATE' in os.environ:
-            date = os.environ['GIT_AUTHOR_DATE']
-        self.__set_field('authdate', date)
+        self.__set_field('authdate', date or git.author().date)
 
     def get_commname(self):
         return self.__get_field('commname')
 
     def set_commname(self, name):
-        if not name:
-            if config.has_option('stgit', 'commname'):
-                name = config.get('stgit', 'commname')
-            elif 'GIT_COMMITTER_NAME' in os.environ:
-                name = os.environ['GIT_COMMITTER_NAME']
-        self.__set_field('commname', name)
+        self.__set_field('commname', name or git.committer().name)
 
     def get_commemail(self):
         return self.__get_field('commemail')
 
-    def set_commemail(self, address):
-        if not address:
-            if config.has_option('stgit', 'commemail'):
-                address = config.get('stgit', 'commemail')
-            elif 'GIT_COMMITTER_EMAIL' in os.environ:
-                address = os.environ['GIT_COMMITTER_EMAIL']
-        self.__set_field('commemail', address)
+    def set_commemail(self, email):
+        self.__set_field('commemail', email or git.committer().email)
 
     def get_log(self):
         return self.__get_field('log')