Index: tools/gn/last_commit_position.py |
diff --git a/tools/gn/last_commit_position.py b/tools/gn/last_commit_position.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e25bd00489255d1541d766250b4a011825587375 |
--- /dev/null |
+++ b/tools/gn/last_commit_position.py |
@@ -0,0 +1,101 @@ |
+# 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(".") |
+if not value: |
+ print "Could not get last commit position." |
+ sys.exit(1) |
+ |
+WriteHeader(output_file, header_guard, value) |