Beating this back into shape under SVN.
authorEric S. Raymond <esr@thyrsus.com>
Thu, 27 Sep 2012 17:32:34 +0000 (13:32 -0400)
committerEric S. Raymond <esr@thyrsus.com>
Thu, 27 Sep 2012 17:32:34 +0000 (13:32 -0400)
irkbot.py

index a353a1306641d76923db6d7cff08d8cbf4c956ca..a4fda6d0fd2bf3b48093af95526c22c359aebe11 100755 (executable)
--- a/irkbot.py
+++ b/irkbot.py
 # -n to see the notification dumped to stdout and verify that it looks
 # sane. With -V it dumps its version and exits.
 #
-# git configuration variables affecting this script:
+# Currently works for svn and git.  For svn you must call it as follows:
+#
+# irkbot.py type=svn repository=REPO-PATH commit=REVISION channels=CHANNELS
+#
+# REPO-PATH must be the absolute path of the SVN repository (first
+# argument of Subversion post-commit).  REVISION must be the Subversion numeric
+# commit level (second argument of Subversion post-commit). CHANNELS must
+# be a string containing either an IRC URL or comma-separated list of same
+#
+# For git, you can noormally call this script withoutr arguments; it will 
+# deduce what it needs from git configuration variables and where it is in
+# the file system.  Configuration variables are as follows.
 #
 # irker.project = name of the project
 # irker.channels = list of IRC URLs corresponding to channels
 # Any of these variables can be overridden with a command-line argument that
 # is a key=value pair. For example "project=foobar" will force the project
 # name to foobar, regardless of what the git configuration says.
+#
+# Other configuration changes you may want to make are to:
+# urlprefix: the current version should work for viewcvs or gitweb
+# installations, but will require modification for other systems.
+# tinyfier: If your project maintains its own url-shrinking service
 
 # The default location of the irker proxy, if the project configuration
 # does not override it.
 default_server = "localhost"
 IRKER_PORT = 6659
 
-# Changeset URL prefix for your repo: when the commit ID is appended
-# to this, it should point at a CGI that will display the commit
-# through gitweb or something similar. The defaults will probably
-# work if you have a typical gitweb/cgit setup.
-#
-#urlprefix = "http://%(host)s/cgi-bin/gitweb.cgi?p=%(repo)s;a=commit;h="
-if vcs == "git":
-    urlprefix = "http://%(host)s/viewcvs/%(repo)s?view=revision&revision="
-else:
-    urlprefix = "http://%(host)s/cgi-bin/cgit.cgi/%(repo)s/commit/?id="
-
 # The service used to turn your gitwebbish URL into a tinyurl so it
 # will take up less space on the IRC notification line.
 tinyifier = "http://tinyurl.com/api-create.php?url="
 
-# The template used to generate notifications.  You can make
-# visible changes to the IRC-bot notification lines by hacking this.
-#
-# ${project}: ${author} ${repo}:${branch} * ${rev} / ${files}: ${logmsg} ${url}
-if vcs == "git":
-    template = '%(project)s: %(author)s %(repo)s:%(branch)s * %(rev)s / %(files)s: %(logmsg)s %(url)s'
-else:
-    template = '%(project)s: %(author)s %(repo)s * %(rev)s / %(files)s: %(logmsg)s %(url)s'
-
 #
 # No user-serviceable parts below this line:
 #
@@ -97,24 +93,25 @@ class GitExtractor:
         self.server = do("git config --get irker.server")
         self.channels = do("git config --get irker.channels")
         self.tcp = do("git config --bool --get irker.tcp")
-        # The project variable defaults to the name of the repository toplevel. 
+        # The project variable defaults to the name of the repository toplevel.
+        bare = do("git config --bool --get core.bare")
+        if bare.lower() == "true":
+            keyfile = "HEAD"
+        else:
+            keyfile = ".git/HEAD"
         if not self.project:
             here = os.getcwd()
             while True:
-                if os.path.exists(os.path.join(here, ".git")):
+                if os.path.exists(os.path.join(here, keyfile)):
                     self.project = os.path.basename(here)
                     break
                 elif here == '/':
-                    sys.stderr.write("irkbot.py: no .git below root!\n")
+                    sys.stderr.write("irkbot.py: no git repo below root!\n")
                     sys.exit(1)
                 here = os.path.dirname(here)
-        if not self.repo:
-            self.repo = self.project.lower()
-        self.host = socket.getfqdn()            
         # Revision level
         self.refname = do("git symbolic-ref HEAD 2>/dev/null")
         self.commit = do("git rev-parse HEAD")
-        self.url = urlify(self, self.commit)
 
         self.branch = os.path.basename(self.refname)
 
