summaryrefslogtreecommitdiffstats
path: root/build/util
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2011-06-09 11:47:42 +0100
committerKristian Monsen <kristianm@google.com>2011-06-29 14:33:03 +0100
commitdc0f95d653279beabeb9817299e2902918ba123e (patch)
tree32eb121cd532053a5b9cb0c390331349af8d6baa /build/util
parentba160cd4054d13d0cb0b1b46e61c3bed67095811 (diff)
downloadexternal_chromium-dc0f95d653279beabeb9817299e2902918ba123e.zip
external_chromium-dc0f95d653279beabeb9817299e2902918ba123e.tar.gz
external_chromium-dc0f95d653279beabeb9817299e2902918ba123e.tar.bz2
Merge Chromium at r11.0.696.0: Initial merge by git
Change-Id: I273dde2843af0839dfc08b419bb443fbd449532d
Diffstat (limited to 'build/util')
-rwxr-xr-xbuild/util/lastchange.py190
1 files changed, 159 insertions, 31 deletions
diff --git a/build/util/lastchange.py b/build/util/lastchange.py
index c7200f1..4d7a1fe 100755
--- a/build/util/lastchange.py
+++ b/build/util/lastchange.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python
-# Copyright (c) 2010 The Chromium Authors. All rights reserved.
+# Copyright (c) 2011 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.
@@ -7,6 +7,7 @@
lastchange.py -- Chromium revision fetching utility.
"""
+import re
import optparse
import os
import subprocess
@@ -18,38 +19,10 @@ class VersionInfo(object):
self.root = root
self.revision = revision
-def FetchGitRevision(directory):
- """
- Fetch the Git hash for the a given directory.
-
- Errors are swallowed.
-
- Returns:
- a VersionInfo object or None on error.
- """
- # Force shell usage under cygwin & win32. 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.
- command = ['git', 'rev-parse', 'HEAD']
- if sys.platform in ('cygwin', 'win32'):
- command = ['sh', '-c', ' '.join(command)]
- try:
- proc = subprocess.Popen(command,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- cwd=directory)
- except OSError:
- return None
- output = proc.communicate()[0].strip()
- if proc.returncode == 0 and output:
- return VersionInfo('git', 'git', output[:7])
- return None
-
def FetchSVNRevision(directory):
"""
- Fetch the Subversion branch and revision for the a given directory.
+ Fetch the Subversion branch and revision for a given directory.
Errors are swallowed.
@@ -86,12 +59,167 @@ def FetchSVNRevision(directory):
return VersionInfo(url, root, revision)
+def RunGitCommand(directory, command):
+ """
+ Launches git subcommand.
+
+ Errors are swallowed.
+
+ Returns:
+ process object or None.
+ """
+ command = ['git'] + command
+ # Force shell usage under cygwin & win32. 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 in ('cygwin', 'win32'):
+ command = ['sh', '-c', ' '.join(command)]
+ try:
+ proc = subprocess.Popen(command,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ cwd=directory)
+ return proc
+ except OSError:
+ return None
+
+
+def FetchGitRevision(directory):
+ """
+ Fetch the Git hash for a given directory.
+
+ Errors are swallowed.
+
+ Returns:
+ a VersionInfo object or None on error.
+ """
+ proc = RunGitCommand(directory, ['rev-parse', 'HEAD'])
+ if proc:
+ output = proc.communicate()[0].strip()
+ if proc.returncode == 0 and output:
+ return VersionInfo('git', 'git', output[:7])
+ return None
+
+
+def IsGitSVN(directory):
+ """
+ Checks whether git-svn has been set up.
+
+ Errors are swallowed.
+
+ Returns:
+ whether git-svn has been set up.
+ """
+ # To test whether git-svn has been set up, query the config for any
+ # svn-related configuration. This command exits with an error code
+ # if there aren't any matches, so ignore its output.
+ proc = RunGitCommand(directory, ['config', '--get-regexp', '^svn'])
+ if proc:
+ return (proc.wait() == 0)
+ return False
+
+
+def FetchGitSVNURL(directory):
+ """
+ Fetch URL of SVN repository bound to git.
+
+ Errors are swallowed.
+
+ Returns:
+ SVN URL.
+ """
+ if IsGitSVN(directory):
+ proc = RunGitCommand(directory, ['svn', 'info', '--url'])
+ if proc:
+ output = proc.communicate()[0].strip()
+ if proc.returncode == 0:
+ match = re.search(r'^\w+://.*$', output, re.M)
+ if match:
+ return match.group(0)
+ return ''
+
+
+def FetchGitSVNRoot(directory):
+ """
+ Fetch root of SVN repository bound to git.
+
+ Errors are swallowed.
+
+ Returns:
+ SVN root repository.
+ """
+ if IsGitSVN(directory):
+ git_command = ['config', '--get-regexp', '^svn-remote.svn.url$']
+ proc = RunGitCommand(directory, git_command)
+ if proc:
+ output = proc.communicate()[0].strip()
+ if proc.returncode == 0:
+ # Zero return code implies presence of requested configuration variable.
+ # Its value is second (last) field of output.
+ match = re.search(r'\S+$', output)
+ if match:
+ return match.group(0)
+ return ''
+
+
+def LookupGitSVNRevision(directory, depth):
+ """
+ Fetch the Git-SVN identifier for the local tree.
+ Parses first |depth| commit messages.
+
+ Errors are swallowed.
+ """
+ if not IsGitSVN(directory):
+ return None
+ git_re = re.compile(r'^\s*git-svn-id:\s+(\S+)@(\d+)')
+ proc = RunGitCommand(directory, ['log', '-' + str(depth)])
+ if proc:
+ for line in proc.stdout:
+ match = git_re.match(line)
+ if match:
+ id = match.group(2)
+ if id:
+ proc.stdout.close() # Cut pipe for fast exit.
+ return id
+ return None
+
+
+def IsGitSVNDirty(directory):
+ """
+ Checks whether our git-svn tree contains clean trunk or some branch.
+
+ Errors are swallowed.
+ """
+ # For git branches the last commit message is either
+ # some local commit or a merge.
+ return LookupGitSVNRevision(directory, 1) is None
+
+
+def FetchGitSVNRevision(directory):
+ """
+ Fetch the Git-SVN identifier for the local tree.
+
+ Errors are swallowed.
+ """
+ # We assume that at least first 999 commit messages contain svn evidence.
+ revision = LookupGitSVNRevision(directory, 999)
+ if not revision:
+ return None
+ if IsGitSVNDirty(directory):
+ revision = revision + '-dirty'
+ url = FetchGitSVNURL(directory)
+ root = FetchGitSVNRoot(directory)
+ return VersionInfo(url, root, revision)
+
+
def FetchVersionInfo(default_lastchange, directory=None):
"""
Returns the last change (in the form of a branch, revision tuple),
from some appropriate revision control system.
"""
- version_info = FetchSVNRevision(directory) or FetchGitRevision(directory)
+ version_info = (FetchSVNRevision(directory) or
+ FetchGitSVNRevision(directory) or FetchGitRevision(directory))
if not version_info:
if default_lastchange and os.path.exists(default_lastchange):
revision = open(default_lastchange, 'r').read().strip()