source: valtobtest/subversion-1.6.2/tools/hook-scripts/log-police.py @ 3

Last change on this file since 3 was 3, checked in by valtob, 15 years ago

subversion source 1.6.2 as test

  • Property svn:executable set to *
File size: 4.3 KB
Line 
1#!/usr/bin/env python
2
3# log-police.py: Ensure that log messages end with a single newline.
4# See usage() function for details, or just run with no arguments.
5
6import os
7import sys
8import getopt
9try:
10  my_getopt = getopt.gnu_getopt
11except AttributeError:
12  my_getopt = getopt.getopt
13
14import svn
15import svn.fs
16import svn.repos
17import svn.core
18
19
20def fix_log_message(log_message):
21  """Return a fixed version of LOG_MESSAGE.  By default, this just
22  means ensuring that the result ends with exactly one newline and no
23  other whitespace.  But if you want to do other kinds of fixups, this
24  function is the place to implement them -- all log message fixing in
25  this script happens here."""
26  return log_message.rstrip() + "\n"
27
28
29def fix_txn(fs, txn_name):
30  "Fix up the log message for txn TXN_NAME in FS.  See fix_log_message()."
31  txn = svn.fs.svn_fs_open_txn(fs, txn_name)
32  log_message = svn.fs.svn_fs_txn_prop(txn, "svn:log")
33  if log_message is not None:
34    new_message = fix_log_message(log_message)
35    if new_message != log_message:
36      svn.fs.svn_fs_change_txn_prop(txn, "svn:log", new_message)
37
38
39def fix_rev(fs, revnum):
40  "Fix up the log message for revision REVNUM in FS.  See fix_log_message()."
41  log_message = svn.fs.svn_fs_revision_prop(fs, revnum, 'svn:log')
42  if log_message is not None:
43    new_message = fix_log_message(log_message)
44    if new_message != log_message:
45      svn.fs.svn_fs_change_rev_prop(fs, revnum, "svn:log", new_message)
46
47
48def usage_and_exit(error_msg=None):
49  """Write usage information and exit.  If ERROR_MSG is provide, that
50  error message is printed first (to stderr), the usage info goes to
51  stderr, and the script exits with a non-zero status.  Otherwise,
52  usage info goes to stdout and the script exits with a zero status."""
53  import os.path
54  stream = error_msg and sys.stderr or sys.stdout
55  if error_msg:
56    stream.write("ERROR: %s\n\n" % error_msg)
57  stream.write("USAGE: %s [-t TXN_NAME | -r REV_NUM | --all-revs] REPOS\n"
58               % (os.path.basename(sys.argv[0])))
59  stream.write("""
60Ensure that log messages end with exactly one newline and no other
61whitespace characters.  Use as a pre-commit hook by passing '-t TXN_NAME';
62fix up a single revision by passing '-r REV_NUM'; fix up all revisions by
63passing '--all-revs'.  (When used as a pre-commit hook, may modify the
64svn:log property on the txn.)
65""")
66  sys.exit(error_msg and 1 or 0)
67
68
69def main(ignored_pool, argv):
70  repos_path = None
71  txn_name = None
72  rev_name = None
73  all_revs = False
74
75  try:
76    opts, args = my_getopt(argv[1:], 't:r:h?', ["help", "all-revs"])
77  except:
78    usage_and_exit("problem processing arguments / options.")
79  for opt, value in opts:
80    if opt == '--help' or opt == '-h' or opt == '-?':
81      usage_and_exit()
82    elif opt == '-t':
83      txn_name = value
84    elif opt == '-r':
85      rev_name = value
86    elif opt == '--all-revs':
87      all_revs = True
88    else:
89      usage_and_exit("unknown option '%s'." % opt)
90
91  if txn_name is not None and rev_name is not None:
92    usage_and_exit("cannot pass both -t and -r.")
93  if txn_name is not None and all_revs:
94    usage_and_exit("cannot pass --all-revs with -t.")
95  if rev_name is not None and all_revs:
96    usage_and_exit("cannot pass --all-revs with -r.")
97  if rev_name is None and txn_name is None and not all_revs:
98    usage_and_exit("must provide exactly one of -r, -t, or --all-revs.")
99  if len(args) != 1:
100    usage_and_exit("only one argument allowed (the repository).")
101
102  repos_path = svn.core.svn_path_canonicalize(args[0])
103
104  # A non-bindings version of this could be implemented by calling out
105  # to 'svnlook getlog' and 'svnadmin setlog'.  However, using the
106  # bindings results in much simpler code.
107
108  fs = svn.repos.svn_repos_fs(svn.repos.svn_repos_open(repos_path))
109  if txn_name is not None:
110    fix_txn(fs, txn_name)
111  elif rev_name is not None:
112    fix_rev(fs, int(rev_name))
113  elif all_revs:
114    # Do it such that if we're running on a live repository, we'll
115    # catch up even with commits that came in after we started.
116    last_youngest = 0
117    while True:
118      youngest = svn.fs.svn_fs_youngest_rev(fs)
119      if youngest >= last_youngest:
120        for this_rev in range(last_youngest, youngest + 1):
121          fix_rev(fs, this_rev)
122        last_youngest = youngest + 1
123      else:
124        break
125
126
127if __name__ == '__main__':
128  sys.exit(svn.core.run_app(main, sys.argv))
Note: See TracBrowser for help on using the repository browser.