Chromium Code Reviews| 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 |