]> asedeno.scripts.mit.edu Git - git-svn-keywords.git/commitdiff
More caching, and some reorg.
authorAlejandro R. Sedeño <asedeno@mit.edu>
Fri, 25 Sep 2009 00:53:01 +0000 (20:53 -0400)
committerAlejandro R. Sedeño <asedeno@mit.edu>
Fri, 25 Sep 2009 00:54:28 +0000 (20:54 -0400)
git-svn-keywords.py

index 7e7b3474a256f65c515e40d07a3075cc4d04f936..d1e6f21887e50f432aa3718b748aa4f0468e79b6 100755 (executable)
@@ -35,6 +35,16 @@ VERSION = 0
 def gsk(g):
     return os.path.join(g.path, 'svn_keywords')
 
+#Configuration Data
+CONFIG = ConfigParser.ConfigParser()
+FILES = ConfigParser.ConfigParser()
+FILEINFO = ConfigParser.ConfigParser()
+
+CONFIG_PATH = ''
+FILES_PATH = ''
+FILEINFO_PATH = ''
+
+
 # Valid keywords:
 svn_keywords = {'Date': ['Date', 'LastDateChanged'],
                 'Revision': ['Revision', 'LastChangedRevision', 'Rev'],
@@ -53,7 +63,6 @@ def get_svn_keyword_re(s):
         svn_keywords_re[s] = re.compile('\$(' + ('|'.join(svn_keywords[s])) + ')[^$]*\$')
     return svn_keywords_re[s]
 
-
 # Parse the unhandled log.
 def parse_svn_unhandled(g):
     try:
@@ -62,24 +71,15 @@ def parse_svn_unhandled(g):
         if e.errno != errno.EEXIST:
             raise
 
-    config = ConfigParser.ConfigParser()
-    config_path = os.path.join(gsk(g), 'conf.ini')
-    config.read(config_path)
-
-    files = ConfigParser.ConfigParser()
-    files_path = os.path.join(gsk(g), 'files.ini')
-
     ver = -1
-    if not config.has_section('core'):
-        config.add_section('core')
-    if config.has_option('core', 'version'):
-        ver = config.getint('core', 'version')
+    if CONFIG.has_option('core', 'version'):
+        ver = CONFIG.getint('core', 'version')
 
     lastrev = None
     if ver == VERSION:
-        files.read(files_path)
-        if config.has_option('core', 'lastrev'):
-            lastrev = config.getint('core', 'lastrev')
+        FILES.read(FILES_PATH)
+        if CONFIG.has_option('core', 'lastrev'):
+            lastrev = CONFIG.getint('core', 'lastrev')
 
     with open(g.path + '/svn/git-svn/unhandled.log', 'r') as f:
         # Compile the regular expressions we'll be using here.
@@ -100,80 +100,89 @@ def parse_svn_unhandled(g):
             if m:
                 path = urllib.unquote(m.group(1))
                 keywords = set(urllib.unquote(m.group(2)).split(' '))
-                if not files.has_section(path):
-                    files.add_section(path)
-                files.set(path, rev, keywords)
+                if not FILES.has_section(path):
+                    FILES.add_section(path)
+                FILES.set(path, rev, keywords)
 
         lastrev = max(int(rev), lastrev)
-        config.set('core', 'lastrev', lastrev)
-        config.set('core', 'version', VERSION)
-
-    with open(files_path, 'wb') as f:
-        files.write(f)
-
-    with open(config_path, 'wb') as f:
-        config.write(f)
+        CONFIG.set('core', 'lastrev', lastrev)
+        CONFIG.set('core', 'version', VERSION)
+
+    with open(FILES_PATH, 'wb') as f:
+        FILES.write(f)
+
+    with open(CONFIG_PATH, 'wb') as f:
+        CONFIG.write(f)
+
+def get_path_info(g, path):
+    write_config = False
+
+    # parse ls-tree output and get a blob id for path
+    blob = g.git.ls_tree('HEAD', path).split(' ')[2].split("\t")[0]
+
+    # translate that to a commit id
+    if not CONFIG.has_option('BlobToCommit', blob):
+        CONFIG.set('BlobToCommit', blob, g.commits('HEAD', path, 1)[0].id)
+        write_config = True
+    commit = CONFIG.get('BlobToCommit', blob)
+
+    # tranlsate that into an svn revision id
+    if not CONFIG.has_option('CommitToRev', commit):
+        CONFIG.set('CommitToRev',commit,g.git.svn('find-rev', commit))
+        write_config = True
+    file_rev = CONFIG.get('CommitToRev', commit)
+
+    # get information about that revision
+    info_dict = {}
+    if not CONFIG.has_option('RevInfo', file_rev):
+        for line in g.git.svn('info', path).split("\n"):
+            k, v = line.split(": ", 1)
+            if k == 'Last Changed Date':
+                info_dict['Date'] = v
+            elif k == 'Last Changed Author':
+                info_dict['Author'] = v
+        CONFIG.set('RevInfo', file_rev, info_dict)
+        write_config = True
+    else:
+        info = CONFIG.get('RevInfo', file_rev)
+        info_dict.update(info if type(info) is dict else eval(info))
+
+    if write_config:
+        with open(CONFIG_PATH, 'wb') as f:
+            CONFIG.write(f)
+
+    info_dict['Revision'] = file_rev
+    return info_dict
 
 # Do the work.
-def smudge(g, clean=0):
+def smudge(g, clean=False):
     parse_svn_unhandled(g)
     rev_head = int(g.git.svn('find-rev', 'HEAD'))
+    url_base = g.git.svn('info', '--url')
 
-    files = ConfigParser.ConfigParser()
-    files_path = os.path.join(gsk(g), 'files.ini')
-    files.read(files_path)
-
-    fileinfo = ConfigParser.ConfigParser()
-    fileinfo_path = os.path.join(gsk(g), 'fileinfo.ini')
-    fileinfo.read(fileinfo_path)
+    FILES.read(FILES_PATH)
+    FILEINFO.read(FILEINFO_PATH)
 
-    revinfo = ConfigParser.ConfigParser()
-    revinfo_path = os.path.join(gsk(g), 'revinfo.ini')
-    revinfo.read(revinfo_path)
-    if not revinfo.has_section('Revisions'):
-        revinfo.add_section('Revisions')
-
-    paths = files.sections()
+    paths = FILES.sections()
     paths.sort()
     for path in paths:
         if not os.path.exists(path):
             continue
 
-        kw_rev = max(filter(lambda x: x <= rev_head, map(int, files.options(path))))
-        commit = g.commits('HEAD', path, 1)[0].id
-        if not revinfo.has_option('Revisions', commit):
-            revinfo.set('Revisions',commit,g.git.svn('find-rev', commit))
-            with open(revinfo_path, 'wb') as f:
-                revinfo.write(f)
-        file_rev = int(revinfo.get('Revisions',commit))
+        kw_rev = max(filter(lambda x: x <= rev_head, map(int, FILES.options(path))))
 
         info_dict = {}
         if not clean:
-            if not fileinfo.has_section(path):
-                fileinfo.add_section(path)
-            if not fileinfo.has_option(path, str(file_rev)):
-                fileinfo.set(path, str(file_rev), g.git.svn('info', path))
-                with open(fileinfo_path, 'wb') as f:
-                    fileinfo.write(f)
-
-            for line in fileinfo.get(path,str(file_rev)).split("\n"):
-                k, v = line.split(": ", 1)
-                if k == 'Last Changed Date':
-                    info_dict['Date'] = v
-                elif k == 'Revision':
-                    info_dict['Revision'] = str(max(kw_rev, file_rev))
-                elif k == 'Last Changed Author':
-                    info_dict['Author'] = v
-                elif k == 'URL':
-                    info_dict['URL'] = v
-                elif k == 'Name':
-                    info_dict['Name'] = v
+            info_dict.update(get_path_info(g, path))
+            info_dict['URL'] = '/'.join([url_base, path])
+            info_dict['Name'] = os.path.basename(path)
+            info_dict['Revision'] = str(max(kw_rev, info_dict['Revision']))
 
         buf = ''
         with open(os.path.join(g.wd, path), 'r') as f:
             buf = f.read()
 
-        keywords = eval(files.get(path, str(kw_rev)))
+        keywords = eval(FILES.get(path, str(kw_rev)))
         for k in keywords:
             for sk in svn_keywords:
                 if k in svn_keywords[sk]:
@@ -191,11 +200,10 @@ def smudge(g, clean=0):
         with open(os.path.join(g.wd, path), 'w') as f:
             f.write(buf)
 
-        print path + ' [' + ', '.join(keywords) + ']'
-
+        #print path + ' [' + ', '.join(keywords) + '] [len: ' + str(len(buf)) +']'
 
 def clean(g):
-    smudge(g,1)
+    smudge(g,True)
 
 if __name__ == '__main__':
     try:
@@ -203,5 +211,15 @@ if __name__ == '__main__':
     except git.errors.InvalidGitRepositoryError:
         print "You are not in a git repository or working directory."
         exit(1)
+
+    CONFIG_PATH = os.path.join(gsk(g), 'conf.ini')
+    FILES_PATH = os.path.join(gsk(g), 'files.ini')
+    FILEINFO_PATH = os.path.join(gsk(g), 'fileinfo.ini')
+
+    CONFIG.read(CONFIG_PATH)
+    for section in ['core','CommitToRev','BlobToCommit', 'RevInfo']:
+        if not CONFIG.has_section(section):
+            CONFIG.add_section(section)
+
     smudge(g)
     #clean(g)