Hello I attach a patch to implement command line options for smtp servers.
[[[ add command line options to mailer.py * tools/hook-scripts/mailer/mailer.py () : import OptionParser. (main) : add options to arguments. (PipeOutput.__init__) : call cfg.get_mail_command() to get mail command. (Messenger.__init__) : call cfg.get_mail_command() and cfg.get_smtp_hostname() to get target. (Config.__init__) : add options to arguments and save it. (Config.get_mail_command) : get mail command from command line or config. (Config.get_smtp_hostname): get smtp hostname from command line or config. (Config.get_smtp_username): get smtp username from command line or config. (Config.get_smtp_password): get smtp password from command line or config. (setup_option_parser) : create instance of OptionParser. (usage) : print usage by using OptionParser. (): parse command line by using OptionParser. ]]] -- Masaru Tsuchiyama <m.tma...@gmail.com>
Index: tools/hook-scripts/mailer/mailer.py =================================================================== --- tools/hook-scripts/mailer/mailer.py (revision 1514200) +++ tools/hook-scripts/mailer/mailer.py (working copy) @@ -65,6 +65,7 @@ else: import smtplib import re import tempfile +from optparse import OptionParser # Minimal version of Subversion's bindings required _MIN_SVN_VERSION = [1, 5, 0] @@ -92,13 +93,13 @@ if _MIN_SVN_VERSION > [svn.core.SVN_VER_MAJOR, SEPARATOR = '=' * 78 -def main(pool, cmd, config_fname, repos_dir, cmd_args): +def main(pool, cmd, options, config_fname, repos_dir, cmd_args): ### TODO: Sanity check the incoming args if cmd == 'commit': revision = int(cmd_args[0]) repos = Repository(repos_dir, revision, pool) - cfg = Config(config_fname, repos, + cfg = Config(options, config_fname, repos, {'author': repos.author, 'repos_basename': os.path.basename(repos.repos_dir) }) @@ -111,7 +112,7 @@ SEPARATOR = '=' * 78 repos = Repository(repos_dir, revision, pool) # Override the repos revision author with the author of the propchange repos.author = author - cfg = Config(config_fname, repos, + cfg = Config(options, config_fname, repos, {'author': author, 'repos_basename': os.path.basename(repos.repos_dir) }) @@ -121,7 +122,7 @@ SEPARATOR = '=' * 78 repos = Repository(repos_dir, 0, pool) ### any old revision will do # Override the repos revision author with the author of the lock/unlock repos.author = author - cfg = Config(config_fname, repos, + cfg = Config(options, config_fname, repos, {'author': author, 'repos_basename': os.path.basename(repos.repos_dir) }) @@ -291,10 +292,10 @@ class SMTPOutput(MailedOutput): self.write(self.mail_headers(group, params)) def finish(self): - server = smtplib.SMTP(self.cfg.general.smtp_hostname) - if self.cfg.is_set('general.smtp_username'): - server.login(self.cfg.general.smtp_username, - self.cfg.general.smtp_password) + server = smtplib.SMTP(self.cfg.get_smtp_hostname()) + if self.cfg.get_smtp_username(): + server.login(self.cfg.get_smtp_username(), + self.cfg.get_smtp_password()) server.sendmail(self.from_addr, self.to_addrs, self.buffer.getvalue()) server.quit() @@ -321,7 +322,7 @@ class PipeOutput(MailedOutput): MailedOutput.__init__(self, cfg, repos, prefix_param) # figure out the command for delivery - self.cmd = cfg.general.mail_command.split() + self.cmd = cfg.get_mail_command().split() def start(self, group, params): MailedOutput.start(self, group, params) @@ -352,9 +353,9 @@ class Messenger: self.cfg = cfg self.repos = repos - if cfg.is_set('general.mail_command'): + if cfg.get_mail_command(): cls = PipeOutput - elif cfg.is_set('general.smtp_hostname'): + elif cfg.get_smtp_hostname(): cls = SMTPOutput else: cls = StandardOutput @@ -1169,10 +1170,13 @@ class Config: # set of groups. _predefined = ('general', 'defaults', 'maps') - def __init__(self, fname, repos, global_params): + def __init__(self, options, fname, repos, global_params): cp = configparser.ConfigParser() cp.read(fname) + # save options + self._options = options + # record the (non-default) groups that we find self._groups = [ ] @@ -1380,7 +1384,42 @@ class Config: return groups + def get_mail_command(self): + "Return mail_command" + if self._options.mail_command: + return self._options.mail_command + if self.is_set('general.mail_command'): + return self.general.mail_command + return None + + def get_smtp_hostname(self): + "Return smtp_hostname" + if self._options.smtp_hostname: + return self._options.smtp_hostname + + if self.is_set('general.smtp_hostname'): + return self.general.smtp_hostname + return None + + def get_smtp_username(self): + "Return smtp_username" + if self._options.smtp_username: + return self._options.smtp_username + + if self.is_set('general.smtp_username'): + return self.general.smtp_username + return None + + def get_smtp_password(self): + "Return smtp_password" + if self._options.smtp_password: + return self._options.smtp_password + + if self.is_set('general.smtp_password'): + return self.general.smtp_password + return None + class _sub_section: pass @@ -1400,10 +1439,9 @@ class UnknownSubcommand(Exception): if __name__ == '__main__': - def usage(): + def setup_option_parser(): scriptname = os.path.basename(sys.argv[0]) - sys.stderr.write( -"""USAGE: %s commit REPOS REVISION [CONFIG-FILE] + usage = """%s commit REPOS REVISION [CONFIG-FILE] %s propchange REPOS REVISION AUTHOR REVPROPNAME [CONFIG-FILE] %s propchange2 REPOS REVISION AUTHOR REVPROPNAME ACTION [CONFIG-FILE] %s lock REPOS AUTHOR [CONFIG-FILE] @@ -1416,10 +1454,41 @@ the script itself resides. ACTION was added as a fifth argument to the post-revprop-change hook in Subversion 1.2.0. Its value is one of 'A', 'M' or 'D' to indicate if the property was added, modified or deleted, respectively. +""" % (scriptname, scriptname, scriptname, scriptname, scriptname) -""" % (scriptname, scriptname, scriptname, scriptname, scriptname)) + parser = OptionParser(usage=usage) + parser.add_option("--mail-command", dest="mail_command", default=None, + help="specify mail command" ) + parser.add_option("--smtp-hostname", dest="smtp_hostname", default=None, + help="specify smtp host name" ) + parser.add_option("--smtp-username", dest="smtp_username", default=None, + help="specify smtp username" ) + parser.add_option("--smtp-password", dest="smtp_password", default=None, + help="specify smtp password" ) + return parser + + def usage(parser): + parser.print_help() sys.exit(1) + parser = setup_option_parser() + (options, args) = parser.parse_args() + + # check command line option for smtp servers. + if options.smtp_username or options.smtp_password: + if options.mail_command: + print ("--mail-command and --smtp-username or --smtp-password are mutually exclusive\n") + parser.print_help() + sys.exit(1) + if options.smtp_hostname == None: + print ("if use --smtp-username or --smtp-password, you must specify --smtp-hostname too.\n") + parser.print_help() + sys.exit(1) + elif options.mail_command and options.smtp_hostname: + print ("--mail-command and --smtp-hostname are mutually exclusive\n") + parser.print_help() + sys.exit(1) + # Command list: subcommand -> number of arguments expected (not including # the repository directory and config-file) cmd_list = {'commit' : 1, @@ -1430,23 +1499,23 @@ if the property was added, modified or deleted, re } config_fname = None - argc = len(sys.argv) - if argc < 3: - usage() + argc = len(args) + if argc < 2: + usage(parser) - cmd = sys.argv[1] - repos_dir = svn.core.svn_path_canonicalize(sys.argv[2]) + cmd = args[0] + repos_dir = svn.core.svn_path_canonicalize(args[1]) try: expected_args = cmd_list[cmd] except KeyError: - usage() + usage(parser) - if argc < (expected_args + 3): - usage() - elif argc > expected_args + 4: - usage() - elif argc == (expected_args + 4): - config_fname = sys.argv[expected_args + 3] + if argc < (expected_args + 2): + usage(parser) + elif argc > expected_args + 3: + usage(parser) + elif argc == (expected_args + 3): + config_fname = args[expected_args + 2] # Settle on a config file location, and open it. if config_fname is None: @@ -1458,8 +1527,8 @@ if the property was added, modified or deleted, re if not os.path.exists(config_fname): raise MissingConfig(config_fname) - svn.core.run_app(main, cmd, config_fname, repos_dir, - sys.argv[3:3+expected_args]) + svn.core.run_app(main, cmd, options, config_fname, repos_dir, + args[2:2+expected_args]) # ------------------------------------------------------------------------ # TODO