# 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
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.
C header file to write.
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:
print "Could not get last commit position."
sys.exit(1)
WriteHeader(output_file, header_guard, value)