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
 # 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
 
 # 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>
 
 # 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'):
     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:
     else:
+        try:
+            sender = str(git.user())
+        except git.GitException:
+            sender = str(git.author())
+
+    if not sender:
         raise CmdException, 'unknown sender details'
 
         raise CmdException, 'unknown sender details'
 
+    return sender
+
 def __parse_addresses(addresses):
     """Return a two elements tuple: (from, [to])
     """
 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.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'):
 
     # 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
 #
 #
 # 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
     """
 class Commit:
     """Handle the commit objects
     """
@@ -402,6 +434,60 @@ def rm(files, force = False):
         if files:
             __run('git-update-index --force-remove --', files)
 
         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
     """
 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
     # 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
     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)
             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:
         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):
         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 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):
 
     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):
 
     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 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')
 
     def get_log(self):
         return self.__get_field('log')