[release] Remove logic for handling the ChangeLog
https://v8.dev/blog/tags/release is the new ChangeLog! This also removes an unused file push_to_candidate.py which wasn't deleted earlier as it's intertwined a lot in test cases. This CL also cleans that up. Furthermore, logic for selecting CLs for the ChangeLog (using LOG= lines) is removed as well. Nobody has used this feature for more than 5 release cycles. We'll delete the ChangeLog file in a separate CL. Bug: v8:10010 No-Try: true Change-Id: Idee551dc0600c3df9f784cc543897e3e18517ca1 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1930616 Reviewed-by: Tamer Tas <tmrts@chromium.org> Commit-Queue: Michael Achenbach <machenbach@chromium.org> Cr-Commit-Position: refs/heads/master@{#65191}
This commit is contained in:
parent
a0b1a9cd10
commit
2e9251bc61
@ -48,7 +48,6 @@ import urllib2
|
||||
from git_recipes import GitRecipesMixin
|
||||
from git_recipes import GitFailedException
|
||||
|
||||
CHANGELOG_FILE = "ChangeLog"
|
||||
DAY_IN_SECONDS = 24 * 60 * 60
|
||||
PUSH_MSG_GIT_RE = re.compile(r".* \(based on (?P<git_rev>[a-fA-F0-9]+)\)$")
|
||||
PUSH_MSG_NEW_RE = re.compile(r"^Version \d+\.\d+\.\d+$")
|
||||
@ -93,99 +92,6 @@ def MSub(rexp, replacement, text):
|
||||
return re.sub(rexp, replacement, text, flags=re.MULTILINE)
|
||||
|
||||
|
||||
def Fill80(line):
|
||||
# Replace tabs and remove surrounding space.
|
||||
line = re.sub(r"\t", r" ", line.strip())
|
||||
|
||||
# Format with 8 characters indentation and line width 80.
|
||||
return textwrap.fill(line, width=80, initial_indent=" ",
|
||||
subsequent_indent=" ")
|
||||
|
||||
|
||||
def MakeComment(text):
|
||||
return MSub(r"^( ?)", "#", text)
|
||||
|
||||
|
||||
def StripComments(text):
|
||||
# Use split not splitlines to keep terminal newlines.
|
||||
return "\n".join(filter(lambda x: not x.startswith("#"), text.split("\n")))
|
||||
|
||||
|
||||
def MakeChangeLogBody(commit_messages, auto_format=False):
|
||||
result = ""
|
||||
added_titles = set()
|
||||
for (title, body, author) in commit_messages:
|
||||
# TODO(machenbach): Better check for reverts. A revert should remove the
|
||||
# original CL from the actual log entry.
|
||||
title = title.strip()
|
||||
if auto_format:
|
||||
# Only add commits that set the LOG flag correctly.
|
||||
log_exp = r"^[ \t]*LOG[ \t]*=[ \t]*(?:(?:Y(?:ES)?)|TRUE)"
|
||||
if not re.search(log_exp, body, flags=re.I | re.M):
|
||||
continue
|
||||
# Never include reverts.
|
||||
if title.startswith("Revert "):
|
||||
continue
|
||||
# Don't include duplicates.
|
||||
if title in added_titles:
|
||||
continue
|
||||
|
||||
# Add and format the commit's title and bug reference. Move dot to the end.
|
||||
added_titles.add(title)
|
||||
raw_title = re.sub(r"(\.|\?|!)$", "", title)
|
||||
bug_reference = MakeChangeLogBugReference(body)
|
||||
space = " " if bug_reference else ""
|
||||
result += "%s\n" % Fill80("%s%s%s." % (raw_title, space, bug_reference))
|
||||
|
||||
# Append the commit's author for reference if not in auto-format mode.
|
||||
if not auto_format:
|
||||
result += "%s\n" % Fill80("(%s)" % author.strip())
|
||||
|
||||
result += "\n"
|
||||
return result
|
||||
|
||||
|
||||
def MakeChangeLogBugReference(body):
|
||||
"""Grep for "BUG=xxxx" lines in the commit message and convert them to
|
||||
"(issue xxxx)".
|
||||
"""
|
||||
crbugs = []
|
||||
v8bugs = []
|
||||
|
||||
def AddIssues(text):
|
||||
ref = re.match(r"^BUG[ \t]*=[ \t]*(.+)$", text.strip())
|
||||
if not ref:
|
||||
return
|
||||
for bug in ref.group(1).split(","):
|
||||
bug = bug.strip()
|
||||
match = re.match(r"^v8:(\d+)$", bug)
|
||||
if match: v8bugs.append(int(match.group(1)))
|
||||
else:
|
||||
match = re.match(r"^(?:chromium:)?(\d+)$", bug)
|
||||
if match: crbugs.append(int(match.group(1)))
|
||||
|
||||
# Add issues to crbugs and v8bugs.
|
||||
map(AddIssues, body.splitlines())
|
||||
|
||||
# Filter duplicates, sort, stringify.
|
||||
crbugs = map(str, sorted(set(crbugs)))
|
||||
v8bugs = map(str, sorted(set(v8bugs)))
|
||||
|
||||
bug_groups = []
|
||||
def FormatIssues(prefix, bugs):
|
||||
if len(bugs) > 0:
|
||||
plural = "s" if len(bugs) > 1 else ""
|
||||
bug_groups.append("%sissue%s %s" % (prefix, plural, ", ".join(bugs)))
|
||||
|
||||
FormatIssues("", v8bugs)
|
||||
FormatIssues("Chromium ", crbugs)
|
||||
|
||||
if len(bug_groups) > 0:
|
||||
return "(%s)" % ", ".join(bug_groups)
|
||||
else:
|
||||
return ""
|
||||
|
||||
|
||||
def SortingKey(version):
|
||||
"""Key for sorting version number strings: '3.11' > '3.2.1.1'"""
|
||||
version_keys = map(int, version.split("."))
|
||||
@ -282,9 +188,6 @@ class SideEffectHandler(object): # pragma: no cover
|
||||
def Sleep(self, seconds):
|
||||
time.sleep(seconds)
|
||||
|
||||
def GetDate(self):
|
||||
return datetime.date.today().strftime("%Y-%m-%d")
|
||||
|
||||
def GetUTCStamp(self):
|
||||
return time.mktime(datetime.datetime.utcnow().timetuple())
|
||||
|
||||
@ -527,9 +430,6 @@ class Step(GitRecipesMixin):
|
||||
cmd = lambda: self._side_effect_handler.ReadURL(url, params)
|
||||
return self.Retry(cmd, retry_on, wait_plan)
|
||||
|
||||
def GetDate(self):
|
||||
return self._side_effect_handler.GetDate()
|
||||
|
||||
def Die(self, msg=""):
|
||||
if msg != "":
|
||||
print("Error: %s" % msg)
|
||||
|
@ -77,64 +77,6 @@ class DetectLastRelease(Step):
|
||||
self["last_push_master"] = self.GetLatestReleaseBase()
|
||||
|
||||
|
||||
class PrepareChangeLog(Step):
|
||||
MESSAGE = "Prepare raw ChangeLog entry."
|
||||
|
||||
def RunStep(self):
|
||||
self["date"] = self.GetDate()
|
||||
output = "%s: Version %s\n\n" % (self["date"], self["version"])
|
||||
TextToFile(output, self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
commits = self.GitLog(format="%H",
|
||||
git_hash="%s..%s" % (self["last_push_master"],
|
||||
self["push_hash"]))
|
||||
|
||||
# Cache raw commit messages.
|
||||
commit_messages = [
|
||||
[
|
||||
self.GitLog(n=1, format="%s", git_hash=commit),
|
||||
self.GitLog(n=1, format="%B", git_hash=commit),
|
||||
self.GitLog(n=1, format="%an", git_hash=commit),
|
||||
] for commit in commits.splitlines()
|
||||
]
|
||||
|
||||
# Auto-format commit messages.
|
||||
body = MakeChangeLogBody(commit_messages, auto_format=True)
|
||||
AppendToFile(body, self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
|
||||
msg = (" Performance and stability improvements on all platforms."
|
||||
"\n#\n# The change log above is auto-generated. Please review if "
|
||||
"all relevant\n# commit messages from the list below are included."
|
||||
"\n# All lines starting with # will be stripped.\n#\n")
|
||||
AppendToFile(msg, self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
|
||||
# Include unformatted commit messages as a reference in a comment.
|
||||
comment_body = MakeComment(MakeChangeLogBody(commit_messages))
|
||||
AppendToFile(comment_body, self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
|
||||
|
||||
class EditChangeLog(Step):
|
||||
MESSAGE = "Edit ChangeLog entry."
|
||||
|
||||
def RunStep(self):
|
||||
print ("Please press <Return> to have your EDITOR open the ChangeLog "
|
||||
"entry, then edit its contents to your liking. When you're done, "
|
||||
"save the file and exit your EDITOR. ")
|
||||
self.ReadLine(default="")
|
||||
self.Editor(self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
|
||||
# Strip comments and reformat with correct indentation.
|
||||
changelog_entry = FileToText(self.Config("CHANGELOG_ENTRY_FILE")).rstrip()
|
||||
changelog_entry = StripComments(changelog_entry)
|
||||
changelog_entry = "\n".join(map(Fill80, changelog_entry.splitlines()))
|
||||
changelog_entry = changelog_entry.lstrip()
|
||||
|
||||
if changelog_entry == "": # pragma: no cover
|
||||
self.Die("Empty ChangeLog entry.")
|
||||
|
||||
# Safe new change log for adding it later to the candidates patch.
|
||||
TextToFile(changelog_entry, self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
|
||||
|
||||
class DeleteBranchRef(Step):
|
||||
MESSAGE = "Delete branch ref."
|
||||
|
||||
@ -167,20 +109,9 @@ class MakeBranch(Step):
|
||||
def RunStep(self):
|
||||
self.Git("reset --hard origin/master")
|
||||
self.Git("new-branch work-branch --upstream origin/%s" % self["version"])
|
||||
self.GitCheckoutFile(CHANGELOG_FILE, self["latest_version"])
|
||||
self.GitCheckoutFile(VERSION_FILE, self["latest_version"])
|
||||
|
||||
|
||||
class AddChangeLog(Step):
|
||||
MESSAGE = "Add ChangeLog changes to release branch."
|
||||
|
||||
def RunStep(self):
|
||||
changelog_entry = FileToText(self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
old_change_log = FileToText(os.path.join(self.default_cwd, CHANGELOG_FILE))
|
||||
new_change_log = "%s\n\n\n%s" % (changelog_entry, old_change_log)
|
||||
TextToFile(new_change_log, os.path.join(self.default_cwd, CHANGELOG_FILE))
|
||||
|
||||
|
||||
class SetVersion(Step):
|
||||
MESSAGE = "Set correct version for candidates."
|
||||
|
||||
@ -202,30 +133,14 @@ class EnableMergeWatchlist(Step):
|
||||
|
||||
|
||||
class CommitBranch(Step):
|
||||
MESSAGE = "Commit version and changelog to new branch."
|
||||
MESSAGE = "Commit version to new branch."
|
||||
|
||||
def RunStep(self):
|
||||
# Convert the ChangeLog entry to commit message format.
|
||||
text = FileToText(self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
|
||||
# Remove date and trailing white space.
|
||||
text = re.sub(r"^%s: " % self["date"], "", text.rstrip())
|
||||
|
||||
# Remove indentation and merge paragraphs into single long lines, keeping
|
||||
# empty lines between them.
|
||||
def SplitMapJoin(split_text, fun, join_text):
|
||||
return lambda text: join_text.join(map(fun, text.split(split_text)))
|
||||
text = SplitMapJoin(
|
||||
"\n\n", SplitMapJoin("\n", str.strip, " "), "\n\n")(text)
|
||||
|
||||
if not text: # pragma: no cover
|
||||
self.Die("Commit message editing failed.")
|
||||
text += "\n\nTBR=%s" % self._options.reviewer
|
||||
self["commit_title"] = text.splitlines()[0]
|
||||
self["commit_title"] = "Version %s" % self["version"]
|
||||
text = "%s\n\nTBR=%s" % (self["commit_title"], self._options.reviewer)
|
||||
TextToFile(text, self.Config("COMMITMSG_FILE"))
|
||||
|
||||
self.GitCommit(file_name=self.Config("COMMITMSG_FILE"))
|
||||
os.remove(self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
|
||||
|
||||
class LandBranch(Step):
|
||||
@ -294,8 +209,6 @@ class CreateRelease(ScriptsBase):
|
||||
def _Config(self):
|
||||
return {
|
||||
"PERSISTFILE_BASENAME": "/tmp/create-releases-tempfile",
|
||||
"CHANGELOG_ENTRY_FILE":
|
||||
"/tmp/v8-create-releases-tempfile-changelog-entry",
|
||||
"COMMITMSG_FILE": "/tmp/v8-create-releases-tempfile-commitmsg",
|
||||
}
|
||||
|
||||
@ -305,12 +218,9 @@ class CreateRelease(ScriptsBase):
|
||||
PrepareBranchRevision,
|
||||
IncrementVersion,
|
||||
DetectLastRelease,
|
||||
PrepareChangeLog,
|
||||
EditChangeLog,
|
||||
DeleteBranchRef,
|
||||
PushBranchRef,
|
||||
MakeBranch,
|
||||
AddChangeLog,
|
||||
SetVersion,
|
||||
EnableMergeWatchlist,
|
||||
CommitBranch,
|
||||
|
@ -145,7 +145,7 @@ class CreateCommitMessage(Step):
|
||||
if bug_aggregate:
|
||||
# TODO(machenbach): Use proper gerrit footer for bug after switch to
|
||||
# gerrit. Keep BUG= for now for backwards-compatibility.
|
||||
msg_pieces.append("BUG=%s\nLOG=N\n" % bug_aggregate)
|
||||
msg_pieces.append("BUG=%s\n" % bug_aggregate)
|
||||
|
||||
msg_pieces.append("NOTRY=true\nNOPRESUBMIT=true\nNOTREECHECKS=true\n")
|
||||
|
||||
|
@ -1,400 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2013 the V8 project authors. All rights reserved.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# for py2/py3 compatibility
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import urllib2
|
||||
|
||||
from common_includes import *
|
||||
|
||||
PUSH_MSG_GIT_SUFFIX = " (based on %s)"
|
||||
|
||||
|
||||
class Preparation(Step):
|
||||
MESSAGE = "Preparation."
|
||||
|
||||
def RunStep(self):
|
||||
self.InitialEnvironmentChecks(self.default_cwd)
|
||||
self.CommonPrepare()
|
||||
|
||||
if(self["current_branch"] == self.Config("CANDIDATESBRANCH")
|
||||
or self["current_branch"] == self.Config("BRANCHNAME")):
|
||||
print("Warning: Script started on branch %s" % self["current_branch"])
|
||||
|
||||
self.PrepareBranch()
|
||||
self.DeleteBranch(self.Config("CANDIDATESBRANCH"))
|
||||
|
||||
|
||||
class FreshBranch(Step):
|
||||
MESSAGE = "Create a fresh branch."
|
||||
|
||||
def RunStep(self):
|
||||
self.GitCreateBranch(self.Config("BRANCHNAME"),
|
||||
self.vc.RemoteMasterBranch())
|
||||
|
||||
|
||||
class PreparePushRevision(Step):
|
||||
MESSAGE = "Check which revision to push."
|
||||
|
||||
def RunStep(self):
|
||||
if self._options.revision:
|
||||
self["push_hash"] = self._options.revision
|
||||
else:
|
||||
self["push_hash"] = self.GitLog(n=1, format="%H", git_hash="HEAD")
|
||||
if not self["push_hash"]: # pragma: no cover
|
||||
self.Die("Could not determine the git hash for the push.")
|
||||
|
||||
|
||||
class IncrementVersion(Step):
|
||||
MESSAGE = "Increment version number."
|
||||
|
||||
def RunStep(self):
|
||||
latest_version = self.GetLatestVersion()
|
||||
|
||||
# The version file on master can be used to bump up major/minor at
|
||||
# branch time.
|
||||
self.GitCheckoutFile(VERSION_FILE, self.vc.RemoteMasterBranch())
|
||||
self.ReadAndPersistVersion("master_")
|
||||
master_version = self.ArrayToVersion("master_")
|
||||
|
||||
# Use the highest version from master or from tags to determine the new
|
||||
# version.
|
||||
authoritative_version = sorted(
|
||||
[master_version, latest_version], key=SortingKey)[1]
|
||||
self.StoreVersion(authoritative_version, "authoritative_")
|
||||
|
||||
# Variables prefixed with 'new_' contain the new version numbers for the
|
||||
# ongoing candidates push.
|
||||
self["new_major"] = self["authoritative_major"]
|
||||
self["new_minor"] = self["authoritative_minor"]
|
||||
self["new_build"] = str(int(self["authoritative_build"]) + 1)
|
||||
|
||||
# Make sure patch level is 0 in a new push.
|
||||
self["new_patch"] = "0"
|
||||
|
||||
self["version"] = "%s.%s.%s" % (self["new_major"],
|
||||
self["new_minor"],
|
||||
self["new_build"])
|
||||
|
||||
print ("Incremented version to %s" % self["version"])
|
||||
|
||||
|
||||
class DetectLastRelease(Step):
|
||||
MESSAGE = "Detect commit ID of last release base."
|
||||
|
||||
def RunStep(self):
|
||||
if self._options.last_master:
|
||||
self["last_push_master"] = self._options.last_master
|
||||
else:
|
||||
self["last_push_master"] = self.GetLatestReleaseBase()
|
||||
|
||||
|
||||
class PrepareChangeLog(Step):
|
||||
MESSAGE = "Prepare raw ChangeLog entry."
|
||||
|
||||
def RunStep(self):
|
||||
self["date"] = self.GetDate()
|
||||
output = "%s: Version %s\n\n" % (self["date"], self["version"])
|
||||
TextToFile(output, self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
commits = self.GitLog(format="%H",
|
||||
git_hash="%s..%s" % (self["last_push_master"],
|
||||
self["push_hash"]))
|
||||
|
||||
# Cache raw commit messages.
|
||||
commit_messages = [
|
||||
[
|
||||
self.GitLog(n=1, format="%s", git_hash=commit),
|
||||
self.GitLog(n=1, format="%B", git_hash=commit),
|
||||
self.GitLog(n=1, format="%an", git_hash=commit),
|
||||
] for commit in commits.splitlines()
|
||||
]
|
||||
|
||||
# Auto-format commit messages.
|
||||
body = MakeChangeLogBody(commit_messages, auto_format=True)
|
||||
AppendToFile(body, self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
|
||||
msg = (" Performance and stability improvements on all platforms."
|
||||
"\n#\n# The change log above is auto-generated. Please review if "
|
||||
"all relevant\n# commit messages from the list below are included."
|
||||
"\n# All lines starting with # will be stripped.\n#\n")
|
||||
AppendToFile(msg, self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
|
||||
# Include unformatted commit messages as a reference in a comment.
|
||||
comment_body = MakeComment(MakeChangeLogBody(commit_messages))
|
||||
AppendToFile(comment_body, self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
|
||||
|
||||
class EditChangeLog(Step):
|
||||
MESSAGE = "Edit ChangeLog entry."
|
||||
|
||||
def RunStep(self):
|
||||
print ("Please press <Return> to have your EDITOR open the ChangeLog "
|
||||
"entry, then edit its contents to your liking. When you're done, "
|
||||
"save the file and exit your EDITOR. ")
|
||||
self.ReadLine(default="")
|
||||
self.Editor(self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
|
||||
# Strip comments and reformat with correct indentation.
|
||||
changelog_entry = FileToText(self.Config("CHANGELOG_ENTRY_FILE")).rstrip()
|
||||
changelog_entry = StripComments(changelog_entry)
|
||||
changelog_entry = "\n".join(map(Fill80, changelog_entry.splitlines()))
|
||||
changelog_entry = changelog_entry.lstrip()
|
||||
|
||||
if changelog_entry == "": # pragma: no cover
|
||||
self.Die("Empty ChangeLog entry.")
|
||||
|
||||
# Safe new change log for adding it later to the candidates patch.
|
||||
TextToFile(changelog_entry, self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
|
||||
|
||||
class StragglerCommits(Step):
|
||||
MESSAGE = ("Fetch straggler commits that sneaked in since this script was "
|
||||
"started.")
|
||||
|
||||
def RunStep(self):
|
||||
self.vc.Fetch()
|
||||
self.GitCheckout(self.vc.RemoteMasterBranch())
|
||||
|
||||
|
||||
class SquashCommits(Step):
|
||||
MESSAGE = "Squash commits into one."
|
||||
|
||||
def RunStep(self):
|
||||
# Instead of relying on "git rebase -i", we'll just create a diff, because
|
||||
# that's easier to automate.
|
||||
TextToFile(self.GitDiff(self.vc.RemoteCandidateBranch(),
|
||||
self["push_hash"]),
|
||||
self.Config("PATCH_FILE"))
|
||||
|
||||
# Convert the ChangeLog entry to commit message format.
|
||||
text = FileToText(self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
|
||||
# Remove date and trailing white space.
|
||||
text = re.sub(r"^%s: " % self["date"], "", text.rstrip())
|
||||
|
||||
# Show the used master hash in the commit message.
|
||||
suffix = PUSH_MSG_GIT_SUFFIX % self["push_hash"]
|
||||
text = MSub(r"^(Version \d+\.\d+\.\d+)$", "\\1%s" % suffix, text)
|
||||
|
||||
# Remove indentation and merge paragraphs into single long lines, keeping
|
||||
# empty lines between them.
|
||||
def SplitMapJoin(split_text, fun, join_text):
|
||||
return lambda text: join_text.join(map(fun, text.split(split_text)))
|
||||
strip = lambda line: line.strip()
|
||||
text = SplitMapJoin("\n\n", SplitMapJoin("\n", strip, " "), "\n\n")(text)
|
||||
|
||||
if not text: # pragma: no cover
|
||||
self.Die("Commit message editing failed.")
|
||||
self["commit_title"] = text.splitlines()[0]
|
||||
TextToFile(text, self.Config("COMMITMSG_FILE"))
|
||||
|
||||
|
||||
class NewBranch(Step):
|
||||
MESSAGE = "Create a new branch from candidates."
|
||||
|
||||
def RunStep(self):
|
||||
self.GitCreateBranch(self.Config("CANDIDATESBRANCH"),
|
||||
self.vc.RemoteCandidateBranch())
|
||||
|
||||
|
||||
class ApplyChanges(Step):
|
||||
MESSAGE = "Apply squashed changes."
|
||||
|
||||
def RunStep(self):
|
||||
self.ApplyPatch(self.Config("PATCH_FILE"))
|
||||
os.remove(self.Config("PATCH_FILE"))
|
||||
# The change log has been modified by the patch. Reset it to the version
|
||||
# on candidates and apply the exact changes determined by this
|
||||
# PrepareChangeLog step above.
|
||||
self.GitCheckoutFile(CHANGELOG_FILE, self.vc.RemoteCandidateBranch())
|
||||
# The version file has been modified by the patch. Reset it to the version
|
||||
# on candidates.
|
||||
self.GitCheckoutFile(VERSION_FILE, self.vc.RemoteCandidateBranch())
|
||||
|
||||
|
||||
class CommitSquash(Step):
|
||||
MESSAGE = "Commit to local candidates branch."
|
||||
|
||||
def RunStep(self):
|
||||
# Make a first commit with a slightly different title to not confuse
|
||||
# the tagging.
|
||||
msg = FileToText(self.Config("COMMITMSG_FILE")).splitlines()
|
||||
msg[0] = msg[0].replace("(based on", "(squashed - based on")
|
||||
self.GitCommit(message = "\n".join(msg))
|
||||
|
||||
|
||||
class PrepareVersionBranch(Step):
|
||||
MESSAGE = "Prepare new branch to commit version and changelog file."
|
||||
|
||||
def RunStep(self):
|
||||
self.GitCheckout("master")
|
||||
self.Git("fetch")
|
||||
self.GitDeleteBranch(self.Config("CANDIDATESBRANCH"))
|
||||
self.GitCreateBranch(self.Config("CANDIDATESBRANCH"),
|
||||
self.vc.RemoteCandidateBranch())
|
||||
|
||||
|
||||
class AddChangeLog(Step):
|
||||
MESSAGE = "Add ChangeLog changes to candidates branch."
|
||||
|
||||
def RunStep(self):
|
||||
changelog_entry = FileToText(self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
old_change_log = FileToText(os.path.join(self.default_cwd, CHANGELOG_FILE))
|
||||
new_change_log = "%s\n\n\n%s" % (changelog_entry, old_change_log)
|
||||
TextToFile(new_change_log, os.path.join(self.default_cwd, CHANGELOG_FILE))
|
||||
os.remove(self.Config("CHANGELOG_ENTRY_FILE"))
|
||||
|
||||
|
||||
class SetVersion(Step):
|
||||
MESSAGE = "Set correct version for candidates."
|
||||
|
||||
def RunStep(self):
|
||||
self.SetVersion(os.path.join(self.default_cwd, VERSION_FILE), "new_")
|
||||
|
||||
|
||||
class CommitCandidate(Step):
|
||||
MESSAGE = "Commit version and changelog to local candidates branch."
|
||||
|
||||
def RunStep(self):
|
||||
self.GitCommit(file_name = self.Config("COMMITMSG_FILE"))
|
||||
os.remove(self.Config("COMMITMSG_FILE"))
|
||||
|
||||
|
||||
class SanityCheck(Step):
|
||||
MESSAGE = "Sanity check."
|
||||
|
||||
def RunStep(self):
|
||||
# TODO(machenbach): Run presubmit script here as it is now missing in the
|
||||
# prepare push process.
|
||||
if not self.Confirm("Please check if your local checkout is sane: Inspect "
|
||||
"%s, compile, run tests. Do you want to commit this new candidates "
|
||||
"revision to the repository?" % VERSION_FILE):
|
||||
self.Die("Execution canceled.") # pragma: no cover
|
||||
|
||||
|
||||
class Land(Step):
|
||||
MESSAGE = "Land the patch."
|
||||
|
||||
def RunStep(self):
|
||||
self.vc.CLLand()
|
||||
|
||||
|
||||
class TagRevision(Step):
|
||||
MESSAGE = "Tag the new revision."
|
||||
|
||||
def RunStep(self):
|
||||
self.vc.Tag(
|
||||
self["version"], self.vc.RemoteCandidateBranch(), self["commit_title"])
|
||||
|
||||
|
||||
class CleanUp(Step):
|
||||
MESSAGE = "Done!"
|
||||
|
||||
def RunStep(self):
|
||||
print("Congratulations, you have successfully created the candidates "
|
||||
"revision %s."
|
||||
% self["version"])
|
||||
|
||||
self.CommonCleanup()
|
||||
if self.Config("CANDIDATESBRANCH") != self["current_branch"]:
|
||||
self.GitDeleteBranch(self.Config("CANDIDATESBRANCH"))
|
||||
|
||||
|
||||
class PushToCandidates(ScriptsBase):
|
||||
def _PrepareOptions(self, parser):
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument("-f", "--force",
|
||||
help="Don't prompt the user.",
|
||||
default=False, action="store_true")
|
||||
group.add_argument("-m", "--manual",
|
||||
help="Prompt the user at every important step.",
|
||||
default=False, action="store_true")
|
||||
parser.add_argument("-b", "--last-master",
|
||||
help=("The git commit ID of the last master "
|
||||
"revision that was pushed to candidates. This is"
|
||||
" used for the auto-generated ChangeLog entry."))
|
||||
parser.add_argument("-l", "--last-push",
|
||||
help="The git commit ID of the last candidates push.")
|
||||
parser.add_argument("-R", "--revision",
|
||||
help="The git commit ID to push (defaults to HEAD).")
|
||||
|
||||
def _ProcessOptions(self, options): # pragma: no cover
|
||||
if not options.manual and not options.reviewer:
|
||||
print("A reviewer (-r) is required in (semi-)automatic mode.")
|
||||
return False
|
||||
if not options.manual and not options.author:
|
||||
print("Specify your chromium.org email with -a in (semi-)automatic mode.")
|
||||
return False
|
||||
|
||||
options.tbr_commit = not options.manual
|
||||
return True
|
||||
|
||||
def _Config(self):
|
||||
return {
|
||||
"BRANCHNAME": "prepare-push",
|
||||
"CANDIDATESBRANCH": "candidates-push",
|
||||
"PERSISTFILE_BASENAME": "/tmp/v8-push-to-candidates-tempfile",
|
||||
"CHANGELOG_ENTRY_FILE":
|
||||
"/tmp/v8-push-to-candidates-tempfile-changelog-entry",
|
||||
"PATCH_FILE": "/tmp/v8-push-to-candidates-tempfile-patch-file",
|
||||
"COMMITMSG_FILE": "/tmp/v8-push-to-candidates-tempfile-commitmsg",
|
||||
}
|
||||
|
||||
def _Steps(self):
|
||||
return [
|
||||
Preparation,
|
||||
FreshBranch,
|
||||
PreparePushRevision,
|
||||
IncrementVersion,
|
||||
DetectLastRelease,
|
||||
PrepareChangeLog,
|
||||
EditChangeLog,
|
||||
StragglerCommits,
|
||||
SquashCommits,
|
||||
NewBranch,
|
||||
ApplyChanges,
|
||||
CommitSquash,
|
||||
SanityCheck,
|
||||
Land,
|
||||
PrepareVersionBranch,
|
||||
AddChangeLog,
|
||||
SetVersion,
|
||||
CommitCandidate,
|
||||
Land,
|
||||
TagRevision,
|
||||
CleanUp,
|
||||
]
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
sys.exit(PushToCandidates().Run())
|
@ -129,7 +129,7 @@ class CreateCommitMessage(Step):
|
||||
bugs.extend(s.strip() for s in bug.split(","))
|
||||
bug_aggregate = ",".join(sorted(filter(lambda s: s and s != "none", bugs)))
|
||||
if bug_aggregate:
|
||||
msg_pieces.append("BUG=%s\nLOG=N\n" % bug_aggregate)
|
||||
msg_pieces.append("BUG=%s\n" % bug_aggregate)
|
||||
|
||||
self["new_commit_msg"] = "".join(msg_pieces)
|
||||
|
||||
|
@ -41,11 +41,9 @@ import auto_roll
|
||||
import common_includes
|
||||
from common_includes import *
|
||||
import create_release
|
||||
from create_release import CreateRelease
|
||||
from create_release import *
|
||||
import merge_to_branch
|
||||
from merge_to_branch import MergeToBranch
|
||||
import push_to_candidates
|
||||
from push_to_candidates import *
|
||||
from auto_tag import AutoTag
|
||||
import roll_merge
|
||||
from roll_merge import RollMerge
|
||||
@ -53,13 +51,10 @@ from roll_merge import RollMerge
|
||||
TEST_CONFIG = {
|
||||
"DEFAULT_CWD": None,
|
||||
"BRANCHNAME": "test-prepare-push",
|
||||
"CANDIDATESBRANCH": "test-candidates-push",
|
||||
"PERSISTFILE_BASENAME": "/tmp/test-v8-push-to-candidates-tempfile",
|
||||
"CHANGELOG_ENTRY_FILE":
|
||||
"/tmp/test-v8-push-to-candidates-tempfile-changelog-entry",
|
||||
"PATCH_FILE": "/tmp/test-v8-push-to-candidates-tempfile-patch",
|
||||
"COMMITMSG_FILE": "/tmp/test-v8-push-to-candidates-tempfile-commitmsg",
|
||||
"CHROMIUM": "/tmp/test-v8-push-to-candidates-tempfile-chromium",
|
||||
"PERSISTFILE_BASENAME": "/tmp/test-create-releases-tempfile",
|
||||
"PATCH_FILE": "/tmp/test-v8-create-releases-tempfile-tempfile-patch",
|
||||
"COMMITMSG_FILE": "/tmp/test-v8-create-releases-tempfile-commitmsg",
|
||||
"CHROMIUM": "/tmp/test-create-releases-tempfile-chromium",
|
||||
"SETTINGS_LOCATION": None,
|
||||
"ALREADY_MERGING_SENTINEL_FILE":
|
||||
"/tmp/test-merge-to-branch-tempfile-already-merging",
|
||||
@ -98,142 +93,6 @@ class ToplevelTest(unittest.TestCase):
|
||||
]
|
||||
self.assertEquals(expected, NormalizeVersionTags(input))
|
||||
|
||||
def testMakeComment(self):
|
||||
self.assertEquals("# Line 1\n# Line 2\n#",
|
||||
MakeComment(" Line 1\n Line 2\n"))
|
||||
self.assertEquals("#Line 1\n#Line 2",
|
||||
MakeComment("Line 1\n Line 2"))
|
||||
|
||||
def testStripComments(self):
|
||||
self.assertEquals(" Line 1\n Line 3\n",
|
||||
StripComments(" Line 1\n# Line 2\n Line 3\n#\n"))
|
||||
self.assertEquals("\nLine 2 ### Test\n #",
|
||||
StripComments("###\n# \n\n# Line 1\nLine 2 ### Test\n #"))
|
||||
|
||||
def testMakeChangeLogBodySimple(self):
|
||||
commits = [
|
||||
["Title text 1",
|
||||
"Title text 1\n\nBUG=\n",
|
||||
"author1@chromium.org"],
|
||||
["Title text 2.",
|
||||
"Title text 2\n\nBUG=1234\n",
|
||||
"author2@chromium.org"],
|
||||
]
|
||||
self.assertEquals(" Title text 1.\n"
|
||||
" (author1@chromium.org)\n\n"
|
||||
" Title text 2 (Chromium issue 1234).\n"
|
||||
" (author2@chromium.org)\n\n",
|
||||
MakeChangeLogBody(commits))
|
||||
|
||||
def testMakeChangeLogBodyEmpty(self):
|
||||
self.assertEquals("", MakeChangeLogBody([]))
|
||||
|
||||
def testMakeChangeLogBodyAutoFormat(self):
|
||||
commits = [
|
||||
["Title text 1!",
|
||||
"Title text 1\nLOG=y\nBUG=\n",
|
||||
"author1@chromium.org"],
|
||||
["Title text 2",
|
||||
"Title text 2\n\nBUG=1234\n",
|
||||
"author2@chromium.org"],
|
||||
["Title text 3",
|
||||
"Title text 3\n\nBUG=1234\nLOG = Yes\n",
|
||||
"author3@chromium.org"],
|
||||
["Title text 3",
|
||||
"Title text 4\n\nBUG=1234\nLOG=\n",
|
||||
"author4@chromium.org"],
|
||||
]
|
||||
self.assertEquals(" Title text 1.\n\n"
|
||||
" Title text 3 (Chromium issue 1234).\n\n",
|
||||
MakeChangeLogBody(commits, True))
|
||||
|
||||
def testRegressWrongLogEntryOnTrue(self):
|
||||
body = """
|
||||
Check elimination: Learn from if(CompareMap(x)) on true branch.
|
||||
|
||||
BUG=
|
||||
R=verwaest@chromium.org
|
||||
|
||||
Committed: https://code.google.com/p/v8/source/detail?r=18210
|
||||
"""
|
||||
self.assertEquals("", MakeChangeLogBody([["title", body, "author"]], True))
|
||||
|
||||
def testMakeChangeLogBugReferenceEmpty(self):
|
||||
self.assertEquals("", MakeChangeLogBugReference(""))
|
||||
self.assertEquals("", MakeChangeLogBugReference("LOG="))
|
||||
self.assertEquals("", MakeChangeLogBugReference(" BUG ="))
|
||||
self.assertEquals("", MakeChangeLogBugReference("BUG=none\t"))
|
||||
|
||||
def testMakeChangeLogBugReferenceSimple(self):
|
||||
self.assertEquals("(issue 987654)",
|
||||
MakeChangeLogBugReference("BUG = v8:987654"))
|
||||
self.assertEquals("(Chromium issue 987654)",
|
||||
MakeChangeLogBugReference("BUG=987654 "))
|
||||
|
||||
def testMakeChangeLogBugReferenceFromBody(self):
|
||||
self.assertEquals("(Chromium issue 1234567)",
|
||||
MakeChangeLogBugReference("Title\n\nTBR=\nBUG=\n"
|
||||
" BUG=\tchromium:1234567\t\n"
|
||||
"R=somebody\n"))
|
||||
|
||||
def testMakeChangeLogBugReferenceMultiple(self):
|
||||
# All issues should be sorted and grouped. Multiple references to the same
|
||||
# issue should be filtered.
|
||||
self.assertEquals("(issues 123, 234, Chromium issue 345)",
|
||||
MakeChangeLogBugReference("Title\n\n"
|
||||
"BUG=v8:234\n"
|
||||
" BUG\t= 345, \tv8:234,\n"
|
||||
"BUG=v8:123\n"
|
||||
"R=somebody\n"))
|
||||
self.assertEquals("(Chromium issues 123, 234)",
|
||||
MakeChangeLogBugReference("Title\n\n"
|
||||
"BUG=234,,chromium:123 \n"
|
||||
"R=somebody\n"))
|
||||
self.assertEquals("(Chromium issues 123, 234)",
|
||||
MakeChangeLogBugReference("Title\n\n"
|
||||
"BUG=chromium:234, , 123\n"
|
||||
"R=somebody\n"))
|
||||
self.assertEquals("(issues 345, 456)",
|
||||
MakeChangeLogBugReference("Title\n\n"
|
||||
"\t\tBUG=v8:345,v8:456\n"
|
||||
"R=somebody\n"))
|
||||
self.assertEquals("(issue 123, Chromium issues 345, 456)",
|
||||
MakeChangeLogBugReference("Title\n\n"
|
||||
"BUG=chromium:456\n"
|
||||
"BUG = none\n"
|
||||
"R=somebody\n"
|
||||
"BUG=456,v8:123, 345"))
|
||||
|
||||
# TODO(machenbach): These test don't make much sense when the formatting is
|
||||
# done later.
|
||||
def testMakeChangeLogBugReferenceLong(self):
|
||||
# -----------------00--------10--------20--------30--------
|
||||
self.assertEquals("(issues 234, 1234567890, 1234567"
|
||||
"8901234567890, Chromium issues 12345678,"
|
||||
" 123456789)",
|
||||
MakeChangeLogBugReference("BUG=v8:234\n"
|
||||
"BUG=v8:1234567890\n"
|
||||
"BUG=v8:12345678901234567890\n"
|
||||
"BUG=123456789\n"
|
||||
"BUG=12345678\n"))
|
||||
# -----------------00--------10--------20--------30--------
|
||||
self.assertEquals("(issues 234, 1234567890, 1234567"
|
||||
"8901234567890, Chromium issues"
|
||||
" 123456789, 1234567890)",
|
||||
MakeChangeLogBugReference("BUG=v8:234\n"
|
||||
"BUG=v8:12345678901234567890\n"
|
||||
"BUG=v8:1234567890\n"
|
||||
"BUG=123456789\n"
|
||||
"BUG=1234567890\n"))
|
||||
# -----------------00--------10--------20--------30--------
|
||||
self.assertEquals("(Chromium issues 234, 1234567890"
|
||||
", 12345678901234567, "
|
||||
"1234567890123456789)",
|
||||
MakeChangeLogBugReference("BUG=234\n"
|
||||
"BUG=12345678901234567\n"
|
||||
"BUG=1234567890123456789\n"
|
||||
"BUG=1234567890\n"))
|
||||
|
||||
|
||||
def Cmd(*args, **kwargs):
|
||||
"""Convenience function returning a shell command test expectation."""
|
||||
@ -278,6 +137,7 @@ class SimpleMock(object):
|
||||
|
||||
def Call(self, name, *args, **kwargs): # pragma: no cover
|
||||
self._index += 1
|
||||
|
||||
try:
|
||||
expected_call = self._recipe[self._index]
|
||||
except IndexError:
|
||||
@ -380,9 +240,9 @@ class ScriptTest(unittest.TestCase):
|
||||
config=TEST_CONFIG, side_effect_handler=self,
|
||||
options=options)
|
||||
|
||||
def RunStep(self, script=PushToCandidates, step_class=Step, args=None):
|
||||
def RunStep(self, script=CreateRelease, step_class=Step, args=None):
|
||||
"""Convenience wrapper."""
|
||||
args = args if args is not None else ["-m"]
|
||||
args = args if args is not None else ["-m", "-a=author", "-r=reviewer", ]
|
||||
return script(TEST_CONFIG, self, self._state).RunSteps([step_class], args)
|
||||
|
||||
def Call(self, fun, *args, **kwargs):
|
||||
@ -405,9 +265,6 @@ class ScriptTest(unittest.TestCase):
|
||||
def Sleep(self, seconds):
|
||||
pass
|
||||
|
||||
def GetDate(self):
|
||||
return "1999-07-31"
|
||||
|
||||
def GetUTCStamp(self):
|
||||
return "1000000"
|
||||
|
||||
@ -486,13 +343,13 @@ class ScriptTest(unittest.TestCase):
|
||||
def testTagTimeout(self):
|
||||
self.Expect([
|
||||
Cmd("git fetch", ""),
|
||||
Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
|
||||
Cmd("git log -1 --format=%H --grep=\"Title\" origin/tag_name", ""),
|
||||
Cmd("git fetch", ""),
|
||||
Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
|
||||
Cmd("git log -1 --format=%H --grep=\"Title\" origin/tag_name", ""),
|
||||
Cmd("git fetch", ""),
|
||||
Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
|
||||
Cmd("git log -1 --format=%H --grep=\"Title\" origin/tag_name", ""),
|
||||
Cmd("git fetch", ""),
|
||||
Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
|
||||
Cmd("git log -1 --format=%H --grep=\"Title\" origin/tag_name", ""),
|
||||
])
|
||||
args = ["--branch", "candidates", "ab12345"]
|
||||
self._state["version"] = "tag_name"
|
||||
@ -530,84 +387,6 @@ class ScriptTest(unittest.TestCase):
|
||||
r"\g<space>3",
|
||||
"//\n#define V8_BUILD_NUMBER 321\n"))
|
||||
|
||||
def testPreparePushRevision(self):
|
||||
# Tests the default push hash used when the --revision option is not set.
|
||||
self.Expect([
|
||||
Cmd("git log -1 --format=%H HEAD", "push_hash")
|
||||
])
|
||||
|
||||
self.RunStep(PushToCandidates, PreparePushRevision)
|
||||
self.assertEquals("push_hash", self._state["push_hash"])
|
||||
|
||||
def testPrepareChangeLog(self):
|
||||
self.WriteFakeVersionFile()
|
||||
TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
|
||||
|
||||
self.Expect([
|
||||
Cmd("git log --format=%H 1234..push_hash", "rev1\nrev2\nrev3\nrev4"),
|
||||
Cmd("git log -1 --format=%s rev1", "Title text 1"),
|
||||
Cmd("git log -1 --format=%B rev1", "Title\n\nBUG=\nLOG=y\n"),
|
||||
Cmd("git log -1 --format=%an rev1", "author1@chromium.org"),
|
||||
Cmd("git log -1 --format=%s rev2", "Title text 2."),
|
||||
Cmd("git log -1 --format=%B rev2", "Title\n\nBUG=123\nLOG= \n"),
|
||||
Cmd("git log -1 --format=%an rev2", "author2@chromium.org"),
|
||||
Cmd("git log -1 --format=%s rev3", "Title text 3"),
|
||||
Cmd("git log -1 --format=%B rev3", "Title\n\nBUG=321\nLOG=true\n"),
|
||||
Cmd("git log -1 --format=%an rev3", "author3@chromium.org"),
|
||||
Cmd("git log -1 --format=%s rev4", "Title text 4"),
|
||||
Cmd("git log -1 --format=%B rev4", "Title\n\nBUG=456\nLOG=N"),
|
||||
Cmd("git log -1 --format=%an rev4", "author4@chromium.org"),
|
||||
])
|
||||
|
||||
self._state["last_push_master"] = "1234"
|
||||
self._state["push_hash"] = "push_hash"
|
||||
self._state["version"] = "3.22.5"
|
||||
self.RunStep(PushToCandidates, PrepareChangeLog)
|
||||
|
||||
actual_cl = FileToText(TEST_CONFIG["CHANGELOG_ENTRY_FILE"])
|
||||
|
||||
expected_cl = """1999-07-31: Version 3.22.5
|
||||
|
||||
Title text 1.
|
||||
|
||||
Title text 3 (Chromium issue 321).
|
||||
|
||||
Performance and stability improvements on all platforms.
|
||||
#
|
||||
# The change log above is auto-generated. Please review if all relevant
|
||||
# commit messages from the list below are included.
|
||||
# All lines starting with # will be stripped.
|
||||
#
|
||||
# Title text 1.
|
||||
# (author1@chromium.org)
|
||||
#
|
||||
# Title text 2 (Chromium issue 123).
|
||||
# (author2@chromium.org)
|
||||
#
|
||||
# Title text 3 (Chromium issue 321).
|
||||
# (author3@chromium.org)
|
||||
#
|
||||
# Title text 4 (Chromium issue 456).
|
||||
# (author4@chromium.org)
|
||||
#
|
||||
#"""
|
||||
|
||||
self.assertEquals(expected_cl, actual_cl)
|
||||
|
||||
def testEditChangeLog(self):
|
||||
TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
|
||||
TextToFile(" New \n\tLines \n", TEST_CONFIG["CHANGELOG_ENTRY_FILE"])
|
||||
os.environ["EDITOR"] = "vi"
|
||||
self.Expect([
|
||||
RL(""), # Open editor.
|
||||
Cmd("vi %s" % TEST_CONFIG["CHANGELOG_ENTRY_FILE"], ""),
|
||||
])
|
||||
|
||||
self.RunStep(PushToCandidates, EditChangeLog)
|
||||
|
||||
self.assertEquals("New\n Lines",
|
||||
FileToText(TEST_CONFIG["CHANGELOG_ENTRY_FILE"]))
|
||||
|
||||
TAGS = """
|
||||
4425.0
|
||||
0.0.0.0
|
||||
@ -626,64 +405,13 @@ test_tag
|
||||
"", cb=lambda: self.WriteFakeVersionFile(3, 22, 6)),
|
||||
])
|
||||
|
||||
self.RunStep(PushToCandidates, IncrementVersion)
|
||||
self.RunStep(CreateRelease, IncrementVersion)
|
||||
|
||||
self.assertEquals("3", self._state["new_major"])
|
||||
self.assertEquals("22", self._state["new_minor"])
|
||||
self.assertEquals("7", self._state["new_build"])
|
||||
self.assertEquals("0", self._state["new_patch"])
|
||||
|
||||
def _TestSquashCommits(self, change_log, expected_msg):
|
||||
TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
|
||||
with open(TEST_CONFIG["CHANGELOG_ENTRY_FILE"], "w") as f:
|
||||
f.write(change_log)
|
||||
|
||||
self.Expect([
|
||||
Cmd("git diff origin/candidates hash1", "patch content"),
|
||||
])
|
||||
|
||||
self._state["push_hash"] = "hash1"
|
||||
self._state["date"] = "1999-11-11"
|
||||
|
||||
self.RunStep(PushToCandidates, SquashCommits)
|
||||
self.assertEquals(FileToText(TEST_CONFIG["COMMITMSG_FILE"]), expected_msg)
|
||||
|
||||
patch = FileToText(TEST_CONFIG["PATCH_FILE"])
|
||||
self.assertTrue(re.search(r"patch content", patch))
|
||||
|
||||
def testSquashCommitsUnformatted(self):
|
||||
change_log = """1999-11-11: Version 3.22.5
|
||||
|
||||
Log text 1.
|
||||
Chromium issue 12345
|
||||
|
||||
Performance and stability improvements on all platforms.\n"""
|
||||
commit_msg = """Version 3.22.5 (based on hash1)
|
||||
|
||||
Log text 1. Chromium issue 12345
|
||||
|
||||
Performance and stability improvements on all platforms."""
|
||||
self._TestSquashCommits(change_log, commit_msg)
|
||||
|
||||
def testSquashCommitsFormatted(self):
|
||||
change_log = """1999-11-11: Version 3.22.5
|
||||
|
||||
Long commit message that fills more than 80 characters (Chromium issue
|
||||
12345).
|
||||
|
||||
Performance and stability improvements on all platforms.\n"""
|
||||
commit_msg = """Version 3.22.5 (based on hash1)
|
||||
|
||||
Long commit message that fills more than 80 characters (Chromium issue 12345).
|
||||
|
||||
Performance and stability improvements on all platforms."""
|
||||
self._TestSquashCommits(change_log, commit_msg)
|
||||
|
||||
def testSquashCommitsQuotationMarks(self):
|
||||
change_log = """Line with "quotation marks".\n"""
|
||||
commit_msg = """Line with "quotation marks"."""
|
||||
self._TestSquashCommits(change_log, commit_msg)
|
||||
|
||||
def testBootstrapper(self):
|
||||
work_dir = self.MakeEmptyTempDirectory()
|
||||
class FakeScript(ScriptsBase):
|
||||
@ -699,189 +427,16 @@ Performance and stability improvements on all platforms."""
|
||||
])
|
||||
FakeScript(fake_config, self).Run(["--work-dir", work_dir])
|
||||
|
||||
def _PushToCandidates(self, force=False, manual=False):
|
||||
TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
|
||||
|
||||
# The version file on master has build level 5, while the version
|
||||
# file from candidates has build level 4.
|
||||
self.WriteFakeVersionFile(build=5)
|
||||
|
||||
TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
|
||||
master_change_log = "2014-03-17: Sentinel\n"
|
||||
TextToFile(master_change_log,
|
||||
os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
|
||||
os.environ["EDITOR"] = "vi"
|
||||
|
||||
commit_msg_squashed = """Version 3.22.5 (squashed - based on push_hash)
|
||||
|
||||
Log text 1 (issue 321).
|
||||
|
||||
Performance and stability improvements on all platforms."""
|
||||
|
||||
commit_msg = """Version 3.22.5 (based on push_hash)
|
||||
|
||||
Log text 1 (issue 321).
|
||||
|
||||
Performance and stability improvements on all platforms."""
|
||||
|
||||
def ResetChangeLog():
|
||||
"""On 'git co -b new_branch origin/candidates',
|
||||
and 'git checkout -- ChangeLog',
|
||||
the ChangLog will be reset to its content on candidates."""
|
||||
candidates_change_log = """1999-04-05: Version 3.22.4
|
||||
|
||||
Performance and stability improvements on all platforms.\n"""
|
||||
TextToFile(candidates_change_log,
|
||||
os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
|
||||
|
||||
def ResetToCandidates():
|
||||
ResetChangeLog()
|
||||
self.WriteFakeVersionFile()
|
||||
|
||||
def CheckVersionCommit():
|
||||
commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
|
||||
self.assertEquals(commit_msg, commit)
|
||||
version = FileToText(
|
||||
os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE))
|
||||
self.assertTrue(re.search(r"#define V8_MINOR_VERSION\s+22", version))
|
||||
self.assertTrue(re.search(r"#define V8_BUILD_NUMBER\s+5", version))
|
||||
self.assertFalse(re.search(r"#define V8_BUILD_NUMBER\s+6", version))
|
||||
self.assertTrue(re.search(r"#define V8_PATCH_LEVEL\s+0", version))
|
||||
self.assertTrue(
|
||||
re.search(r"#define V8_IS_CANDIDATE_VERSION\s+0", version))
|
||||
|
||||
# Check that the change log on the candidates branch got correctly
|
||||
# modified.
|
||||
change_log = FileToText(
|
||||
os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
|
||||
self.assertEquals(
|
||||
"""1999-07-31: Version 3.22.5
|
||||
|
||||
Log text 1 (issue 321).
|
||||
|
||||
Performance and stability improvements on all platforms.
|
||||
|
||||
|
||||
1999-04-05: Version 3.22.4
|
||||
|
||||
Performance and stability improvements on all platforms.\n""",
|
||||
change_log)
|
||||
|
||||
force_flag = " -f" if not manual else ""
|
||||
expectations = []
|
||||
if not force:
|
||||
expectations.append(Cmd("which vi", "/usr/bin/vi"))
|
||||
expectations += [
|
||||
Cmd("git status -s -uno", ""),
|
||||
Cmd("git checkout -f origin/master", ""),
|
||||
Cmd("git fetch", ""),
|
||||
Cmd("git branch", " branch1\n* branch2\n"),
|
||||
Cmd("git branch", " branch1\n* branch2\n"),
|
||||
Cmd(("git new-branch %s --upstream origin/master" %
|
||||
TEST_CONFIG["BRANCHNAME"]), ""),
|
||||
Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
|
||||
Cmd("git tag", self.TAGS),
|
||||
Cmd("git checkout -f origin/master -- include/v8-version.h",
|
||||
"", cb=self.WriteFakeVersionFile),
|
||||
Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"),
|
||||
Cmd("git log -1 --format=%s release_hash",
|
||||
"Version 3.22.4 (based on abc3)\n"),
|
||||
Cmd("git log --format=%H abc3..push_hash", "rev1\n"),
|
||||
Cmd("git log -1 --format=%s rev1", "Log text 1.\n"),
|
||||
Cmd("git log -1 --format=%B rev1", "Text\nLOG=YES\nBUG=v8:321\nText\n"),
|
||||
Cmd("git log -1 --format=%an rev1", "author1@chromium.org\n"),
|
||||
]
|
||||
if manual:
|
||||
expectations.append(RL("")) # Open editor.
|
||||
if not force:
|
||||
expectations.append(
|
||||
Cmd("vi %s" % TEST_CONFIG["CHANGELOG_ENTRY_FILE"], ""))
|
||||
expectations += [
|
||||
Cmd("git fetch", ""),
|
||||
Cmd("git checkout -f origin/master", ""),
|
||||
Cmd("git diff origin/candidates push_hash", "patch content\n"),
|
||||
Cmd(("git new-branch %s --upstream origin/candidates" %
|
||||
TEST_CONFIG["CANDIDATESBRANCH"]), "", cb=ResetToCandidates),
|
||||
Cmd("git apply --index --reject \"%s\"" % TEST_CONFIG["PATCH_FILE"], ""),
|
||||
Cmd("git checkout -f origin/candidates -- ChangeLog", "",
|
||||
cb=ResetChangeLog),
|
||||
Cmd("git checkout -f origin/candidates -- include/v8-version.h", "",
|
||||
cb=self.WriteFakeVersionFile),
|
||||
Cmd("git commit -am \"%s\"" % commit_msg_squashed, ""),
|
||||
]
|
||||
if manual:
|
||||
expectations.append(RL("Y")) # Sanity check.
|
||||
expectations += [
|
||||
Cmd("git cl land -f --bypass-hooks", ""),
|
||||
Cmd("git checkout -f master", ""),
|
||||
Cmd("git fetch", ""),
|
||||
Cmd("git branch -D %s" % TEST_CONFIG["CANDIDATESBRANCH"], ""),
|
||||
Cmd(("git new-branch %s --upstream origin/candidates" %
|
||||
TEST_CONFIG["CANDIDATESBRANCH"]), "", cb=ResetToCandidates),
|
||||
Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], "",
|
||||
cb=CheckVersionCommit),
|
||||
Cmd("git cl land -f --bypass-hooks", ""),
|
||||
Cmd("git fetch", ""),
|
||||
Cmd("git log -1 --format=%H --grep="
|
||||
"\"Version 3.22.5 (based on push_hash)\""
|
||||
" origin/candidates", "hsh_to_tag"),
|
||||
Cmd("git tag 3.22.5 hsh_to_tag", ""),
|
||||
Cmd("git push origin refs/tags/3.22.5:refs/tags/3.22.5", ""),
|
||||
Cmd("git checkout -f origin/master", ""),
|
||||
Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
|
||||
Cmd("git branch -D %s" % TEST_CONFIG["CANDIDATESBRANCH"], ""),
|
||||
]
|
||||
self.Expect(expectations)
|
||||
|
||||
args = ["-a", "author@chromium.org", "--revision", "push_hash"]
|
||||
if force: args.append("-f")
|
||||
if manual: args.append("-m")
|
||||
else: args += ["-r", "reviewer@chromium.org"]
|
||||
PushToCandidates(TEST_CONFIG, self).Run(args)
|
||||
|
||||
cl = FileToText(os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
|
||||
self.assertTrue(re.search(r"^\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl))
|
||||
self.assertTrue(re.search(r" Log text 1 \(issue 321\).", cl))
|
||||
self.assertTrue(re.search(r"1999\-04\-05: Version 3\.22\.4", cl))
|
||||
|
||||
# Note: The version file is on build number 5 again in the end of this test
|
||||
# since the git command that merges to master is mocked out.
|
||||
|
||||
def testPushToCandidatesManual(self):
|
||||
self._PushToCandidates(manual=True)
|
||||
|
||||
def testPushToCandidatesSemiAutomatic(self):
|
||||
self._PushToCandidates()
|
||||
|
||||
def testPushToCandidatesForced(self):
|
||||
self._PushToCandidates(force=True)
|
||||
|
||||
def testCreateRelease(self):
|
||||
TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
|
||||
|
||||
# The version file on master has build level 5.
|
||||
self.WriteFakeVersionFile(build=5)
|
||||
|
||||
master_change_log = "2014-03-17: Sentinel\n"
|
||||
TextToFile(master_change_log,
|
||||
os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
|
||||
|
||||
commit_msg = """Version 3.22.5
|
||||
|
||||
Log text 1 (issue 321).
|
||||
|
||||
Performance and stability improvements on all platforms.
|
||||
|
||||
TBR=reviewer@chromium.org"""
|
||||
|
||||
def ResetChangeLog():
|
||||
last_change_log = """1999-04-05: Version 3.22.4
|
||||
|
||||
Performance and stability improvements on all platforms.\n"""
|
||||
TextToFile(last_change_log,
|
||||
os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
|
||||
|
||||
|
||||
def CheckVersionCommit():
|
||||
commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
|
||||
self.assertEquals(commit_msg, commit)
|
||||
@ -894,23 +449,6 @@ TBR=reviewer@chromium.org"""
|
||||
self.assertTrue(
|
||||
re.search(r"#define V8_IS_CANDIDATE_VERSION\s+0", version))
|
||||
|
||||
# Check that the change log on the candidates branch got correctly
|
||||
# modified.
|
||||
change_log = FileToText(
|
||||
os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
|
||||
self.assertEquals(
|
||||
"""1999-07-31: Version 3.22.5
|
||||
|
||||
Log text 1 (issue 321).
|
||||
|
||||
Performance and stability improvements on all platforms.
|
||||
|
||||
|
||||
1999-04-05: Version 3.22.4
|
||||
|
||||
Performance and stability improvements on all platforms.\n""",
|
||||
change_log)
|
||||
|
||||
expectations = [
|
||||
Cmd("git fetch origin +refs/heads/*:refs/heads/*", ""),
|
||||
Cmd("git checkout -f origin/master", "", cb=self.WriteFakeWatchlistsFile),
|
||||
@ -923,14 +461,9 @@ TBR=reviewer@chromium.org"""
|
||||
Cmd("git log -1 --format=%s release_hash", "Version 3.22.4\n"),
|
||||
Cmd("git log -1 --format=%H release_hash^", "abc3\n"),
|
||||
Cmd("git log --format=%H abc3..push_hash", "rev1\n"),
|
||||
Cmd("git log -1 --format=%s rev1", "Log text 1.\n"),
|
||||
Cmd("git log -1 --format=%B rev1", "Text\nLOG=YES\nBUG=v8:321\nText\n"),
|
||||
Cmd("git log -1 --format=%an rev1", "author1@chromium.org\n"),
|
||||
Cmd("git push origin :refs/heads/3.22.5", ""),
|
||||
Cmd("git push origin push_hash:refs/heads/3.22.5", ""),
|
||||
Cmd("git reset --hard origin/master", ""),
|
||||
Cmd("git new-branch work-branch --upstream origin/3.22.5", ""),
|
||||
Cmd("git checkout -f 3.22.4 -- ChangeLog", "", cb=ResetChangeLog),
|
||||
Cmd("git checkout -f 3.22.4 -- include/v8-version.h", "",
|
||||
cb=self.WriteFakeVersionFile),
|
||||
Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], "",
|
||||
@ -956,11 +489,6 @@ TBR=reviewer@chromium.org"""
|
||||
"--revision", "push_hash"]
|
||||
CreateRelease(TEST_CONFIG, self).Run(args)
|
||||
|
||||
cl = FileToText(os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
|
||||
self.assertTrue(re.search(r"^\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl))
|
||||
self.assertTrue(re.search(r" Log text 1 \(issue 321\).", cl))
|
||||
self.assertTrue(re.search(r"1999\-04\-05: Version 3\.22\.4", cl))
|
||||
|
||||
# Note: The version file is on build number 5 again in the end of this test
|
||||
# since the git command that merges to master is mocked out.
|
||||
|
||||
@ -1174,7 +702,6 @@ Title1
|
||||
Revert "Something"
|
||||
|
||||
BUG=123,234,345,456,567,v8:123
|
||||
LOG=N
|
||||
"""
|
||||
|
||||
def VerifyLand():
|
||||
@ -1218,7 +745,7 @@ LOG=N
|
||||
Cmd("git log -1 --format=%s ab56789", "Revert \"Something\""),
|
||||
Cmd("git log -1 ab12345", "Title4\nBUG=123\nBUG=234"),
|
||||
Cmd("git log -1 ab23456", "Title2\n BUG = v8:123,345"),
|
||||
Cmd("git log -1 ab34567", "Title3\nLOG=n\nBUG=567, 456"),
|
||||
Cmd("git log -1 ab34567", "Title3\nBUG=567, 456"),
|
||||
Cmd("git log -1 ab45678", "Title1\nBUG="),
|
||||
Cmd("git log -1 ab56789", "Revert \"Something\"\nBUG=none"),
|
||||
Cmd("git log -1 -p ab12345", "patch4"),
|
||||
@ -1316,7 +843,6 @@ Merged: Revert \"Something\"
|
||||
Revision: ab56789
|
||||
|
||||
BUG=123,234,345,456,567,v8:123
|
||||
LOG=N
|
||||
NOTRY=true
|
||||
NOPRESUBMIT=true
|
||||
NOTREECHECKS=true
|
||||
@ -1356,7 +882,7 @@ NOTREECHECKS=true
|
||||
Cmd("git log -1 --format=%s ab56789", "Revert \"Something\""),
|
||||
Cmd("git log -1 ab12345", "Title4\nBUG=123\nBUG=234"),
|
||||
Cmd("git log -1 ab23456", "Title2\n BUG = v8:123,345"),
|
||||
Cmd("git log -1 ab34567", "Title3\nLOG=n\nBug: 567, 456,345"),
|
||||
Cmd("git log -1 ab34567", "Title3\nBug: 567, 456,345"),
|
||||
Cmd("git log -1 ab45678", "Title1\nBug:"),
|
||||
Cmd("git log -1 ab56789", "Revert \"Something\"\nBUG=none"),
|
||||
Cmd("git log -1 -p ab12345", "patch4"),
|
||||
|
Loading…
Reference in New Issue
Block a user