From: Eric S. Raymond Date: Thu, 27 Sep 2012 17:32:34 +0000 (-0400) Subject: Beating this back into shape under SVN. X-Git-Tag: 1.0~20 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=d895924f54a0c29875aaa591132fedfbc9e91e57;p=irker.git Beating this back into shape under SVN. --- diff --git a/irkbot.py b/irkbot.py index a353a13..a4fda6d 100755 --- a/irkbot.py +++ b/irkbot.py @@ -11,7 +11,18 @@ # -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 @@ -37,36 +48,21 @@ # 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 = 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(",")