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 subprocess | 12 import subprocess |
13 import sys | 13 import sys |
14 | 14 |
15 class VersionInfo(object): | 15 class VersionInfo(object): |
16 def __init__(self, url, root, revision): | 16 def __init__(self, url, root, revision): |
17 self.url = url | 17 self.url = url |
18 self.root = root | 18 self.root = root |
19 self.revision = revision | 19 self.revision = revision |
20 | 20 |
21 | 21 def FetchGitRevision(directory): |
22 def IsGitSVN(directory): | |
23 """Return true if the directory is managed by git-svn.""" | |
24 | |
25 # To test whether git-svn has been set up, query the config for any | |
26 # svn-related configuration. This command exits with an error code | |
27 # if there aren't any matches, so ignore its output. | |
28 try: | |
29 status = subprocess.call(['git', 'config', '--get-regexp', '^svn'], | |
30 stdout=subprocess.PIPE, | |
31 stderr=subprocess.PIPE, | |
32 cwd=directory) | |
33 return status == 0 | |
34 except OSError: | |
35 return False | |
36 | |
37 | |
38 def FetchSVNRevision(command, directory): | |
39 """ | 22 """ |
40 Fetch the Subversion branch and revision for the a given directory | 23 Fetch the Git hash for the a given directory. |
41 by running the given command (e.g. "svn info"). | |
42 | 24 |
43 Errors are swallowed. | 25 Errors are swallowed. |
44 | 26 |
45 Returns: | 27 Returns: |
46 a VersionInfo object or None on error. | 28 a VersionInfo object or None on error. |
47 """ | 29 """ |
48 | |
49 # Force shell usage under cygwin & win32. This is a workaround for | 30 # Force shell usage under cygwin & win32. This is a workaround for |
50 # mysterious loss of cwd while invoking cygwin's git. | 31 # mysterious loss of cwd while invoking cygwin's git. |
51 # We can't just pass shell=True to Popen, as under win32 this will | 32 # We can't just pass shell=True to Popen, as under win32 this will |
52 # cause CMD to be used, while we explicitly want a cygwin shell. | 33 # cause CMD to be used, while we explicitly want a cygwin shell. |
53 if sys.platform in ('cygwin', 'win32'): | 34 if sys.platform in ('cygwin', 'win32'): |
54 command = ['sh', '-c', ' '.join(command)] | 35 command = ['sh', '-c', ' '.join(command)] |
55 try: | 36 try: |
56 proc = subprocess.Popen(command, | 37 proc = subprocess.Popen(['git', 'rev-parse', 'HEAD'], |
57 stdout=subprocess.PIPE, | 38 stdout=subprocess.PIPE, |
58 stderr=subprocess.PIPE, | 39 stderr=subprocess.PIPE, |
59 cwd=directory) | 40 cwd=directory) |
41 except OSError: | |
42 return None | |
43 return VersionInfo('git', 'git', proc.stdout.read().strip()[:7]) | |
44 | |
45 | |
46 def FetchSVNRevision(directory): | |
47 """ | |
48 Fetch the Subversion branch and revision for the a given directory. | |
49 | |
50 Errors are swallowed. | |
51 | |
52 Returns: | |
53 a VersionInfo object or None on error. | |
54 """ | |
55 try: | |
56 proc = subprocess.Popen(['svn', 'info'], | |
57 stdout=subprocess.PIPE, | |
58 stderr=subprocess.PIPE, | |
59 cwd=directory) | |
60 except OSError: | 60 except OSError: |
61 # command is apparently either not installed or not executable. | 61 # command is apparently either not installed or not executable. |
62 return None | 62 return None |
63 if not proc: | 63 if not proc: |
64 return None | 64 return None |
65 | 65 |
66 attrs = {} | 66 attrs = {} |
67 for line in proc.stdout: | 67 for line in proc.stdout: |
68 line = line.strip() | 68 line = line.strip() |
69 # git-svn can print out extra "Rebuilding ..." lines, which we don't | 69 if not line: |
70 # care about and want to skip over. | |
71 if not line or ': ' not in line: | |
72 continue | 70 continue |
73 key, val = line.split(': ', 1) | 71 key, val = line.split(': ', 1) |
74 attrs[key] = val | 72 attrs[key] = val |
75 | 73 |
76 try: | 74 try: |
77 url = attrs['URL'] | 75 url = attrs['URL'] |
78 root = attrs['Repository Root'] | 76 root = attrs['Repository Root'] |
79 revision = attrs['Revision'] | 77 revision = attrs['Revision'] |
80 except KeyError: | 78 except KeyError: |
81 return None | 79 return None |
82 | 80 |
83 return VersionInfo(url, root, revision) | 81 return VersionInfo(url, root, revision) |
84 | 82 |
85 | 83 |
86 def FetchVersionInfo(default_lastchange, directory=None): | 84 def FetchVersionInfo(default_lastchange, directory=None): |
87 """ | 85 """ |
88 Returns the last change (in the form of a branch, revision tuple), | 86 Returns the last change (in the form of a branch, revision tuple), |
89 from some appropriate revision control system. | 87 from some appropriate revision control system. |
90 """ | 88 """ |
91 version_info = FetchSVNRevision(['svn', 'info'], directory) | 89 version_info = FetchSVNRevision(directory) |
92 # N.B. test for git-svn before trying 'git svn info', as the info | 90 if not version_info: |
93 # command will hang if git-svn hasn't been set up. | 91 version_info = FetchGitRevision(directory) |
tony
2011/01/26 18:56:29
You could do: version_info = FetchSVNRevision(dire
| |
94 if not version_info and IsGitSVN(directory): | |
95 version_info = FetchSVNRevision(['git', 'svn', 'info'], directory) | |
96 if not version_info: | 92 if not version_info: |
97 if default_lastchange and os.path.exists(default_lastchange): | 93 if default_lastchange and os.path.exists(default_lastchange): |
98 revision = open(default_lastchange, 'r').read().strip() | 94 revision = open(default_lastchange, 'r').read().strip() |
99 version_info = VersionInfo(None, None, revision) | 95 version_info = VersionInfo(None, None, revision) |
100 else: | 96 else: |
101 version_info = VersionInfo('unknown', '', '0') | 97 version_info = VersionInfo('unknown', '', '0') |
102 return version_info | 98 return version_info |
103 | 99 |
104 | 100 |
105 def WriteIfChanged(file_name, contents): | 101 def WriteIfChanged(file_name, contents): |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
150 if out_file: | 146 if out_file: |
151 WriteIfChanged(out_file, contents) | 147 WriteIfChanged(out_file, contents) |
152 else: | 148 else: |
153 sys.stdout.write(contents) | 149 sys.stdout.write(contents) |
154 | 150 |
155 return 0 | 151 return 0 |
156 | 152 |
157 | 153 |
158 if __name__ == '__main__': | 154 if __name__ == '__main__': |
159 sys.exit(main()) | 155 sys.exit(main()) |
OLD | NEW |