OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """ | 6 """ |
7 lastchange.py -- Chromium revision fetching utility. | 7 lastchange.py -- Chromium revision fetching utility. |
8 """ | 8 """ |
9 | 9 |
10 import optparse | 10 import optparse |
11 import os | 11 import os |
12 import re | |
13 import subprocess | 12 import subprocess |
14 import sys | 13 import sys |
15 | 14 |
| 15 class VersionInfo(object): |
| 16 def __init__(self, url, root, revision): |
| 17 self.url = url |
| 18 self.root = root |
| 19 self.revision = revision |
16 | 20 |
17 def FetchSVNRevision(command): | 21 |
| 22 def FetchSVNRevision(command, directory): |
18 """ | 23 """ |
19 Fetch the Subversion revision for the local tree. | 24 Fetch the Subversion branch and revision for the a given directory |
| 25 by running the given command (e.g. "svn info"). |
20 | 26 |
21 Errors are swallowed. | 27 Errors are swallowed. |
| 28 |
| 29 Returns: |
| 30 a VersionInfo object or None on error. |
22 """ | 31 """ |
23 try: | 32 try: |
24 proc = subprocess.Popen(command, | 33 proc = subprocess.Popen(command, |
25 stdout=subprocess.PIPE, | 34 stdout=subprocess.PIPE, |
26 stderr=subprocess.PIPE, | 35 stderr=subprocess.PIPE, |
| 36 cwd=directory, |
27 shell=(sys.platform=='win32')) | 37 shell=(sys.platform=='win32')) |
28 except OSError: | 38 except OSError: |
29 # command is apparently either not installed or not executable. | 39 # command is apparently either not installed or not executable. |
30 return None | 40 return None |
31 if proc: | 41 if not proc: |
32 svn_re = re.compile('^Revision:\s+(\d+)', re.M) | 42 return None |
33 match = svn_re.search(proc.stdout.read()) | 43 |
34 if match: | 44 attrs = {} |
35 return match.group(1) | 45 for line in proc.stdout: |
36 return None | 46 line = line.strip() |
| 47 if not line: |
| 48 continue |
| 49 key, val = line.split(': ', 1) |
| 50 attrs[key] = val |
| 51 |
| 52 try: |
| 53 url = attrs['URL'] |
| 54 root = attrs['Repository Root'] |
| 55 revision = attrs['Revision'] |
| 56 except KeyError: |
| 57 return None |
| 58 |
| 59 return VersionInfo(url, root, revision) |
37 | 60 |
38 | 61 |
39 def FetchChange(default_lastchange): | 62 def FetchVersionInfo(default_lastchange, directory=None): |
40 """ | 63 """ |
41 Returns the last change, from some appropriate revision control system. | 64 Returns the last change (in the form of a branch, revision tuple), |
| 65 from some appropriate revision control system. |
42 """ | 66 """ |
43 change = FetchSVNRevision(['svn', 'info']) | 67 version_info = FetchSVNRevision(['svn', 'info'], directory) |
44 if not change and sys.platform in ('linux2',): | 68 if not version_info and sys.platform in ('linux2',): |
45 change = FetchSVNRevision(['git', 'svn', 'info']) | 69 version_info = FetchSVNRevision(['git', 'svn', 'info'], directory) |
46 if not change: | 70 if not version_info: |
47 if default_lastchange and os.path.exists(default_lastchange): | 71 if default_lastchange and os.path.exists(default_lastchange): |
48 change = open(default_lastchange, 'r').read().strip() | 72 revision = open(default_lastchange, 'r').read().strip() |
| 73 version_info = VersionInfo(None, None, revision) |
49 else: | 74 else: |
50 change = '0' | 75 version_info = VersionInfo('', '', '0') |
51 return change | 76 return version_info |
52 | 77 |
53 | 78 |
54 def WriteIfChanged(file_name, contents): | 79 def WriteIfChanged(file_name, contents): |
55 """ | 80 """ |
56 Writes the specified contents to the specified file_name | 81 Writes the specified contents to the specified file_name |
57 iff the contents are different than the current contents. | 82 iff the contents are different than the current contents. |
58 """ | 83 """ |
59 try: | 84 try: |
60 old_contents = open(file_name, 'r').read() | 85 old_contents = open(file_name, 'r').read() |
61 except EnvironmentError: | 86 except EnvironmentError: |
(...skipping 21 matching lines...) Expand all Loading... |
83 out_file = opts.output | 108 out_file = opts.output |
84 | 109 |
85 while len(args) and out_file is None: | 110 while len(args) and out_file is None: |
86 if out_file is None: | 111 if out_file is None: |
87 out_file = args.pop(0) | 112 out_file = args.pop(0) |
88 if args: | 113 if args: |
89 sys.stderr.write('Unexpected arguments: %r\n\n' % args) | 114 sys.stderr.write('Unexpected arguments: %r\n\n' % args) |
90 parser.print_help() | 115 parser.print_help() |
91 sys.exit(2) | 116 sys.exit(2) |
92 | 117 |
93 change = FetchChange(opts.default_lastchange) | 118 version_info = FetchVersionInfo(opts.default_lastchange) |
94 | 119 |
95 if opts.revision_only: | 120 if opts.revision_only: |
96 print change | 121 print version_info.revision |
97 else: | 122 else: |
98 contents = "LASTCHANGE=%s\n" % change | 123 contents = "LASTCHANGE=%s\n" % version_info.revision |
99 if out_file: | 124 if out_file: |
100 WriteIfChanged(out_file, contents) | 125 WriteIfChanged(out_file, contents) |
101 else: | 126 else: |
102 sys.stdout.write(contents) | 127 sys.stdout.write(contents) |
103 | 128 |
104 return 0 | 129 return 0 |
105 | 130 |
106 | 131 |
107 if __name__ == '__main__': | 132 if __name__ == '__main__': |
108 sys.exit(main()) | 133 sys.exit(main()) |
OLD | NEW |