@@ -138,66 +135,77 @@ class GitExtractor:
         # would make the freenode #commits channel into harvester heaven.
         self.author = self.author.replace("<", "").split("@")[0].split()[-1]
 
-class SvnExtractor(object):
+class SvnExtractor:
     "Metadata extraction for the svn version control system."
-    def __init__(self, project, repository, revision):
-        self.repository = repository
-        self.rev = revision
-        self.project = project
-
+    def __init__(self, arguments):
+        self.commit = None
+        for tok in arguments:
+            if tok.startswith("repository="):
+                self.repository = tok[11:]
+            elif tok.startswith("commit="):
+                self.commit = tok[7:]
+        self.project = os.path.basename(self.path)
         self.author = self.svnlook("author")
         self.files = self.svnlook("dirs-changed")
         self.logmsg = self.svnlook("log")
-        self.host = socket.getfqdn()
-        # TODO: The below three should be configurable
         self.repo = None
         self.tcp = True
         self.channels = None
         # SVN includes this in the path
         self.branch = ""
 
-        # The project variable defaults to the name of the repository toplevel. 
-        if not self.project:
-            here = os.getcwd()
-            while os.path.exists(os.path.join(here, ".svn")):
-                self.project = os.path.basename(here)
-                here = os.path.dirname(here)
-
-        if not self.repo and self.project:
-            self.repo = self.project.lower()
-
-        self.url = urlify(self, self.rev)
-
     def svnlook(self, info):
-        return do("svnlook {0} {1} --revision {2}".format(info, self.repository, self.rev))
+        return do("svnlook {0} {1} --revision {2}".format(info, self.repository, self.commit))
 
 if __name__ == "__main__":
     import getopt
 
     try:
-        (options, arguments) = getopt.getopt(sys.argv[1:], "np:V")
+        (options, arguments) = getopt.getopt(sys.argv[1:], "nV")
     except getopt.GetoptError, msg:
         print "irkbot.py: " + str(msg)
         raise SystemExit, 1
 
     vcs = "git"
     notify = True
-    project = None
     channels = ""
+    commit = ""
     for (switch, val) in options:
-        if switch == '-p':
-            project = val
-        elif switch == '-n':
+        if switch == '-n':
             notify = False
         elif switch == '-V':
             print "irkbot.py: version", version
             sys.exit(0)
 
+    # Force the type if not git
+    for tok in arguments:
+        if tok.startswith("type="):
+            vcs = tok[5:]
+
     # Someday we'll have extractors for several version-control systems
     if vcs == "git":
-        extractor = SvnExtractor(project, arguments[0], arguments[1])
+        extractor = GitExtractor()
+    else:
+        extractor = SvnExtractor(arguments)
+
+    # Changeset URL prefix for your repo: when the commit ID is appended
+    # to this, it should point at a CGI that will display the commit
+    # through gitweb or something similar. The defaults will probably
+    # work if you have a typical gitweb/cgit setup.
+    #
+    #urlprefix = "http://%(host)s/cgi-bin/gitweb.cgi?p=%(repo)s;a=commit;h="
+    if vcs == "svn":
+        urlprefix = "http://%(host)s/viewcvs/%(repo)s?view=revision&revision="
+    else:
+        urlprefix = "http://%(host)s/cgi-bin/cgit.cgi/%(repo)s/commit/?id="
+    # The template used to generate notifications.  You can make
+    # visible changes to the IRC-bot notification lines by hacking this.
+    #
+    # ${project}: ${author} ${repo}:${branch} * ${rev} / ${files}: ${logmsg} ${url}
+    if vcs == "svn":
+        template = '%(project)s: %(author)s %(repo)s:%(branch)s * %(rev)s / %(files)s: %(logmsg)s %(url)s'
     else:
-        extractor = GitExtractor(project)
+        template = '%(project)s: %(author)s %(repo)s * %(rev)s / %(files)s: %(logmsg)s %(url)s'
 
     # Make command-line overrides possible.
     # Each argument of the form <key>=<value> can override the
@@ -218,8 +226,15 @@ if __name__ == "__main__":
     # By default, the channel list includes the freenode #commits list 
     if not extractor.channels:
         extractor.channels = "irc://chat.freenode.net/%s,irc://chat.freenode.net/#commits" % extractor.project
+    # Other defaults get set here
+    if not extractor.repo:
+        extractor.repo = extractor.project.lower()
+    extractor.host = socket.getfqdn()            
+    extractor.url = urlify(extractor, extractor.commit)
 
-    urlprefix = urlprefix % extractor.__dict__
+    if not extractor.project:
+        sys.stderr.write("irkbot.py: no project name set\n")
+        sys.exit(1)
 
     privmsg = template % extractor.__dict__
     channel_list = extractor.channels.split(",")