OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 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 re | 10 import re |
11 import optparse | 11 import optparse |
12 import os | 12 import os |
13 import subprocess | 13 import subprocess |
14 import sys | 14 import sys |
15 | 15 |
16 _GIT_SVN_ID_REGEX = re.compile(r'.*git-svn-id:\s*([^@]*)@([0-9]+)', re.DOTALL) | |
17 | |
18 class VersionInfo(object): | 16 class VersionInfo(object): |
19 def __init__(self, url, revision): | 17 def __init__(self, revision): |
20 self.url = url | |
21 self.revision = revision | 18 self.revision = revision |
22 | 19 |
23 | 20 |
24 def RunGitCommand(directory, command): | 21 def RunGitCommand(directory, command): |
25 """ | 22 """ |
26 Launches git subcommand. | 23 Launches git subcommand. |
27 | 24 |
28 Errors are swallowed. | 25 Errors are swallowed. |
29 | 26 |
30 Returns: | 27 Returns: |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 return None | 65 return None |
69 pos = '' | 66 pos = '' |
70 proc = RunGitCommand(directory, ['cat-file', 'commit', hsh]) | 67 proc = RunGitCommand(directory, ['cat-file', 'commit', hsh]) |
71 if proc: | 68 if proc: |
72 output = proc.communicate()[0] | 69 output = proc.communicate()[0] |
73 if proc.returncode == 0 and output: | 70 if proc.returncode == 0 and output: |
74 for line in reversed(output.splitlines()): | 71 for line in reversed(output.splitlines()): |
75 if line.startswith('Cr-Commit-Position:'): | 72 if line.startswith('Cr-Commit-Position:'): |
76 pos = line.rsplit()[-1].strip() | 73 pos = line.rsplit()[-1].strip() |
77 break | 74 break |
78 return VersionInfo('git', '%s-%s' % (hsh, pos)) | 75 return VersionInfo('%s-%s' % (hsh, pos)) |
79 | 76 |
80 | 77 |
81 def FetchVersionInfo(directory=None, | 78 def FetchVersionInfo(directory=None): |
82 directory_regex_prior_to_src_url='chrome|svn'): | |
83 """ | 79 """ |
84 Returns the last change (in the form of a branch, revision tuple), | 80 Returns the last change (in the form of a branch, revision tuple), |
85 from some appropriate revision control system. | 81 from some appropriate revision control system. |
86 """ | 82 """ |
87 svn_url_regex = re.compile( | |
88 r'.*/(' + directory_regex_prior_to_src_url + r')(/.*)') | |
89 | |
90 version_info = FetchGitRevision(directory) | 83 version_info = FetchGitRevision(directory) |
91 if not version_info: | 84 if not version_info: |
92 version_info = VersionInfo(None, None) | 85 version_info = VersionInfo(None) |
93 return version_info | 86 return version_info |
94 | 87 |
95 | 88 |
96 def GetHeaderGuard(path): | 89 def GetHeaderGuard(path): |
97 """ | 90 """ |
98 Returns the header #define guard for the given file path. | 91 Returns the header #define guard for the given file path. |
99 This treats everything after the last instance of "src/" as being a | 92 This treats everything after the last instance of "src/" as being a |
100 relevant part of the guard. If there is no "src/", then the entire path | 93 relevant part of the guard. If there is no "src/", then the entire path |
101 is used. | 94 is used. |
102 """ | 95 """ |
103 src_index = path.rfind('src/') | 96 src_index = path.rfind('src/') |
104 if src_index != -1: | 97 if src_index != -1: |
105 guard = path[src_index + 4:] | 98 guard = path[src_index + 4:] |
106 else: | 99 else: |
107 guard = path | 100 guard = path |
108 guard = guard.upper() | 101 guard = guard.upper() |
109 return guard.replace('/', '_').replace('.', '_').replace('\\', '_') + '_' | 102 return guard.replace('/', '_').replace('.', '_').replace('\\', '_') + '_' |
110 | 103 |
111 | 104 |
112 def GetHeaderContents(path, define, version): | 105 def GetHeaderContents(path, define, version): |
113 """ | 106 """ |
114 Returns what the contents of the header file should be that indicate the given | 107 Returns what the contents of the header file should be that indicate the given |
115 revision. Note that the #define is specified as a string, even though it's | 108 revision. |
116 currently always a SVN revision number, in case we need to move to git hashes. | |
117 """ | 109 """ |
118 header_guard = GetHeaderGuard(path) | 110 header_guard = GetHeaderGuard(path) |
119 | 111 |
120 header_contents = """/* Generated by lastchange.py, do not edit.*/ | 112 header_contents = """/* Generated by lastchange.py, do not edit.*/ |
121 | 113 |
122 #ifndef %(header_guard)s | 114 #ifndef %(header_guard)s |
123 #define %(header_guard)s | 115 #define %(header_guard)s |
124 | 116 |
125 #define %(define)s "%(version)s" | 117 #define %(define)s "%(version)s" |
126 | 118 |
(...skipping 30 matching lines...) Expand all Loading... |
157 help="Name of C #define when using --header. Defaults to " + | 149 help="Name of C #define when using --header. Defaults to " + |
158 "LAST_CHANGE.", | 150 "LAST_CHANGE.", |
159 default="LAST_CHANGE") | 151 default="LAST_CHANGE") |
160 parser.add_option("-o", "--output", metavar="FILE", | 152 parser.add_option("-o", "--output", metavar="FILE", |
161 help="Write last change to FILE. " + | 153 help="Write last change to FILE. " + |
162 "Can be combined with --header to write both files.") | 154 "Can be combined with --header to write both files.") |
163 parser.add_option("", "--header", metavar="FILE", | 155 parser.add_option("", "--header", metavar="FILE", |
164 help="Write last change to FILE as a C/C++ header. " + | 156 help="Write last change to FILE as a C/C++ header. " + |
165 "Can be combined with --output to write both files.") | 157 "Can be combined with --output to write both files.") |
166 parser.add_option("--revision-only", action='store_true', | 158 parser.add_option("--revision-only", action='store_true', |
167 help="Just print the SVN revision number. Overrides any " + | 159 help="Just print the GIT hash. Overrides any " + |
168 "file-output-related options.") | 160 "file-output-related options.") |
169 parser.add_option("-s", "--source-dir", metavar="DIR", | 161 parser.add_option("-s", "--source-dir", metavar="DIR", |
170 help="Use repository in the given directory.") | 162 help="Use repository in the given directory.") |
171 opts, args = parser.parse_args(argv[1:]) | 163 opts, args = parser.parse_args(argv[1:]) |
172 | 164 |
173 out_file = opts.output | 165 out_file = opts.output |
174 header = opts.header | 166 header = opts.header |
175 | 167 |
176 while len(args) and out_file is None: | 168 while len(args) and out_file is None: |
177 if out_file is None: | 169 if out_file is None: |
(...skipping 25 matching lines...) Expand all Loading... |
203 if header: | 195 if header: |
204 WriteIfChanged(header, | 196 WriteIfChanged(header, |
205 GetHeaderContents(header, opts.version_macro, | 197 GetHeaderContents(header, opts.version_macro, |
206 version_info.revision)) | 198 version_info.revision)) |
207 | 199 |
208 return 0 | 200 return 0 |
209 | 201 |
210 | 202 |
211 if __name__ == '__main__': | 203 if __name__ == '__main__': |
212 sys.exit(main()) | 204 sys.exit(main()) |
OLD | NEW |