| # Copyright 2014 The Chromium Authors. All rights reserved. | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| """Writes the most recent "Cr-Commit-Position" value on the master branch | |
| to a C header file. | |
| Usage: last_commit_position.py <dir> <outfile> <headerguard> | |
| <dir> | |
| Some directory inside the repo to check. This will be used as the current | |
| directory when running git. It's best to pass the repo toplevel directory. | |
| <outfile> | |
| C header file to write. | |
| <headerguard> | |
| String to use as the header guard for the written file. | |
| """ | |
| import os | |
| import re | |
| import subprocess | |
| import sys | |
| def RunGitCommand(directory, command): | |
| """ | |
| Launches git subcommand. | |
| Errors are swallowed. | |
| Returns: | |
| A process object or None. | |
| """ | |
| command = ['git'] + command | |
| # Force shell usage under cygwin. This is a workaround for | |
| # mysterious loss of cwd while invoking cygwin's git. | |
| # We can't just pass shell=True to Popen, as under win32 this will | |
| # cause CMD to be used, while we explicitly want a cygwin shell. | |
| if sys.platform == 'cygwin': | |
| command = ['sh', '-c', ' '.join(command)] | |
| try: | |
| proc = subprocess.Popen(command, | |
| stdout=subprocess.PIPE, | |
| stderr=subprocess.PIPE, | |
| cwd=directory, | |
| shell=(sys.platform=='win32')) | |
| return proc | |
| except OSError: | |
| return None | |
| def FetchCommitPosition(directory): | |
| regex = re.compile(r'\s*Cr-Commit-Position: refs/heads/master@\{#(\d+)\}\s*') | |
| # Search this far backward in the git log. The commit position should be | |
| # close to the top. We allow some slop for long commit messages, and maybe | |
| # there were some local commits after the last "official" one. Having this | |
| # max prevents us from searching all history in the case of an error. | |
| max_lines = 2048 | |
| proc = RunGitCommand(directory, ['log']) | |
| for i in range(max_lines): | |
| line = proc.stdout.readline() | |
| if not line: | |
| return None | |
| match = regex.match(line) | |
| if match: | |
| return match.group(1) | |
| return None | |
| def WriteHeader(header_file, header_guard, value): | |
| with open(header_file, 'w') as f: | |
| f.write('''/* Generated by last_commit_position.py. */ | |
| #ifndef %(guard)s | |
| #define %(guard)s | |
| #define LAST_COMMIT_POSITION "%(value)s" | |
| #endif | |
| ''' % {'guard': header_guard, 'value': value}) | |
| if len(sys.argv) != 4: | |
| print "Wrong number of arguments" | |
| sys.exit(1) | |
| git_directory = sys.argv[1] | |
| output_file = sys.argv[2] | |
| header_guard = sys.argv[3] | |
| value = FetchCommitPosition(git_directory) | |
| if not value: | |
| value = 'UNKNOWN' | |
| WriteHeader(output_file, header_guard, value) |