Commit cd0e1d01 authored by Maksim Ivanov's avatar Maksim Ivanov Committed by Commit Bot

Revert "Reland: "Add --merge-base-ref option to lastchange.py""

This reverts commit 5f2e9a96.

Reason for revert: gclient sync fails with the following error:

  ________ running '/usr/bin/python src/build/util/lastchange.py -o src/build/util/LASTCHANGE' in '/mnt/sdd/chrome'
  ERROR:root:Failed to get version info: %s

Original change's description:
> Reland: "Add --merge-base-ref option to lastchange.py"
> 
> Reland commit f4f6c5ff
> Revert was 172ccc05
> 
> The previous attempt at a reland changed FetchGitRevision
> which caused breakage when
> chrome/test/chromedriver/embed_version_in_cpp.py attempted to call this
> function. https://crrev.com/c/1459921 was recently merged which
> completely removed embed_version_in_cpp.py which should allow
> this change to re-land without modification from the previous
> attempt at a reland.
> 
> Change-Id: I0dbd7436938ae27167a9381415277d95d0d8312f
> Bug: 917159
> Reviewed-on: https://chromium-review.googlesource.com/c/1460454
> Reviewed-by: Dirk Pranke <dpranke@chromium.org>
> Reviewed-by: Andrii Shyshkalov <tandrii@chromium.org>
> Commit-Queue: Eli Ribble <eliribble@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#633730}

TBR=dpranke@chromium.org,tandrii@chromium.org,eliribble@chromium.org

