| 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 |