Change-Id: Ia644ba3b8fe50b38fec26959a298f0d269fa54c9
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 917159
Reviewed-on: https://chromium-review.googlesource.com/c/1479950Reviewed-by: default avatarMaksim Ivanov <emaxx@chromium.org>
Commit-Queue: Maksim Ivanov <emaxx@chromium.org>
Cr-Commit-Position: refs/heads/master@{#633886}
parent 08dbcae9
......@@ -7,23 +7,20 @@
lastchange.py -- Chromium revision fetching utility.
"""
import argparse
import collections
import re
import logging
import argparse
import os
import subprocess
import sys
VersionInfo = collections.namedtuple("VersionInfo",
("revision_id", "revision", "timestamp"))
class VersionInfo(object):
def __init__(self, revision_id, full_revision_string, timestamp):
self.revision_id = revision_id
self.revision = full_revision_string
self.timestamp = timestamp
class GitError(Exception):
pass
# This function exists for compatibility with logic outside this
# repository that uses this file as a library.
# TODO(eliribble) remove this function after it has been ported into
# the repositories that depend on it
def RunGitCommand(directory, command):
"""
Launches git subcommand.
......@@ -52,95 +49,53 @@ def RunGitCommand(directory, command):
return None
def _RunGitCommand(directory, command):
"""Launches git subcommand.
Returns:
The stripped stdout of the git command.
Raises:
GitError on failure, including a nonzero return code.
def FetchGitRevision(directory, git_log_filter):
"""
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:
logging.info("Executing '%s' in %s", ' '.join(command), directory)
proc = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
cwd=directory,
shell=(sys.platform=='win32'))
stdout, stderr = proc.communicate()
stdout = stdout.strip()
logging.debug("returncode: %d", proc.returncode)
logging.debug("stdout: %s", stdout)
logging.debug("stderr: %s", stderr)
if proc.returncode != 0 or not stdout:
raise GitError((
"Git command 'git {}' in {} failed: "
"rc={}, stdout='{}' stderr='{}'").format(
" ".join(command), directory, proc.returncode, stdout, stderr))
return stdout
except OSError as e:
raise GitError("Git command 'git {}' in {} failed: {}".format(
" ".join(command), directory, e))
Fetch the Git hash (and Cr-Commit-Position if any) for a given directory.
def GetMergeBase(directory, ref):
"""
Return the merge-base of HEAD and ref.
Errors are swallowed.
Args:
directory: The directory containing the .git directory.
ref: The ref to use to find the merge base.
Returns:
The git commit SHA of the merge-base as a string.
"""
logging.debug("Calculating merge base between HEAD and %s in %s",
ref, directory)
command = ['merge-base', 'HEAD', ref]
return _RunGitCommand(directory, command)
git_log_filter: a string to be used for filtering git log result.
def FetchGitRevision(directory, commit_filter, start_commit="HEAD"):
"""
Fetch the Git hash (and Cr-Commit-Position if any) for a given directory.
Args:
directory: The directory containing the .git directory.
commit_filter: A filter to supply to grep to filter commits
start_commit: A commit identifier. The result of this function
will be limited to only consider commits before the provided
commit.
Returns:
A VersionInfo object. On error all values will be 0.
A VersionInfo object or None on error.
"""
hash_ = ''
hsh = ''
git_args = ['log', '-1', '--format=%H %ct']
if commit_filter is not None:
git_args.append('--grep=' + commit_filter)
git_args.append(start_commit)
output = _RunGitCommand(directory, git_args)
hash_, commit_timestamp = output.split()
if not hash_:
return VersionInfo('0', '0', 0)
revision = hash_
output = _RunGitCommand(directory, ['cat-file', 'commit', hash_])
for line in reversed(output.splitlines()):
if line.startswith('Cr-Commit-Position:'):
pos = line.rsplit()[-1].strip()
logging.debug("Found Cr-Commit-Position '%s'", pos)
revision = "{}-{}".format(hash_, pos)
break
return VersionInfo(hash_, revision, int(commit_timestamp))
if git_log_filter is not None:
git_args.append('--grep=' + git_log_filter)
proc = RunGitCommand(directory, git_args)
if proc:
output = proc.communicate()[0].strip()
if proc.returncode == 0 and output:
hsh, ct = output.split()
else:
logging.error('Git error: rc=%d, output=%r' %
(proc.returncode, output))
if not hsh:
return None
pos = ''
proc = RunGitCommand(directory, ['cat-file', 'commit', hsh])
if proc:
output = proc.communicate()[0]
if proc.returncode == 0 and output:
for line in reversed(output.splitlines()):
if line.startswith('Cr-Commit-Position:'):
pos = line.rsplit()[-1].strip()
break
return VersionInfo(hsh, '%s-%s' % (hsh, pos), int(ct))
def FetchVersionInfo(directory=None, git_log_filter=None):
"""
Returns the last change (as a VersionInfo object)
from some appropriate revision control system.
"""
version_info = FetchGitRevision(directory, git_log_filter)
if not version_info:
version_info = VersionInfo('0', '0', 0)
return version_info
def GetHeaderGuard(path):
......@@ -181,17 +136,6 @@ def GetHeaderContents(path, define, version):
return header_contents
def GetGitTopDirectory(source_dir):
"""Get the top git directory - the directory that contains the .git directory.
Args:
source_dir: The directory to search.
Returns:
The output of "git rev-parse --show-toplevel" as a string
"""
return _RunGitCommand(source_dir, ['rev-parse', '--show-toplevel'])
def WriteIfChanged(file_name, contents):
"""
Writes the specified contents to the specified file_name
......@@ -216,23 +160,20 @@ def main(argv=None):
parser = argparse.ArgumentParser(usage="lastchange.py [options]")
parser.add_argument("-m", "--version-macro",
help=("Name of C #define when using --header. Defaults to "
"LAST_CHANGE."))
help="Name of C #define when using --header. Defaults to " +
"LAST_CHANGE.",
default="LAST_CHANGE")
parser.add_argument("-o", "--output", metavar="FILE",
help=("Write last change to FILE. "
"Can be combined with --header to write both files."))
help="Write last change to FILE. " +
"Can be combined with --header to write both files.")
parser.add_argument("--header", metavar="FILE",
help=("Write last change to FILE as a C/C++ header. "
"Can be combined with --output to write both files."))
parser.add_argument("--merge-base-ref",
default=None,
help=("Only consider changes since the merge "
"base between HEAD and the provided ref"))
parser.add_argument("--revision-id-only", action='store_true',
help=("Output the revision as a VCS revision ID only (in "
"Git, a 40-character commit hash, excluding the "
"Cr-Commit-Position)."))
parser.add_argument("--print-only", action="store_true",
parser.add_argument("--print-only", action='store_true',
help=("Just print the revision string. Overrides any "
"file-output-related options."))
parser.add_argument("-s", "--source-dir", metavar="DIR",
......@@ -242,14 +183,13 @@ def main(argv=None):
"matches the supplied filter regex. Defaults to "
"'^Change-Id:' to suppress local commits."),
default='^Change-Id:')
args, extras = parser.parse_known_args(argv[1:])
logging.basicConfig(level=logging.WARNING)
out_file = args.output
header = args.header
commit_filter=args.filter
git_log_filter=args.filter
while len(extras) and out_file is None:
if out_file is None:
......@@ -259,37 +199,19 @@ def main(argv=None):
parser.print_help()
sys.exit(2)
source_dir = args.source_dir or os.path.dirname(os.path.abspath(__file__))
try:
git_top_dir = GetGitTopDirectory(source_dir)
except GitError as e:
logging.error("Failed to get git top directory from '%s': %s",
source_dir, e)
return 2
if args.merge_base_ref:
try:
merge_base_sha = GetMergeBase(git_top_dir, args.merge_base_ref)
except GitError as e:
logging.error("You requested a --merge-base-ref value of '%s' but no "
"merge base could be found between it and HEAD. Git "
"reports: %s", args.merge_base_ref, e)
return 3
if args.source_dir:
src_dir = args.source_dir
else:
merge_base_sha = 'HEAD'
try:
version_info = FetchGitRevision(git_top_dir, commit_filter, merge_base_sha)
except GitError as e:
logging.error("Failed to get version info: %s")
return 1
src_dir = os.path.dirname(os.path.abspath(__file__))
version_info = FetchVersionInfo(directory=src_dir,
git_log_filter=git_log_filter)
revision_string = version_info.revision
if args.revision_id_only:
revision_string = version_info.revision_id
if args.print_only:
print(revision_string)
print revision_string
else:
contents = "LASTCHANGE=%s\n" % revision_string
if not out_file and not args.header:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment