summaryrefslogtreecommitdiffstats
path: root/WebKitTools/Scripts
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2009-11-05 09:23:40 +0000
committerSteve Block <steveblock@google.com>2009-11-10 22:41:12 +0000
commitcac0f67c402d107cdb10971b95719e2ff9c7c76b (patch)
treed182c7f87211c6f201a5f038e332336493ebdbe7 /WebKitTools/Scripts
parent4b2ef0f288e7c6c4602f621b7a0e9feed304b70e (diff)
downloadexternal_webkit-cac0f67c402d107cdb10971b95719e2ff9c7c76b.zip
external_webkit-cac0f67c402d107cdb10971b95719e2ff9c7c76b.tar.gz
external_webkit-cac0f67c402d107cdb10971b95719e2ff9c7c76b.tar.bz2
Merge webkit.org at r50258 : Initial merge by git.
Change-Id: I1a9e1dc4ed654b69174ad52a4f031a07240f37b0
Diffstat (limited to 'WebKitTools/Scripts')
-rw-r--r--WebKitTools/Scripts/VCSUtils.pm137
-rwxr-xr-xWebKitTools/Scripts/bisect-builds4
-rwxr-xr-xWebKitTools/Scripts/bugzilla-tool122
-rw-r--r--WebKitTools/Scripts/modules/bugzilla.py26
-rw-r--r--WebKitTools/Scripts/modules/buildbot.py14
-rw-r--r--WebKitTools/Scripts/modules/buildbot_unittest.py16
-rw-r--r--WebKitTools/Scripts/modules/committers.py31
-rw-r--r--WebKitTools/Scripts/modules/cpp_style.py85
-rw-r--r--WebKitTools/Scripts/modules/cpp_style_unittest.py100
-rw-r--r--WebKitTools/Scripts/modules/scm.py16
-rw-r--r--WebKitTools/Scripts/modules/scm_unittest.py59
-rwxr-xr-xWebKitTools/Scripts/pdevenv14
-rwxr-xr-xWebKitTools/Scripts/prepare-ChangeLog27
-rwxr-xr-xWebKitTools/Scripts/resolve-ChangeLogs63
-rwxr-xr-xWebKitTools/Scripts/run-iexploder-tests3
-rwxr-xr-xWebKitTools/Scripts/run-javascriptcore-tests13
-rwxr-xr-xWebKitTools/Scripts/run-jsc7
-rwxr-xr-xWebKitTools/Scripts/run-launcher2
-rwxr-xr-xWebKitTools/Scripts/run-mangleme-tests3
-rwxr-xr-xWebKitTools/Scripts/run-sunspider13
-rwxr-xr-xWebKitTools/Scripts/run-webkit-tests4
-rwxr-xr-xWebKitTools/Scripts/sunspider-compare-results4
-rwxr-xr-xWebKitTools/Scripts/svn-apply125
-rwxr-xr-xWebKitTools/Scripts/svn-create-patch72
-rwxr-xr-xWebKitTools/Scripts/svn-unapply103
-rwxr-xr-xWebKitTools/Scripts/update-webkit8
-rw-r--r--WebKitTools/Scripts/webkitdirs.pm31
27 files changed, 506 insertions, 596 deletions
diff --git a/WebKitTools/Scripts/VCSUtils.pm b/WebKitTools/Scripts/VCSUtils.pm
index 6ec12c9..e1e0bc2 100644
--- a/WebKitTools/Scripts/VCSUtils.pm
+++ b/WebKitTools/Scripts/VCSUtils.pm
@@ -40,10 +40,13 @@ BEGIN {
$VERSION = 1.00;
@ISA = qw(Exporter);
@EXPORT = qw(
+ &canonicalizePath
&chdirReturningRelativePath
&determineSVNRoot
&determineVCSRoot
+ &fixChangeLogPatch
&gitBranch
+ &gitdiff2svndiff
&isGit
&isGitBranchBuild
&isGitDirectory
@@ -51,8 +54,10 @@ BEGIN {
&isSVNDirectory
&isSVNVersion16OrNewer
&makeFilePathRelative
+ &normalizePath
&pathRelativeToSVNRepositoryRootForPath
&svnRevisionForDirectory
+ &svnStatus
);
%EXPORT_TAGS = ( );
@EXPORT_OK = ();
@@ -70,7 +75,7 @@ my $svnVersion;
sub isGitDirectory($)
{
my ($dir) = @_;
- return system("cd $dir && git rev-parse > /dev/null 2>&1") == 0;
+ return system("cd $dir && git rev-parse > " . File::Spec->devnull() . " 2>&1") == 0;
}
sub isGit()
@@ -159,7 +164,6 @@ sub determineGitRoot()
sub determineSVNRoot()
{
- my $devNull = File::Spec->devnull();
my $last = '';
my $path = '.';
my $parent = '..';
@@ -169,7 +173,7 @@ sub determineSVNRoot()
my $thisRoot;
my $thisUUID;
# Ignore error messages in case we've run past the root of the checkout.
- open INFO, "svn info '$path' 2> $devNull |" or die;
+ open INFO, "svn info '$path' 2> " . File::Spec->devnull() . " |" or die;
while (<INFO>) {
if (/^Repository Root: (.+)/) {
$thisRoot = $1;
@@ -268,4 +272,131 @@ sub makeFilePathRelative($)
return $gitRoot . $path;
}
+sub normalizePath($)
+{
+ my ($path) = @_;
+ $path =~ s/\\/\//g;
+ return $path;
+}
+
+sub canonicalizePath($)
+{
+ my ($file) = @_;
+
+ # Remove extra slashes and '.' directories in path
+ $file = File::Spec->canonpath($file);
+
+ # Remove '..' directories in path
+ my @dirs = ();
+ foreach my $dir (File::Spec->splitdir($file)) {
+ if ($dir eq '..' && $#dirs >= 0 && $dirs[$#dirs] ne '..') {
+ pop(@dirs);
+ } else {
+ push(@dirs, $dir);
+ }
+ }
+ return ($#dirs >= 0) ? File::Spec->catdir(@dirs) : ".";
+}
+
+sub svnStatus($)
+{
+ my ($fullPath) = @_;
+ my $svnStatus;
+ open SVN, "svn status --non-interactive --non-recursive '$fullPath' |" or die;
+ if (-d $fullPath) {
+ # When running "svn stat" on a directory, we can't assume that only one
+ # status will be returned (since any files with a status below the
+ # directory will be returned), and we can't assume that the directory will
+ # be first (since any files with unknown status will be listed first).
+ my $normalizedFullPath = File::Spec->catdir(File::Spec->splitdir($fullPath));
+ while (<SVN>) {
+ # Input may use a different EOL sequence than $/, so avoid chomp.
+ $_ = removeEOL($_);
+ my $normalizedStatPath = File::Spec->catdir(File::Spec->splitdir(substr($_, 7)));
+ if ($normalizedFullPath eq $normalizedStatPath) {
+ $svnStatus = "$_\n";
+ last;
+ }
+ }
+ # Read the rest of the svn command output to avoid a broken pipe warning.
+ local $/ = undef;
+ <SVN>;
+ }
+ else {
+ # Files will have only one status returned.
+ $svnStatus = removeEOL(<SVN>) . "\n";
+ }
+ close SVN;
+ return $svnStatus;
+}
+
+sub gitdiff2svndiff($)
+{
+ $_ = shift @_;
+ if (m#^diff --git a/(.+) b/(.+)#) {
+ return "Index: $1";
+ } elsif (m/^new file.*/) {
+ return "";
+ } elsif (m#^index [0-9a-f]{7}\.\.[0-9a-f]{7} [0-9]{6}#) {
+ return "===================================================================";
+ } elsif (m#^--- a/(.+)#) {
+ return "--- $1";
+ } elsif (m#^\+\+\+ b/(.+)#) {
+ return "+++ $1";
+ }
+ return $_;
+}
+
+sub fixChangeLogPatch($)
+{
+ my $patch = shift;
+ my $contextLineCount = 3;
+
+ return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\n( .*\n)+(\+.*\n)+( .*\n){$contextLineCount}$/m;
+ my ($oldLineCount, $newLineCount) = ($1, $2);
+ return $patch if $oldLineCount <= $contextLineCount;
+
+ # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
+ # have lines of context at the top of a patch when the existing entry has the same
+ # date and author as the new entry. This nifty loop alters a ChangeLog patch so
+ # that the added lines ("+") in the patch always start at the beginning of the
+ # patch and there are no initial lines of context.
+ my $newPatch;
+ my $lineCountInState = 0;
+ my $oldContentLineCountReduction = $oldLineCount - $contextLineCount;
+ my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction;
+ my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4);
+ my $state = $stateHeader;
+ foreach my $line (split(/\n/, $patch)) {
+ $lineCountInState++;
+ if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) {
+ $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@";
+ $lineCountInState = 0;
+ $state = $statePreContext;
+ } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") {
+ $line = "+" . substr($line, 1);
+ if ($lineCountInState == $oldContentLineCountReduction) {
+ $lineCountInState = 0;
+ $state = $stateNewChanges;
+ }
+ } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") {
+ # No changes to these lines
+ if ($lineCountInState == $newContentLineCountWithoutContext) {
+ $lineCountInState = 0;
+ $state = $statePostContext;
+ }
+ } elsif ($state == $statePostContext) {
+ if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) {
+ $line = " " . substr($line, 1);
+ } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") {
+ next; # Discard
+ }
+ }
+ $newPatch .= $line . "\n";
+ }
+
+ return $newPatch;
+}
+
+
1;
diff --git a/WebKitTools/Scripts/bisect-builds b/WebKitTools/Scripts/bisect-builds
index 93e9223..55bf238 100755
--- a/WebKitTools/Scripts/bisect-builds
+++ b/WebKitTools/Scripts/bisect-builds
@@ -368,7 +368,7 @@ sub mountAndRunNightly($$$$)
while (-e $mountPath) {
$i++;
usleep 100 if $i > 1;
- `hdiutil detach '$mountPath' 2> /dev/null`;
+ exec "hdiutil", "detach '$mountPath' 2> " . File::Spec->devnull();
die "Could not unmount $diskImage at $mountPath" if $i > 100;
}
die "Can't mount $diskImage: $mountPath already exists!" if -e $mountPath;
@@ -393,7 +393,7 @@ sub mountAndRunNightly($$$$)
$tempFile ||= "";
`DYLD_FRAMEWORK_PATH=$frameworkPath WEBKIT_UNSET_DYLD_FRAMEWORK_PATH=YES $safari $tempFile`;
- `hdiutil detach '$mountPath' 2> /dev/null`;
+ exec "hdiutil", "detach '$mountPath' 2> " . File::Spec->devnull();
}
sub parseRevisions($$;$)
diff --git a/WebKitTools/Scripts/bugzilla-tool b/WebKitTools/Scripts/bugzilla-tool
index ec5aa0d..8e899b5 100755
--- a/WebKitTools/Scripts/bugzilla-tool
+++ b/WebKitTools/Scripts/bugzilla-tool
@@ -73,7 +73,7 @@ def commit_message_for_this_commit(scm):
log("Parsing ChangeLog: %s" % changelog_path)
changelog_entry = ChangeLog(changelog_path).latest_entry()
if not changelog_entry:
- error("Failed to parse ChangeLog: " + os.path.abspath(changelog_path))
+ raise ScriptError(message="Failed to parse ChangeLog: " + os.path.abspath(changelog_path))
changelog_messages.append(changelog_entry)
# FIXME: We should sort and label the ChangeLog messages like commit-log-editor does.
@@ -325,6 +325,11 @@ class LandPatchesFromBugs(Command):
options += WebKitLandingScripts.land_options()
Command.__init__(self, 'Lands all patches on a bug optionally testing them first', 'BUGID', options=options)
+ @staticmethod
+ def handled_error(error):
+ log(error)
+ exit(2) # Exit 2 insted of 1 to indicate to the commit-queue to indicate we handled the error, and that the queue should keep looping.
+
@classmethod
def land_patches(cls, bug_id, patches, options, tool):
try:
@@ -344,11 +349,11 @@ class LandPatchesFromBugs(Command):
except CheckoutNeedsUpdate, e:
log("Commit was rejected because the checkout is out of date. Please update and try again.")
log("You can pass --no-build to skip building/testing after update if you believe the new commits did not affect the results.")
- error(e)
+ cls.handled_error(e)
except ScriptError, e:
# Mark the patch as commit-queue- and comment in the bug.
tool.bugs.reject_patch_from_commit_queue(patch['id'], e.message_with_output())
- error(e)
+ cls.handled_error(e)
@staticmethod
def _fetch_list_of_patches_to_land(options, args, tool):
@@ -420,6 +425,7 @@ class PostDiffAsPatchToBug(Command):
return [
make_option("--no-obsolete", action="store_false", dest="obsolete_patches", default=True, help="Do not obsolete old patches before posting this one."),
make_option("--no-review", action="store_false", dest="review", default=True, help="Do not mark the patch for review."),
+ make_option("--request-commit", action="store_true", dest="request_commit", default=False, help="Mark the patch as needing auto-commit after review."),
]
@staticmethod
@@ -443,7 +449,7 @@ class PostDiffAsPatchToBug(Command):
diff_file = StringIO.StringIO(diff) # add_patch_to_bug expects a file-like object
description = options.description or "Patch v1"
- tool.bugs.add_patch_to_bug(bug_id, diff_file, description, mark_for_review=options.review)
+ tool.bugs.add_patch_to_bug(bug_id, diff_file, description, mark_for_review=options.review, mark_for_commit_queue=options.request_commit)
class PostCommitsAsPatchesToBug(Command):
@@ -493,7 +499,7 @@ class PostCommitsAsPatchesToBug(Command):
diff_file = self._diff_file_for_commit(tool, commit_id)
description = options.description or commit_message.description(lstrip=True, strip_url=True)
comment_text = self._comment_text_for_commit(options, commit_message, tool, commit_id)
- tool.bugs.add_patch_to_bug(bug_id, diff_file, description, comment_text, mark_for_review=options.review)
+ tool.bugs.add_patch_to_bug(bug_id, diff_file, description, comment_text, mark_for_review=options.review, mark_for_commit_queue=options.request_commit)
class RolloutCommit(Command):
@@ -560,6 +566,7 @@ class CreateBug(Command):
make_option("--component", action="store", type="string", dest="component", help="Component for the new bug."),
make_option("--no-prompt", action="store_false", dest="prompt", default=True, help="Do not prompt for bug title and comment; use commit log instead."),
make_option("--no-review", action="store_false", dest="review", default=True, help="Do not mark the patch for review."),
+ make_option("--request-commit", action="store_true", dest="request_commit", default=False, help="Mark the patch as needing auto-commit after review."),
]
Command.__init__(self, 'Create a bug from local changes or local commits.', '[COMMITISH]', options=options)
@@ -583,7 +590,7 @@ class CreateBug(Command):
diff = tool.scm().create_patch_from_local_commit(commit_id)
diff_file = StringIO.StringIO(diff) # create_bug_with_patch expects a file-like object
- bug_id = tool.bugs.create_bug_with_patch(bug_title, comment_text, options.component, diff_file, "Patch v1", cc=options.cc, mark_for_review=options.review)
+ bug_id = tool.bugs.create_bug_with_patch(bug_title, comment_text, options.component, diff_file, "Patch v1", cc=options.cc, mark_for_review=options.review, mark_for_commit_queue=options.request_commit)
if bug_id and len(commit_ids) > 1:
options.bug_id = bug_id
@@ -603,7 +610,7 @@ class CreateBug(Command):
diff = tool.scm().create_patch()
diff_file = StringIO.StringIO(diff) # create_bug_with_patch expects a file-like object
- bug_id = tool.bugs.create_bug_with_patch(bug_title, comment_text, options.component, diff_file, "Patch v1", cc=options.cc, mark_for_review=options.review)
+ bug_id = tool.bugs.create_bug_with_patch(bug_title, comment_text, options.component, diff_file, "Patch v1", cc=options.cc, mark_for_review=options.review, mark_for_commit_queue=options.request_commit)
def prompt_for_bug_title_and_comment(self):
bug_title = raw_input("Bug title: ")
@@ -644,6 +651,7 @@ class CheckTreeStatus(Command):
class LandPatchesFromCommitQueue(Command):
def __init__(self):
options = [
+ make_option("--is-relaunch", action="store_true", dest="is_relaunch", default=False, help="Internal: Used by the queue to indicate that it's relaunching itself."),
make_option("--no-confirm", action="store_false", dest="confirm", default=True, help="Do not ask the user for confirmation before running the queue. Dangerous!"),
make_option("--status-host", action="store", type="string", dest="status_host", default=StatusBot.default_host, help="Do not ask the user for confirmation before running the queue. Dangerous!"),
]
@@ -675,16 +683,25 @@ class LandPatchesFromCommitQueue(Command):
wake_time = datetime.now() + timedelta(seconds=cls.seconds_to_sleep)
return "%s Sleeping until %s (%s)." % (message, wake_time.strftime(cls.log_date_format), cls.sleep_duration_text)
- @classmethod
- def _sleep(cls, message):
- log(cls._sleep_message(message))
- time.sleep(cls.seconds_to_sleep)
+ def _sleep(self, message):
+ log(self._sleep_message(message))
+ time.sleep(self.seconds_to_sleep)
+ self._next_patch()
def _update_status_and_sleep(self, message):
status_message = self._sleep_message(message)
self.status_bot.update_status(status_message)
log(status_message)
time.sleep(self.seconds_to_sleep)
+ self._next_patch()
+
+ def _next_patch(self):
+ # Re-exec this script to catch any updates to the script.
+ # Make sure that the re-execed commit-queue does not wait for the user.
+ args = sys.argv[:]
+ if args.count("--is-relaunch") == 0:
+ args.append("--is-relaunch")
+ os.execvp(sys.argv[0], args)
@staticmethod
def _open_log_file(log_path):
@@ -705,50 +722,55 @@ class LandPatchesFromCommitQueue(Command):
log_file.close()
def execute(self, options, args, tool):
- log("CAUTION: commit-queue will discard all local changes in %s" % tool.scm().checkout_root)
- if options.confirm:
- response = raw_input("Are you sure? Type 'yes' to continue: ")
- if (response != 'yes'):
- error("User declined.")
+ if not options.is_relaunch:
+ log("CAUTION: commit-queue will discard all local changes in %s" % tool.scm().checkout_root)
+ if options.confirm:
+ response = raw_input("Are you sure? Type 'yes' to continue: ")
+ if (response != 'yes'):
+ error("User declined.")
queue_log = self._add_log_to_output_tee(self.queue_log_path)
- log("Running WebKit Commit Queue. %s" % datetime.now().strftime(self.log_date_format))
+ if not options.is_relaunch:
+ log("Running WebKit Commit Queue. %s" % datetime.now().strftime(self.log_date_format))
self.status_bot = StatusBot(host=options.status_host)
- while (True):
- # Either of these calls could throw URLError which shouldn't stop the queue.
- # We catch all exceptions just in case.
- try:
- # Fetch patches instead of just bug ids to that we validate reviewer/committer flags on every patch.
- patches = tool.bugs.fetch_patches_from_commit_queue(reject_invalid_patches=True)
- if not len(patches):
- self._update_status_and_sleep("Empty queue.")
- continue
- patch_ids = map(lambda patch: patch['id'], patches)
- first_bug_id = patches[0]['bug_id']
- log("%s in commit queue [%s]" % (pluralize('patch', len(patches)), ", ".join(patch_ids)))
-
- if not tool.buildbot.core_builders_are_green():
- self._update_status_and_sleep("Builders (http://build.webkit.org) are red.")
- continue
-
- self.status_bot.update_status("Landing patches from bug %s." % first_bug_id, bug_id=first_bug_id)
- except Exception, e:
- # Don't try tell the status bot, in case telling it causes an exception.
- self._sleep("Exception while checking queue and bots: %s." % e)
- continue
-
- # Try to land patches on the first bug in the queue before looping
- bug_log_path = os.path.join(self.bug_logs_directory, "%s.log" % first_bug_id)
- bug_log = self._add_log_to_output_tee(bug_log_path)
- bugzilla_tool_path = __file__ # re-execute this script
- bugzilla_tool_args = [bugzilla_tool_path, 'land-patches', '--force-clean', '--commit-queue', '--quiet', first_bug_id]
- WebKitLandingScripts.run_command_with_teed_output(bugzilla_tool_args, sys.stdout)
- self._remove_log_from_output_tee(bug_log)
-
- log("Finished WebKit Commit Queue. %s" % datetime.now().strftime(self.log_date_format))
- self._remove_log_from_output_tee(queue_log)
+ # Either of these calls could throw URLError which shouldn't stop the queue.
+ # We catch all exceptions just in case.
+ try:
+ # Fetch patches instead of just bug ids to that we validate reviewer/committer flags on every patch.
+ patches = tool.bugs.fetch_patches_from_commit_queue(reject_invalid_patches=True)
+ if not len(patches):
+ self._update_status_and_sleep("Empty queue.")
+ patch_ids = map(lambda patch: patch['id'], patches)
+ first_bug_id = patches[0]['bug_id']
+ log("%s in commit queue [%s]" % (pluralize('patch', len(patches)), ", ".join(patch_ids)))
+
+ red_builders_names = tool.buildbot.red_core_builders_names()
+ if red_builders_names:
+ red_builders_names = map(lambda name: '"%s"' % name, red_builders_names) # Add quotes around the names.
+ self._update_status_and_sleep("Builders [%s] are red. See http://build.webkit.org." % ", ".join(red_builders_names))
+
+ self.status_bot.update_status("Landing patches from bug %s." % first_bug_id, bug_id=first_bug_id)
+ except Exception, e:
+ # Don't try tell the status bot, in case telling it causes an exception.
+ self._sleep("Exception while checking queue and bots: %s." % e)
+
+ # Try to land patches on the first bug in the queue before looping
+ bug_log_path = os.path.join(self.bug_logs_directory, "%s.log" % first_bug_id)
+ bug_log = self._add_log_to_output_tee(bug_log_path)
+ bugzilla_tool_path = __file__ # re-execute this script
+ bugzilla_tool_args = [bugzilla_tool_path, 'land-patches', '--force-clean', '--commit-queue', '--quiet', first_bug_id]
+ try:
+ WebKitLandingScripts.run_and_throw_if_fail(bugzilla_tool_args)
+ except ScriptError, e:
+ # Unexpected failure! Mark the patch as commit-queue- and comment in the bug.
+ # exit(2) is a special exit code we use to indicate that the error was already handled by land-patches and we should keep looping anyway.
+ if e.exit_code != 2:
+ tool.bugs.reject_patch_from_commit_queue(patch['id'], "Unexpected failure when landing patch! Please file a bug against bugzilla-tool.\n%s" % e.message_with_output())
+ self._remove_log_from_output_tee(bug_log)
+ # self._remove_log_from_output_tee(queue_log) # implicit in the exec()
+ self._next_patch()
class NonWrappingEpilogIndentedHelpFormatter(IndentedHelpFormatter):
diff --git a/WebKitTools/Scripts/modules/bugzilla.py b/WebKitTools/Scripts/modules/bugzilla.py
index daf3f19..fe81b48 100644
--- a/WebKitTools/Scripts/modules/bugzilla.py
+++ b/WebKitTools/Scripts/modules/bugzilla.py
@@ -294,7 +294,18 @@ class Bugzilla:
self.authenticated = True
- def add_patch_to_bug(self, bug_id, patch_file_object, description, comment_text=None, mark_for_review=False):
+ def _fill_attachment_form(self, description, patch_file_object, comment_text=None, mark_for_review=False, mark_for_commit_queue=False, bug_id=None):
+ self.browser['description'] = description
+ self.browser['ispatch'] = ("1",)
+ self.browser['flag_type-1'] = ('?',) if mark_for_review else ('X',)
+ self.browser['flag_type-3'] = ('?',) if mark_for_commit_queue else ('X',)
+ if bug_id:
+ patch_name = "bug-%s-%s.patch" % (bug_id, timestamp())
+ else:
+ patch_name ="%s.patch" % timestamp()
+ self.browser.add_file(patch_file_object, "text/plain", patch_name, 'data')
+
+ def add_patch_to_bug(self, bug_id, patch_file_object, description, comment_text=None, mark_for_review=False, mark_for_commit_queue=False):
self.authenticate()
log('Adding patch "%s" to bug %s' % (description, bug_id))
@@ -304,13 +315,10 @@ class Bugzilla:
self.browser.open("%sattachment.cgi?action=enter&bugid=%s" % (self.bug_server_url, bug_id))
self.browser.select_form(name="entryform")
- self.browser['description'] = description
- self.browser['ispatch'] = ("1",)
+ self._fill_attachment_form(description, patch_file_object, mark_for_review=mark_for_review, mark_for_commit_queue=mark_for_commit_queue, bug_id=bug_id)
if comment_text:
log(comment_text)
self.browser['comment'] = comment_text
- self.browser['flag_type-1'] = ('?',) if mark_for_review else ('X',)
- self.browser.add_file(patch_file_object, "text/plain", "bug-%s-%s.patch" % (bug_id, timestamp()))
self.browser.submit()
def prompt_for_component(self, components):
@@ -334,7 +342,7 @@ class Bugzilla:
error_message = "\n" + '\n'.join([" " + line.strip() for line in text_lines if line.strip()])
raise BugzillaError("Bug not created: %s" % error_message)
- def create_bug_with_patch(self, bug_title, bug_description, component, patch_file_object, patch_description, cc, mark_for_review=False):
+ def create_bug_with_patch(self, bug_title, bug_description, component, patch_file_object, patch_description, cc, mark_for_review=False, mark_for_commit_queue=False):
self.authenticate()
log('Creating bug with patch description "%s"' % patch_description)
@@ -355,10 +363,8 @@ class Bugzilla:
if bug_description:
log(bug_description)
self.browser['comment'] = bug_description
- self.browser['description'] = patch_description
- self.browser['ispatch'] = ("1",)
- self.browser['flag_type-1'] = ('?',) if mark_for_review else ('X',)
- self.browser.add_file(patch_file_object, "text/plain", "%s.patch" % timestamp(), 'data')
+
+ self._fill_attachment_form(patch_description, patch_file_object, mark_for_review=mark_for_review, mark_for_commit_queue=mark_for_commit_queue)
response = self.browser.submit()
bug_id = self._check_create_bug_response(response.read())
diff --git a/WebKitTools/Scripts/modules/buildbot.py b/WebKitTools/Scripts/modules/buildbot.py
index 4478429..e948d8c 100644
--- a/WebKitTools/Scripts/modules/buildbot.py
+++ b/WebKitTools/Scripts/modules/buildbot.py
@@ -83,11 +83,19 @@ class BuildBot:
builders.append(builder)
return builders
- def core_builders_are_green(self):
+ def red_core_builders(self):
+ red_builders = []
for builder in self._builder_statuses_with_names_matching_regexps(self.builder_statuses(), self.core_builder_names_regexps):
if not builder['is_green']:
- return False
- return True
+ red_builders.append(builder)
+ return red_builders
+
+ def red_core_builders_names(self):
+ red_builders = self.red_core_builders()
+ return map(lambda builder: builder['name'], red_builders)
+
+ def core_builders_are_green(self):
+ return not self.red_core_builders()
def builder_statuses(self):
build_status_url = self.buildbot_server_url + 'one_box_per_builder'
diff --git a/WebKitTools/Scripts/modules/buildbot_unittest.py b/WebKitTools/Scripts/modules/buildbot_unittest.py
index 461e5a2..a85f2ea 100644
--- a/WebKitTools/Scripts/modules/buildbot_unittest.py
+++ b/WebKitTools/Scripts/modules/buildbot_unittest.py
@@ -91,6 +91,22 @@ class BuildBotTest(unittest.TestCase):
for key, expected_value in expected_parsing.items():
self.assertEquals(builder[key], expected_value, ("Builder %d parse failure for key: %s: Actual='%s' Expected='%s'" % (x, key, builder[key], expected_value)))
+ def test_core_builder_methods(self):
+ buildbot = BuildBot()
+
+ # Override builder_statuses function to not touch the network.
+ def example_builder_statuses(): # We could use instancemethod() to bind 'self' but we don't need to.
+ return BuildBotTest._expected_example_one_box_parsings
+ buildbot.builder_statuses = example_builder_statuses
+
+ buildbot.core_builder_names_regexps = [ 'Leopard', "Windows.*Build" ]
+ self.assertEquals(buildbot.red_core_builders_names(), [])
+ self.assertTrue(buildbot.core_builders_are_green())
+
+ buildbot.core_builder_names_regexps = [ 'SnowLeopard', 'Qt' ]
+ self.assertEquals(buildbot.red_core_builders_names(), [ u'SnowLeopard Intel Release', u'Qt Linux Release' ])
+ self.assertFalse(buildbot.core_builders_are_green())
+
def test_builder_name_regexps(self):
buildbot = BuildBot()
diff --git a/WebKitTools/Scripts/modules/committers.py b/WebKitTools/Scripts/modules/committers.py
index e157fb4..fc263eb 100644
--- a/WebKitTools/Scripts/modules/committers.py
+++ b/WebKitTools/Scripts/modules/committers.py
@@ -42,22 +42,28 @@ class Reviewer(Committer):
Committer.__init__(self, name, email)
self.can_review = True
-# All reviewers are committers, so this list is only of committers
-# who are not reviewers.
+# This is intended as a cannonical, machine-readable list of all non-reviewer committers for WebKit.
+# If your name is missing here and you are a committer, please add it. No review needed.
+# All reviewers are committers, so this list is only of committers who are not reviewers.
committers_unable_to_review = [
Committer("Aaron Boodman", "aa@chromium.org"),
Committer("Adam Langley", "agl@chromium.org"),
Committer("Albert J. Wong", "ajwong@chromium.org"),
+ Committer("Anton Muhin", "antonm@chromium.org"),
Committer("Antonio Gomes", "tonikitoo@webkit.org"),
Committer("Anthony Ricaud", "rik@webkit.org"),
Committer("Ben Murdoch", "benm@google.com"),
+ Committer("Chris Fleizach", "cfleizach@apple.com"),
Committer("Brent Fulgham", "bfulgham@webkit.org"),
Committer("Brian Weinstein", "bweinstein@apple.com"),
Committer("Cameron McCormack", "cam@webkit.org"),
+ Committer("Collin Jackson", "collinj@webkit.org"),
+ Committer("Csaba Osztrogonac", "ossy@webkit.org"),
Committer("Daniel Bates", "dbates@webkit.org"),
Committer("Drew Wilson", "atwilson@chromium.org"),
Committer("Dirk Schulze", "krit@webkit.org"),
Committer("Dmitry Titov", "dimich@chromium.org"),
+ Committer("Dumitru Daniliuc", "dumi@chromium.org"),
Committer("Eli Fidler", "eli@staikos.net"),
Committer("Eric Roman", "eroman@chromium.org"),
Committer("Fumitoshi Ukai", "ukai@chromium.org"),
@@ -69,38 +75,53 @@ committers_unable_to_review = [
Committer("Joseph Pecoraro", "joepeck@webkit.org"),
Committer("Julie Parent", "jparent@google.com"),
Committer("Kenneth Rohde Christiansen", "kenneth@webkit.org"),
+ Committer("Kent Tamura", "tkent@chromium.org"),
Committer("Laszlo Gombos", "laszlo.1.gombos@nokia.com"),
+ Committer("Mads Ager", "ager@chromium.org"),
+ Committer("Mike Belshe", "mike@belshe.com"),
Committer("Nate Chapin", "japhet@chromium.org"),
Committer("Ojan Vafai", "ojan@chromium.org"),
Committer("Pam Greene", "pam@chromium.org"),
Committer("Peter Kasting", "pkasting@google.com"),
Committer("Pierre d'Herbemont", "pdherbemont@free.fr"),
+ Committer("Roland Steiner", "rolandsteiner@chromium.org"),
Committer("Ryosuke Niwa", "rniwa@webkit.org"),
Committer("Scott Violet", "sky@chromium.org"),
Committer("Shinichiro Hamaji", "hamaji@chromium.org"),
+ Committer("Steve Block", "steveblock@google.com"),
Committer("Tony Chang", "tony@chromium.org"),
Committer("Yael Aharon", "yael.aharon@nokia.com"),
Committer("Yong Li", "yong.li@torchmobile.com"),
+ Committer("Yury Semikhatsky", "yurys@chromium.org"),
Committer("Zoltan Horvath", "zoltan@webkit.org"),
]
+# This is intended as a cannonical, machine-readable list of all reviewers for WebKit.
+# If your name is missing here and you are a reviewer, please add it. No review needed.
reviewers_list = [
Reviewer("Adam Barth", "abarth@webkit.org"),
+ Reviewer("Ada Chan", "adachan@apple.com"),
Reviewer("Adam Roben", "aroben@apple.com"),
Reviewer("Adam Treat", "treat@kde.org"),
Reviewer("Adele Peterson", "adele@apple.com"),
Reviewer("Alexey Proskuryakov", "ap@webkit.org"),
+ Reviewer("Alice Liu", "alice.liu@apple.com"),
+ Reviewer("Alp Toker", "alp@nuanti.com"),
Reviewer("Anders Carlsson", "andersca@apple.com"),
Reviewer("Antti Koivisto", "koivisto@iki.fi"),
Reviewer("Ariya Hidayat", "ariya.hidayat@trolltech.com"),
Reviewer("Brady Eidson", "beidson@apple.com"),
+ Reviewer("Cameron Zwarich", "zwarich@apple.com"),
Reviewer("Dan Bernstein", "mitz@webkit.org"),
Reviewer("Darin Adler", "darin@apple.com"),
Reviewer("Darin Fisher", "fishd@chromium.org"),
+ Reviewer("David Harrison", "harrison@apple.com"),
Reviewer("David Hyatt", "hyatt@apple.com"),
Reviewer("David Kilzer", "ddkilzer@webkit.org"),
Reviewer("David Levin", "levin@chromium.org"),
Reviewer("Dimitri Glazkov", "dglazkov@chromium.org"),
+ Reviewer("Don Melton", "gramps@apple.com"),
+ Reviewer("Dmitri Titov", "dimich@chromium.org"),
Reviewer("Eric Carlson", "eric.carlson@apple.com"),
Reviewer("Eric Seidel", "eric@webkit.org"),
Reviewer("Gavin Barraclough", "barraclough@apple.com"),
@@ -110,16 +131,22 @@ reviewers_list = [
Reviewer("Holger Freyther", "zecke@selfish.org"),
Reviewer("Jan Alonzo", "jmalonzo@gmail.com"),
Reviewer("John Sullivan", "sullivan@apple.com"),
+ Reviewer("Jon Honeycutt", "jhoneycutt@apple.com"),
Reviewer("Justin Garcia", "justin.garcia@apple.com"),
+ Reviewer("Kevin Decker", "kdecker@apple.com"),
Reviewer("Kevin McCullough", "kmccullough@apple.com"),
Reviewer("Kevin Ollivier", "kevino@theolliviers.com"),
+ Reviewer("Lars Knoll", "lars@trolltech.com"),
Reviewer("Maciej Stachowiak", "mjs@apple.com"),
Reviewer("Mark Rowe", "mrowe@apple.com"),
Reviewer("Nikolas Zimmermann", "zimmermann@kde.org"),
Reviewer("Oliver Hunt", "oliver@apple.com"),
+ Reviewer("Pavel Feldman", "pfeldman@chromium.org"),
+ Reviewer("Rob Buis", "rwlbuis@gmail.com"),
Reviewer("Sam Weinig", "sam@webkit.org"),
Reviewer("Simon Fraser", "simon.fraser@apple.com"),
Reviewer("Simon Hausmann", "hausmann@webkit.org"),
+ Reviewer("Stephanie Lewis", "slewis@apple.com"),
Reviewer("Steve Falkenburg", "sfalken@apple.com"),
Reviewer("Timothy Hatcher", "timothy@hatcher.name"),
Reviewer(u'Tor Arne Vestb\xf8', "vestbo@webkit.org"),
diff --git a/WebKitTools/Scripts/modules/cpp_style.py b/WebKitTools/Scripts/modules/cpp_style.py
index 0c9dfa0..485b07c 100644
--- a/WebKitTools/Scripts/modules/cpp_style.py
+++ b/WebKitTools/Scripts/modules/cpp_style.py
@@ -1533,16 +1533,15 @@ def check_spacing(filename, clean_lines, line_number, error):
# Don't try to do spacing checks for operator methods
line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line)
-
- # We allow no-spaces around = within an if: "if ( (a=Foo()) == 0 )".
- # Otherwise not. Note we only check for non-spaces on *both* sides;
- # sometimes people put non-spaces on one side when aligning ='s among
- # many lines (not that this is behavior that I approve of...)
- if search(r'[\w.]=[\w.]', line) and not search(r'\b(if|while) ', line):
+ # Don't try to do spacing checks for #include statements at minimum it
+ # messes up checks for spacing around /
+ if match(r'\s*#\s*include', line):
+ return
+ if search(r'[\w.]=[\w.]', line):
error(filename, line_number, 'whitespace/operators', 4,
'Missing spaces around =')
- # FIXME: It's not ok to have spaces around binary operators like + - * / .
+ # FIXME: It's not ok to have spaces around binary operators like .
# You should always have whitespace around binary operators.
# Alas, we can't test < or > because they're legitimately used sans spaces
@@ -1559,12 +1558,6 @@ def check_spacing(filename, clean_lines, line_number, error):
if matched:
error(filename, line_number, 'whitespace/operators', 3,
'Missing spaces around %s' % matched.group(1))
- # We allow no-spaces around << and >> when used like this: 10<<20, but
- # not otherwise (particularly, not when used as streams)
- matched = search(r'[^0-9\s](<<|>>)[^0-9\s=]', line)
- if matched:
- error(filename, line_number, 'whitespace/operators', 3,
- 'Missing spaces around %s' % matched.group(1))
# There shouldn't be space around unary operators
matched = search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line)
@@ -1699,50 +1692,32 @@ def check_namespace_indentation(filename, clean_lines, line_number, file_extensi
if not namespace_match:
return
- namespace_indentation = namespace_match.group('namespace_indentation')
-
- is_header_file = file_extension == 'h'
- is_implementation_file = not is_header_file
+ current_indentation_level = len(namespace_match.group('namespace_indentation'))
+ if current_indentation_level > 0:
+ error(filename, line_number, 'whitespace/indent', 4,
+ 'namespace should never be indented.')
+ return
+ looking_for_semicolon = False;
line_offset = 0
-
- if is_header_file:
- inner_indentation = namespace_indentation + ' ' * 4
-
- for current_line in clean_lines.raw_lines[line_number + 1:]:
- line_offset += 1
-
- # Skip not only empty lines but also those with preprocessor directives.
- # Goto labels don't occur in header files, so no need to check for those.
- if current_line.strip() == '' or current_line.startswith('#'):
- continue
-
- if not current_line.startswith(inner_indentation):
- # If something unindented was discovered, make sure it's a closing brace.
- if not current_line.startswith(namespace_indentation + '}'):
+ in_preprocessor_directive = False;
+ for current_line in clean_lines.elided[line_number + 1:]:
+ line_offset += 1
+ if not current_line.strip():
+ continue
+ if not current_indentation_level:
+ if not (in_preprocessor_directive or looking_for_semicolon):
+ if not match(r'\S', current_line):
error(filename, line_number + line_offset, 'whitespace/indent', 4,
- 'In a header, code inside a namespace should be indented.')
- break
-
- if is_implementation_file:
- for current_line in clean_lines.raw_lines[line_number + 1:]:
- line_offset += 1
-
- # Skip not only empty lines but also those with (goto) labels.
- # The goto label regexp accepts spaces or the beginning of a
- # comment (if anything) after the initial colon.
- if current_line.strip() == '' or match(r'\w+\s*:([\s\/].*)?$', current_line):
- continue
-
- remaining_line = current_line[len(namespace_indentation):]
- if not match(r'\S', remaining_line):
- error(filename, line_number + line_offset, 'whitespace/indent', 4,
- 'In an implementation file, code inside a namespace should not be indented.')
-
- # Just check the first non-empty line in any case, because
- # otherwise we would need to count opened and closed braces,
- # which is obviously a lot more complicated.
- break
-
+ 'Code inside a namespace should not be indented.')
+ if in_preprocessor_directive or (current_line.strip()[0] == '#'): # This takes care of preprocessor directive syntax.
+ in_preprocessor_directive = current_line[-1] == '\\'
+ else:
+ looking_for_semicolon = ((current_line.find(';') == -1) and (current_line.strip()[-1] != '}')) or (current_line[-1] == '\\')
+ else:
+ looking_for_semicolon = False; # If we have a brace we may not need a semicolon.
+ current_indentation_level += current_line.count('{') - current_line.count('}')
+ if current_indentation_level < 0:
+ break;
def check_using_std(filename, clean_lines, line_number, error):
"""Looks for 'using std::foo;' statements which should be replaced with 'using namespace std;'.
diff --git a/WebKitTools/Scripts/modules/cpp_style_unittest.py b/WebKitTools/Scripts/modules/cpp_style_unittest.py
index 322356e..d5637f4 100644
--- a/WebKitTools/Scripts/modules/cpp_style_unittest.py
+++ b/WebKitTools/Scripts/modules/cpp_style_unittest.py
@@ -1265,6 +1265,12 @@ class CppStyleTest(CppStyleTestBase):
self.assert_lint('a<Foo&> t <<= &b | &c;', '')
self.assert_lint('a<Foo*> t <<= &b & &c; // Test', '')
self.assert_lint('a<Foo*> t <<= *b / &c; // Test', '')
+ self.assert_lint('if (a=b == 1)', 'Missing spaces around = [whitespace/operators] [4]')
+ self.assert_lint('a = 1<<20', 'Missing spaces around << [whitespace/operators] [3]')
+ self.assert_lint('if (a = b == 1)', '')
+ self.assert_lint('a = 1 << 20', '')
+ self.assert_multi_line_lint('#include "config.h"\n#include <sys/io.h>\n',
+ '')
def test_spacing_before_last_semicolon(self):
self.assert_lint('call_function() ;',
@@ -2806,40 +2812,39 @@ class WebKitStyleTest(CppStyleTestBase):
'Weird number of spaces at line-start. Are you using a 4-space indent? [whitespace/indent] [3]')
# FIXME: No tests for 8-spaces.
- # 3. In a header, code inside a namespace should be indented.
+ # 3. In a header, code inside a namespace should not be indented.
self.assert_multi_line_lint(
'namespace WebCore {\n\n'
- ' class Document {\n'
- ' int myVariable;\n'
- ' };\n'
+ 'class Document {\n'
+ ' int myVariable;\n'
+ '};\n'
'}',
'',
'foo.h')
self.assert_multi_line_lint(
'namespace OuterNamespace {\n'
' namespace InnerNamespace {\n'
- ' class Document {\n'
- ' };\n'
- ' };\n'
+ ' class Document {\n'
+ '};\n'
+ '};\n'
'}',
- '',
+ ['Code inside a namespace should not be indented. [whitespace/indent] [4]', 'namespace should never be indented. [whitespace/indent] [4]'],
'foo.h')
self.assert_multi_line_lint(
'namespace WebCore {\n'
'#if 0\n'
' class Document {\n'
- ' };\n'
+ '};\n'
'#endif\n'
'}',
- '',
+ 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
'foo.h')
self.assert_multi_line_lint(
'namespace WebCore {\n'
'class Document {\n'
'};\n'
'}',
- 'In a header, code inside a namespace should be indented.'
- ' [whitespace/indent] [4]',
+ '',
'foo.h')
# 4. In an implementation file (files with the extension .cpp, .c
@@ -2858,14 +2863,52 @@ class WebKitStyleTest(CppStyleTestBase):
'namespace OuterNamespace {\n'
'namespace InnerNamespace {\n'
'Document::Foo() { }\n'
- '}',
- '',
+ ' void* p;\n'
+ '}\n'
+ '}\n',
+ 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
'foo.cpp')
self.assert_multi_line_lint(
- ' namespace WebCore {\n\n'
- 'start: // Pointless code, but tests the label regexp.\n'
- ' goto start;\n'
- ' }',
+ 'namespace OuterNamespace {\n'
+ 'namespace InnerNamespace {\n'
+ 'Document::Foo() { }\n'
+ '}\n'
+ ' void* p;\n'
+ '}\n',
+ 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
+ 'foo.cpp')
+ self.assert_multi_line_lint(
+ 'namespace WebCore {\n\n'
+ ' const char* foo = "start:;"\n'
+ ' "dfsfsfs";\n'
+ '}\n',
+ 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
+ 'foo.cpp')
+ self.assert_multi_line_lint(
+ 'namespace WebCore {\n\n'
+ 'const char* foo(void* a = ";", // ;\n'
+ ' void* b);\n'
+ ' void* p;\n'
+ '}\n',
+ 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
+ 'foo.cpp')
+ self.assert_multi_line_lint(
+ 'namespace WebCore {\n\n'
+ 'const char* foo[] = {\n'
+ ' "void* b);", // ;\n'
+ ' "asfdf",\n'
+ ' }\n'
+ ' void* p;\n'
+ '}\n',
+ 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
+ 'foo.cpp')
+ self.assert_multi_line_lint(
+ 'namespace WebCore {\n\n'
+ 'const char* foo[] = {\n'
+ ' "void* b);", // }\n'
+ ' "asfdf",\n'
+ ' }\n'
+ '}\n',
'',
'foo.cpp')
self.assert_multi_line_lint(
@@ -2875,15 +2918,30 @@ class WebKitStyleTest(CppStyleTestBase):
'start: // infinite loops are fun!\n'
' goto start;\n'
' }',
- '',
+ 'namespace should never be indented. [whitespace/indent] [4]',
'foo.cpp')
self.assert_multi_line_lint(
'namespace WebCore {\n'
' Document::Foo() { }\n'
'}',
- 'In an implementation file, code inside a namespace should not be indented.'
+ 'Code inside a namespace should not be indented.'
' [whitespace/indent] [4]',
'foo.cpp')
+ self.assert_multi_line_lint(
+ 'namespace WebCore {\n'
+ '#define abc(x) x; \\\n'
+ ' x\n'
+ '}',
+ '',
+ 'foo.cpp')
+ self.assert_multi_line_lint(
+ 'namespace WebCore {\n'
+ '#define abc(x) x; \\\n'
+ ' x\n'
+ ' void* x;'
+ '}',
+ 'Code inside a namespace should not be indented. [whitespace/indent] [4]',
+ 'foo.cpp')
# 5. A case label should line up with its switch statement. The
# case statement is indented.
@@ -3246,7 +3304,7 @@ class WebKitStyleTest(CppStyleTestBase):
'')
self.assert_multi_line_lint(
'namespace WebCore {\n'
- ' int foo;\n'
+ 'int foo;\n'
'};\n',
'')
self.assert_multi_line_lint(
diff --git a/WebKitTools/Scripts/modules/scm.py b/WebKitTools/Scripts/modules/scm.py
index 3daecbc..3ffa23b 100644
--- a/WebKitTools/Scripts/modules/scm.py
+++ b/WebKitTools/Scripts/modules/scm.py
@@ -124,9 +124,14 @@ class SCM:
@staticmethod
def run_command(args, cwd=None, input=None, error_handler=default_error_handler, return_exit_code=False):
- stdin = subprocess.PIPE if input else None
+ if hasattr(input, 'read'): # Check if the input is a file.
+ stdin = input
+ string_to_communicate = None
+ else:
+ stdin = subprocess.PIPE if input else None
+ string_to_communicate = input
process = subprocess.Popen(args, stdin=stdin, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=cwd)
- output = process.communicate(input)[0].rstrip()
+ output = process.communicate(string_to_communicate)[0].rstrip()
exit_code = process.wait()
if exit_code:
script_error = ScriptError(script_args=args, exit_code=exit_code, output=output, cwd=cwd)
@@ -166,11 +171,8 @@ class SCM:
args = [self.script_path('svn-apply'), '--reviewer', patch['reviewer']]
if force:
args.append('--force')
- patch_apply_process = subprocess.Popen(args, stdin=curl_process.stdout)
- return_code = patch_apply_process.wait()
- if return_code:
- raise ScriptError(message="Patch %s from bug %s failed to download and apply." % (patch['url'], patch['bug_id']))
+ self.run_command(args, input=curl_process.stdout)
def run_status_and_extract_filenames(self, status_command, status_regexp):
filenames = []
@@ -392,7 +394,7 @@ class Git(SCM):
@classmethod
def in_working_directory(cls, path):
- return cls.run_command(['git', 'rev-parse', '--is-inside-work-tree'], cwd=path) == "true"
+ return cls.run_command(['git', 'rev-parse', '--is-inside-work-tree'], cwd=path, error_handler=ignore_error) == "true"
@classmethod
def find_checkout_root(cls, path):
diff --git a/WebKitTools/Scripts/modules/scm_unittest.py b/WebKitTools/Scripts/modules/scm_unittest.py
index 58494a0..784303f 100644
--- a/WebKitTools/Scripts/modules/scm_unittest.py
+++ b/WebKitTools/Scripts/modules/scm_unittest.py
@@ -95,8 +95,6 @@ class SVNTestRepository:
@classmethod
def setup(cls, test_object):
- test_object.original_path = os.path.abspath('.')
-
# Create an test SVN repository
test_object.svn_repo_path = tempfile.mkdtemp(suffix="svn_test_repo")
test_object.svn_repo_url = "file://%s" % test_object.svn_repo_path # Not sure this will work on windows
@@ -115,23 +113,30 @@ class SVNTestRepository:
run(['rm', '-rf', test_object.svn_repo_path])
run(['rm', '-rf', test_object.svn_checkout_path])
+# For testing the SCM baseclass directly.
+class SCMClassTests(unittest.TestCase):
+ def setUp(self):
+ self.dev_null = open(os.devnull, "w") # Used to make our Popen calls quiet.
-class SCMTest(unittest.TestCase):
- def _create_patch(self, patch_contents):
- patch_path = os.path.join(self.svn_checkout_path, 'patch.diff')
- write_into_file_at_path(patch_path, patch_contents)
- patch = {}
- patch['reviewer'] = 'Joe Cool'
- patch['bug_id'] = '12345'
- patch['url'] = 'file://%s' % urllib.pathname2url(patch_path)
- return patch
+ def tearDown(self):
+ self.dev_null.close()
- def _setup_webkittools_scripts_symlink(self, local_scm):
- webkit_scm = detect_scm_system(self.original_path)
- webkit_scripts_directory = webkit_scm.scripts_directory()
- local_scripts_directory = local_scm.scripts_directory()
- os.mkdir(os.path.dirname(local_scripts_directory))
- os.symlink(webkit_scripts_directory, local_scripts_directory)
+ def test_run_command_with_pipe(self):
+ input_process = subprocess.Popen(['/bin/echo', 'foo\nbar'], stdout=subprocess.PIPE, stderr=self.dev_null)
+ self.assertEqual(SCM.run_command(['/usr/bin/grep', 'bar'], input=input_process.stdout), "bar")
+
+ # Test the non-pipe case too:
+ self.assertEqual(SCM.run_command(['/usr/bin/grep', 'bar'], input="foo\nbar"), "bar")
+
+ command_returns_non_zero = ['/bin/sh', '--invalid-option']
+ # Test when the input pipe process fails.
+ input_process = subprocess.Popen(command_returns_non_zero, stdout=subprocess.PIPE, stderr=self.dev_null)
+ self.assertTrue(input_process.poll() != 0)
+ self.assertRaises(ScriptError, SCM.run_command, ['/usr/bin/grep', 'bar'], input=input_process.stdout)
+
+ # Test when the run_command process fails.
+ input_process = subprocess.Popen(['/bin/echo', 'foo\nbar'], stdout=subprocess.PIPE, stderr=self.dev_null) # grep shows usage and calls exit(2) when called w/o arguments.
+ self.assertRaises(ScriptError, SCM.run_command, command_returns_non_zero, input=input_process.stdout)
def test_error_handlers(self):
git_failure_message="Merge conflict during commit: Your file or directory 'WebCore/ChangeLog' is probably out-of-date: resource out of date; try updating at /usr/local/libexec/git-core//git-svn line 469"
@@ -152,6 +157,24 @@ svn: resource out of date; try updating
self.assertRaises(ScriptError, commit_error_handler, ScriptError(output='blah blah blah'))
+# GitTest and SVNTest inherit from this so any test_ methods here will be run once for this class and then once for each subclass.
+class SCMTest(unittest.TestCase):
+ def _create_patch(self, patch_contents):
+ patch_path = os.path.join(self.svn_checkout_path, 'patch.diff')
+ write_into_file_at_path(patch_path, patch_contents)
+ patch = {}
+ patch['reviewer'] = 'Joe Cool'
+ patch['bug_id'] = '12345'
+ patch['url'] = 'file://%s' % urllib.pathname2url(patch_path)
+ return patch
+
+ def _setup_webkittools_scripts_symlink(self, local_scm):
+ webkit_scm = detect_scm_system(os.path.dirname(os.path.abspath(__file__)))
+ webkit_scripts_directory = webkit_scm.scripts_directory()
+ local_scripts_directory = local_scm.scripts_directory()
+ os.mkdir(os.path.dirname(local_scripts_directory))
+ os.symlink(webkit_scripts_directory, local_scripts_directory)
+
# Tests which both GitTest and SVNTest should run.
# FIXME: There must be a simpler way to add these w/o adding a wrapper method to both subclasses
def _shared_test_commit_with_message(self):
@@ -188,7 +211,6 @@ class SVNTest(SCMTest):
def tearDown(self):
SVNTestRepository.tear_down(self)
- os.chdir(self.original_path)
def test_create_patch_is_full_patch(self):
test_dir_path = os.path.join(self.svn_checkout_path, 'test_dir')
@@ -284,7 +306,6 @@ class GitTest(SCMTest):
def tearDown(self):
SVNTestRepository.tear_down(self)
self._tear_down_git_clone_of_svn_repository()
- os.chdir(self.original_path)
def test_detection(self):
scm = detect_scm_system(self.git_checkout_path)
diff --git a/WebKitTools/Scripts/pdevenv b/WebKitTools/Scripts/pdevenv
index 818e4ee..cab8b16 100755
--- a/WebKitTools/Scripts/pdevenv
+++ b/WebKitTools/Scripts/pdevenv
@@ -6,6 +6,9 @@ use warnings;
use File::Temp qw/tempfile/;
use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
my ($fh, $path) = tempfile(UNLINK => 0, SUFFIX => '.cmd') or die;
chomp(my $vcBin = `cygpath -w "$FindBin::Bin/../vcbin"`);
@@ -28,8 +31,15 @@ if ($ENV{'VS80COMNTOOLS'}) {
print $fh "\@echo off\n\n";
print $fh "call \"\%" . $vsToolsVar . "\%\\vsvars32.bat\"\n\n";
print $fh "set PATH=$vcBin;$scriptsPath;\%PATH\%\n\n";
-print $fh "IF EXIST \"\%VSINSTALLDIR\%\\Common7\\IDE\\devenv.com\" (devenv.com /useenv " . join(" ", @ARGV) . ") ELSE ";
-print $fh "VCExpress.exe /useenv " . join(" ", @ARGV) . "\n";
+
+my $useenv = "/useenv ";
+if (isChromium()) {
+ $useenv = "";
+}
+
+print $fh "IF EXIST \"\%VSINSTALLDIR\%\\Common7\\IDE\\devenv.com\" (devenv.com " . $useenv . join(" ", @ARGV) . ") ELSE ";
+print $fh "VCExpress.exe " . $useenv . join(" ", @ARGV) . "\n";
+
close $fh;
diff --git a/WebKitTools/Scripts/prepare-ChangeLog b/WebKitTools/Scripts/prepare-ChangeLog
index ed31005..dd864df 100755
--- a/WebKitTools/Scripts/prepare-ChangeLog
+++ b/WebKitTools/Scripts/prepare-ChangeLog
@@ -85,7 +85,6 @@ sub isConflictStatus($);
sub statusDescription($$$$);
sub propertyChangeDescription($);
sub extractLineRange($);
-sub canonicalizePath($);
sub testListForChangeLog(@);
sub get_function_line_ranges($$);
sub get_function_line_ranges_for_c($$);
@@ -95,7 +94,6 @@ sub method_decl_to_selector($);
sub processPaths(\@);
sub reviewerAndDescriptionForGitCommit($);
sub normalizeLineEndings($$);
-sub normalizePath($);
sub decodeEntities($);
# Project time zone for Cupertino, CA, US
@@ -429,24 +427,6 @@ if ($openChangeLogs && @logs) {
# Done.
exit;
-sub canonicalizePath($)
-{
- my ($file) = @_;
-
- # Remove extra slashes and '.' directories in path
- $file = File::Spec->canonpath($file);
-
- # Remove '..' directories in path
- my @dirs = ();
- foreach my $dir (File::Spec->splitdir($file)) {
- if ($dir eq '..' && $#dirs >= 0 && $dirs[$#dirs] ne '..') {
- pop(@dirs);
- } else {
- push(@dirs, $dir);
- }
- }
- return ($#dirs >= 0) ? File::Spec->catdir(@dirs) : ".";
-}
sub changeLogDate($)
{
@@ -1717,13 +1697,6 @@ sub normalizeLineEndings($$)
return $string;
}
-sub normalizePath($)
-{
- my ($path) = @_;
- $path =~ s/\\/\//g;
- return $path;
-}
-
sub decodeEntities($)
{
my ($text) = @_;
diff --git a/WebKitTools/Scripts/resolve-ChangeLogs b/WebKitTools/Scripts/resolve-ChangeLogs
index db497f9..1a2d2af 100755
--- a/WebKitTools/Scripts/resolve-ChangeLogs
+++ b/WebKitTools/Scripts/resolve-ChangeLogs
@@ -44,7 +44,6 @@ sub canonicalRelativePath($);
sub conflictFiles($);
sub findChangeLog($);
sub findUnmergedChangeLogs();
-sub fixChangeLogPatch($);
sub fixMergedChangeLogs($;@);
sub fixOneMergedChangeLog($);
sub hasGitUnmergedFiles();
@@ -56,7 +55,6 @@ sub resolveChangeLog($);
sub resolveConflict($);
sub showStatus($;$);
sub usageAndExit();
-sub normalizePath($);
my $isGit = isGit();
my $isSVN = isSVN();
@@ -281,57 +279,6 @@ sub findUnmergedChangeLogs()
return @results;
}
-sub fixChangeLogPatch($)
-{
- my $patch = shift;
- my $contextLineCount = 3;
-
- return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\n( .*\n)+(\+.*\n)+( .*\n){$contextLineCount}$/m;
- my ($oldLineCount, $newLineCount) = ($1, $2);
- return $patch if $oldLineCount <= $contextLineCount;
-
- # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
- # have lines of context at the top of a patch when the existing entry has the same
- # date and author as the new entry. This nifty loop alters a ChangeLog patch so
- # that the added lines ("+") in the patch always start at the beginning of the
- # patch and there are no initial lines of context.
- my $newPatch;
- my $lineCountInState = 0;
- my $oldContentLineCountReduction = $oldLineCount - $contextLineCount;
- my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction;
- my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4);
- my $state = $stateHeader;
- foreach my $line (split(/\n/, $patch)) {
- $lineCountInState++;
- if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) {
- $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@";
- $lineCountInState = 0;
- $state = $statePreContext;
- } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") {
- $line = "+" . substr($line, 1);
- if ($lineCountInState == $oldContentLineCountReduction) {
- $lineCountInState = 0;
- $state = $stateNewChanges;
- }
- } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") {
- # No changes to these lines
- if ($lineCountInState == $newContentLineCountWithoutContext) {
- $lineCountInState = 0;
- $state = $statePostContext;
- }
- } elsif ($state == $statePostContext) {
- if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) {
- $line = " " . substr($line, 1);
- } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") {
- next; # Discard
- }
- }
- $newPatch .= $line . "\n";
- }
-
- return $newPatch;
-}
-
sub fixMergedChangeLogs($;@)
{
my $revisionRange = shift;
@@ -408,7 +355,7 @@ sub fixOneMergedChangeLog($)
close FILE;
# Apply the new patch
- open(PATCH, "| patch -p1 $file > /dev/null") or die $!;
+ open(PATCH, "| patch -p1 $file > " . File::Spec->devnull()) or die $!;
print PATCH $newPatch;
close(PATCH) or die $!;
@@ -460,7 +407,7 @@ sub mergeChanges($$$)
unlink("${fileNewer}.orig");
unlink("${fileNewer}.rej");
- open(PATCH, "| patch --fuzz=3 --binary $fileNewer > /dev/null") or die $!;
+ open(PATCH, "| patch --fuzz=3 --binary $fileNewer > " . File::Spec->devnull()) or die $!;
print PATCH fixChangeLogPatch($patch);
close(PATCH);
@@ -571,9 +518,3 @@ sub showStatus($;$)
}
}
-sub normalizePath($)
-{
- my ($path) = @_;
- $path =~ s/\\/\//g;
- return $path;
-}
diff --git a/WebKitTools/Scripts/run-iexploder-tests b/WebKitTools/Scripts/run-iexploder-tests
index f5e8a6c..ed5ecd6 100755
--- a/WebKitTools/Scripts/run-iexploder-tests
+++ b/WebKitTools/Scripts/run-iexploder-tests
@@ -32,6 +32,7 @@ use strict;
use warnings;
use Cwd;
+use File::Spec;
use FindBin;
use Getopt::Long;
use IPC::Open2;
@@ -149,7 +150,7 @@ sub openHTTPDIfNeeded()
"-c", "User \"#$<\"");
my $retryCount = 20;
- while (system("/usr/bin/curl -q --silent --stderr - --output /dev/null $listen") && $retryCount) {
+ while (system("/usr/bin/curl -q --silent --stderr - --output " . File::Spec->devnull() . " $listen") && $retryCount) {
sleep 1;
--$retryCount;
}
diff --git a/WebKitTools/Scripts/run-javascriptcore-tests b/WebKitTools/Scripts/run-javascriptcore-tests
index 865ae1d..fb4c388 100755
--- a/WebKitTools/Scripts/run-javascriptcore-tests
+++ b/WebKitTools/Scripts/run-javascriptcore-tests
@@ -100,21 +100,10 @@ if (!defined($root) && !$skipBuild) {
}
-my $productDir = productDir();
-
-$productDir .= "/JavaScriptCore" if isQt();
-$productDir .= "/Programs" if isGtk();
+my $productDir = jscProductDir();
$ENV{DYLD_FRAMEWORK_PATH} = $productDir;
setPathForRunningWebKitApp(\%ENV) if isCygwin();
-sub jscPath($)
-{
- my ($productDir) = @_;
- my $jscName = "jsc";
- $jscName .= "_debug" if (isCygwin() && ($configuration eq "Debug"));
- return "$productDir/$jscName";
-}
-
sub testapiPath($)
{
my ($productDir) = @_;
diff --git a/WebKitTools/Scripts/run-jsc b/WebKitTools/Scripts/run-jsc
index 20dc5e8..e5341c1 100755
--- a/WebKitTools/Scripts/run-jsc
+++ b/WebKitTools/Scripts/run-jsc
@@ -30,6 +30,7 @@
use strict;
use warnings;
+use File::Spec;
use FindBin;
use lib $FindBin::Bin;
use Getopt::Long;
@@ -43,10 +44,10 @@ GetOptions("count|c=i" => \$count,
"verbose|v" => \$verbose);
die "$usage\n" if (@ARGV < 1);
-my $jsc = productDir() . "/jsc @ARGV";
-$jsc .= " 2> /dev/null" unless $verbose;
+my $jsc = jscProductDir() . "/jsc @ARGV";
+$jsc .= " 2> " . File::Spec->devnull() unless $verbose;
-my $dyld = productDir();
+my $dyld = jscProductDir();
$ENV{"DYLD_FRAMEWORK_PATH"} = $dyld;
print STDERR "Running $count time(s): DYLD_FRAMEWORK_PATH=$dyld $jsc\n";
diff --git a/WebKitTools/Scripts/run-launcher b/WebKitTools/Scripts/run-launcher
index ee462ba..e12a64a 100755
--- a/WebKitTools/Scripts/run-launcher
+++ b/WebKitTools/Scripts/run-launcher
@@ -49,6 +49,8 @@ if (isQt()) {
my $libDir = catdir(productDir(), 'lib');
$launcherPath = catdir($launcherPath, "bin", "QtLauncher");
+ $ENV{QTWEBKIT_PLUGIN_PATH} = catdir($libDir, 'plugins');
+
print "Starting webkit launcher, running against the built WebKit in $libDir...\n";
if (isDarwin()) {
$ENV{DYLD_LIBRARY_PATH} = $ENV{DYLD_LIBRARY_PATH} ? "$libDir:$ENV{DYLD_LIBRARY_PATH}" : $libDir;
diff --git a/WebKitTools/Scripts/run-mangleme-tests b/WebKitTools/Scripts/run-mangleme-tests
index 93b7894..43ac74b 100755
--- a/WebKitTools/Scripts/run-mangleme-tests
+++ b/WebKitTools/Scripts/run-mangleme-tests
@@ -32,6 +32,7 @@ use strict;
use warnings;
use Cwd;
+use File::Spec;
use FindBin;
use Getopt::Long;
use IPC::Open2;
@@ -152,7 +153,7 @@ sub openHTTPDIfNeeded()
"-c", "User \"#$<\"");
my $retryCount = 20;
- while (system("/usr/bin/curl -q --silent --stderr - --output /dev/null $listen") && $retryCount) {
+ while (system("/usr/bin/curl -q --silent --stderr - --output " . File::Spec->devnull() . " $listen") && $retryCount) {
sleep 1;
--$retryCount;
}
diff --git a/WebKitTools/Scripts/run-sunspider b/WebKitTools/Scripts/run-sunspider
index 367fd06..e63f5d1 100755
--- a/WebKitTools/Scripts/run-sunspider
+++ b/WebKitTools/Scripts/run-sunspider
@@ -103,23 +103,12 @@ sub setupEnvironmentForExecution($)
# FIXME: Other platforms may wish to augment this method to use LD_LIBRARY_PATH, etc.
}
-sub jscPath($)
-{
- my ($productDir) = @_;
- my $jscName = "jsc";
- $jscName .= "_debug" if (isCygwin() && ($configuration eq "Debug"));
- return "$productDir/$jscName";
-}
-
buildJSC();
chdirWebKit();
chdir("SunSpider");
-my $productDir = productDir();
-# FIXME: This hack should be pushed down into productDir()
-$productDir .= "/JavaScriptCore" if isQt();
-$productDir .= "/Programs" if isGtk();
+my $productDir = jscProductDir();
setupEnvironmentForExecution($productDir);
my @args = ("--shell", jscPath($productDir), "--runs", $testRuns);
diff --git a/WebKitTools/Scripts/run-webkit-tests b/WebKitTools/Scripts/run-webkit-tests
index a08a53c..6056035 100755
--- a/WebKitTools/Scripts/run-webkit-tests
+++ b/WebKitTools/Scripts/run-webkit-tests
@@ -321,7 +321,7 @@ if (!defined($root)) {
local *DEVNULL;
my ($childIn, $childOut, $childErr);
if ($quiet) {
- open(DEVNULL, ">", File::Spec->devnull) or die "Failed to open /dev/null";
+ open(DEVNULL, ">", File::Spec->devnull()) or die "Failed to open /dev/null";
$childOut = ">&DEVNULL";
$childErr = ">&DEVNULL";
} else {
@@ -1351,7 +1351,7 @@ sub openHTTPDIfNeeded()
open2(\*HTTPDIN, \*HTTPDOUT, $httpdPath, @args);
my $retryCount = 20;
- while (system("/usr/bin/curl -q --silent --stderr - --output /dev/null $listen") && $retryCount) {
+ while (system("/usr/bin/curl -q --silent --stderr - --output " . File::Spec->devnull() . " $listen") && $retryCount) {
sleep 1;
--$retryCount;
}
diff --git a/WebKitTools/Scripts/sunspider-compare-results b/WebKitTools/Scripts/sunspider-compare-results
index ce87a23..a207d7a 100755
--- a/WebKitTools/Scripts/sunspider-compare-results
+++ b/WebKitTools/Scripts/sunspider-compare-results
@@ -107,9 +107,7 @@ sub pathToJSC()
buildJSC();
- my $productDir = productDir();
- # FIXME: This hack should be pushed down into productDir()
- $productDir .= "/JavaScriptCore" if (isQt() or isGtk());
+ my $productDir = jscProductDir();
setupEnvironmentForExecution($productDir);
return pathToBuiltJSC($productDir);
diff --git a/WebKitTools/Scripts/svn-apply b/WebKitTools/Scripts/svn-apply
index 19c8c56..7d14e3a 100755
--- a/WebKitTools/Scripts/svn-apply
+++ b/WebKitTools/Scripts/svn-apply
@@ -74,15 +74,12 @@ use VCSUtils;
sub addDirectoriesIfNeeded($);
sub applyPatch($$;$);
sub checksum($);
-sub fixChangeLogPatch($);
-sub gitdiff2svndiff($);
sub handleBinaryChange($$);
sub isDirectoryEmptyForRemoval($);
sub patch($);
sub removeDirectoriesIfNeeded();
sub setChangeLogDateAndReviewer($$);
sub removeEOL($);
-sub svnStatus($);
# These should be replaced by an scm class/module:
sub scmKnowsOfFile($);
@@ -178,8 +175,9 @@ if ($merge) {
die "--merge is currently only supported for SVN" unless isSVN();
# How do we handle Git patches applied to an SVN checkout here?
for my $file (sort keys %versions) {
- print "Getting version $versions{$file} of $file\n";
- system "svn", "update", "-r", $versions{$file}, $file;
+ my $version = $versions{$file};
+ print "Getting version $version of $file\n";
+ system("svn", "update", "-r", $version, $file) == 0 or die "Failed to run svn update -r $version $file.";
}
}
@@ -258,74 +256,6 @@ sub checksum($)
return $checksum;
}
-sub fixChangeLogPatch($)
-{
- my $patch = shift;
- my $contextLineCount = 3;
-
- return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\r?\n( .*\r?\n)+(\+.*\r?\n)+( .*\r?\n){$contextLineCount}$/m;
- my ($oldLineCount, $newLineCount) = ($1, $2);
- return $patch if $oldLineCount <= $contextLineCount;
-
- # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
- # have lines of context at the top of a patch when the existing entry has the same
- # date and author as the new entry. This nifty loop alters a ChangeLog patch so
- # that the added lines ("+") in the patch always start at the beginning of the
- # patch and there are no initial lines of context.
- my $newPatch;
- my $lineCountInState = 0;
- my $oldContentLineCountReduction = $oldLineCount - $contextLineCount;
- my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction;
- my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4);
- my $state = $stateHeader;
- foreach my $line (split(/\n/, $patch)) {
- $lineCountInState++;
- if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) {
- $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@";
- $lineCountInState = 0;
- $state = $statePreContext;
- } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") {
- $line = "+" . substr($line, 1);
- if ($lineCountInState == $oldContentLineCountReduction) {
- $lineCountInState = 0;
- $state = $stateNewChanges;
- }
- } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") {
- # No changes to these lines
- if ($lineCountInState == $newContentLineCountWithoutContext) {
- $lineCountInState = 0;
- $state = $statePostContext;
- }
- } elsif ($state == $statePostContext) {
- if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) {
- $line = " " . substr($line, 1);
- } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") {
- next; # Discard
- }
- }
- $newPatch .= $line . "\n";
- }
-
- return $newPatch;
-}
-
-sub gitdiff2svndiff($)
-{
- $_ = shift @_;
- if (m#^diff --git a/(.+) b/(.+)#) {
- return "Index: $1";
- } elsif (m/^new file.*/) {
- return "";
- } elsif (m#^index [0-9a-f]{7}\.\.[0-9a-f]{7} [0-9]{6}#) {
- return "===================================================================";
- } elsif (m#^--- a/(.+)#) {
- return "--- $1";
- } elsif (m#^\+\+\+ b/(.+)#) {
- return "+++ $1";
- }
- return $_;
-}
-
sub handleBinaryChange($$)
{
my ($fullPath, $contents) = @_;
@@ -334,7 +264,7 @@ sub handleBinaryChange($$)
# The last line is allowed to have up to two '=' characters at the end (to signify padding).
if ($contents =~ m#((\n[A-Za-z0-9+/]{76})*\n[A-Za-z0-9+/]{2,74}?[A-Za-z0-9+/=]{2}\n)#) {
# Addition or Modification
- open FILE, ">", $fullPath or die;
+ open FILE, ">", $fullPath or die "Failed to open $fullPath.";
print FILE decode_base64($1);
close FILE;
if (!scmKnowsOfFile($fullPath)) {
@@ -373,6 +303,7 @@ sub patch($)
unless ($patch =~ m|^Index: ([^\r\n]+)|) {
my $separator = '-' x 67;
warn "Failed to find 'Index:' in:\n$separator\n$patch\n$separator\n";
+ die unless $force;
return;
}
my $fullPath = $1;
@@ -413,7 +344,7 @@ sub patch($)
unlink("$fullPath.orig") if -e "$fullPath.orig" && checksum($fullPath) eq checksum("$fullPath.orig");
scmAdd($fullPath);
# What is this for?
- system "svn", "stat", "$fullPath.orig" if isSVN() && -e "$fullPath.orig";
+ system("svn", "stat", "$fullPath.orig") if isSVN() && -e "$fullPath.orig";
}
}
}
@@ -455,38 +386,6 @@ sub removeEOL($)
return $line;
}
-sub svnStatus($)
-{
- my ($fullPath) = @_;
- my $svnStatus;
- open SVN, "svn status --non-interactive --non-recursive '$fullPath' |" or die;
- if (-d $fullPath) {
- # When running "svn stat" on a directory, we can't assume that only one
- # status will be returned (since any files with a status below the
- # directory will be returned), and we can't assume that the directory will
- # be first (since any files with unknown status will be listed first).
- my $normalizedFullPath = File::Spec->catdir(File::Spec->splitdir($fullPath));
- while (<SVN>) {
- # Input may use a different EOL sequence than $/, so avoid chomp.
- $_ = removeEOL($_);
- my $normalizedStatPath = File::Spec->catdir(File::Spec->splitdir(substr($_, 7)));
- if ($normalizedFullPath eq $normalizedStatPath) {
- $svnStatus = "$_\n";
- last;
- }
- }
- # Read the rest of the svn command output to avoid a broken pipe warning.
- local $/ = undef;
- <SVN>;
- }
- else {
- # Files will have only one status returned.
- $svnStatus = removeEOL(<SVN>) . "\n";
- }
- close SVN;
- return $svnStatus;
-}
-
# This could be made into a more general "status" call, except svn and git
# have different ideas about "moving" files which might get confusing.
sub scmWillDeleteFile($)
@@ -524,10 +423,10 @@ sub scmCopy($$)
{
my ($source, $destination) = @_;
if (isSVN()) {
- system "svn", "copy", $source, $destination;
+ system("svn", "copy", $source, $destination) == 0 or die "Failed to svn copy $source $destination.";
} elsif (isGit()) {
- system "cp", $source, $destination;
- system "git", "add", $destination;
+ system("cp", $source, $destination) == 0 or die "Failed to copy $source $destination.";
+ system("git", "add", $destination) == 0 or die "Failed to git add $destination.";
}
}
@@ -535,9 +434,9 @@ sub scmAdd($)
{
my ($path) = @_;
if (isSVN()) {
- system "svn", "add", $path;
+ system("svn", "add", $path) == 0 or die "Failed to svn add $path.";
} elsif (isGit()) {
- system "git", "add", $path;
+ system("git", "add", $path) == 0 or die "Failed to git add $path.";
}
}
@@ -555,6 +454,6 @@ sub scmRemove($)
close SVN;
print $svnOutput if $svnOutput;
} elsif (isGit()) {
- system "git", "rm", "--force", $path;
+ system("git", "rm", "--force", $path) == 0 or die "Failed to git rm --force $path.";
}
}
diff --git a/WebKitTools/Scripts/svn-create-patch b/WebKitTools/Scripts/svn-create-patch
index 3f40783..768a8ed 100755
--- a/WebKitTools/Scripts/svn-create-patch
+++ b/WebKitTools/Scripts/svn-create-patch
@@ -56,12 +56,10 @@ use Time::gmtime;
use VCSUtils;
sub binarycmp($$);
-sub canonicalizePath($);
sub findBaseUrl($);
sub findMimeType($;$);
sub findModificationType($);
sub findSourceFileAndRevision($);
-sub fixChangeLogPatch($);
sub generateDiff($$);
sub generateFileList($\%);
sub isBinaryMimeType($);
@@ -132,25 +130,6 @@ sub binarycmp($$)
return $fileDataA->{isBinary} <=> $fileDataB->{isBinary};
}
-sub canonicalizePath($)
-{
- my ($file) = @_;
-
- # Remove extra slashes and '.' directories in path
- $file = File::Spec->canonpath($file);
-
- # Remove '..' directories in path
- my @dirs = ();
- foreach my $dir (File::Spec->splitdir($file)) {
- if ($dir eq '..' && $#dirs >= 0 && $dirs[$#dirs] ne '..') {
- pop(@dirs);
- } else {
- push(@dirs, $dir);
- }
- }
- return ($#dirs >= 0) ? File::Spec->catdir(@dirs) : ".";
-}
-
sub findBaseUrl($)
{
my ($infoPath) = @_;
@@ -211,57 +190,6 @@ sub findSourceFileAndRevision($)
return ($sourceFile, $sourceRevision);
}
-sub fixChangeLogPatch($)
-{
- my $patch = shift;
- my $contextLineCount = 3;
-
- return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\n( .*\n)+(\+.*\n)+( .*\n){$contextLineCount}$/m;
- my ($oldLineCount, $newLineCount) = ($1, $2);
- return $patch if $oldLineCount <= $contextLineCount;
-
- # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
- # have lines of context at the top of a patch when the existing entry has the same
- # date and author as the new entry. This nifty loop alters a ChangeLog patch so
- # that the added lines ("+") in the patch always start at the beginning of the
- # patch and there are no initial lines of context.
- my $newPatch;
- my $lineCountInState = 0;
- my $oldContentLineCountReduction = $oldLineCount - $contextLineCount;
- my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction;
- my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4);
- my $state = $stateHeader;
- foreach my $line (split(/\n/, $patch)) {
- $lineCountInState++;
- if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) {
- $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@";
- $lineCountInState = 0;
- $state = $statePreContext;
- } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") {
- $line = "+" . substr($line, 1);
- if ($lineCountInState == $oldContentLineCountReduction) {
- $lineCountInState = 0;
- $state = $stateNewChanges;
- }
- } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") {
- # No changes to these lines
- if ($lineCountInState == $newContentLineCountWithoutContext) {
- $lineCountInState = 0;
- $state = $statePostContext;
- }
- } elsif ($state == $statePostContext) {
- if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) {
- $line = " " . substr($line, 1);
- } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") {
- next; # Discard
- }
- }
- $newPatch .= $line . "\n";
- }
-
- return $newPatch;
-}
-
sub generateDiff($$)
{
my ($fileData, $prefix) = @_;
diff --git a/WebKitTools/Scripts/svn-unapply b/WebKitTools/Scripts/svn-unapply
index a4cec9a..94bb1ce 100755
--- a/WebKitTools/Scripts/svn-unapply
+++ b/WebKitTools/Scripts/svn-unapply
@@ -71,12 +71,9 @@ use lib $FindBin::Bin;
use VCSUtils;
sub checksum($);
-sub fixChangeLogPatch($);
-sub gitdiff2svndiff($);
sub patch($);
sub revertDirectories();
sub removeEOL($);
-sub svnStatus($);
sub unapplyPatch($$;$);
sub unsetChangeLogDate($$);
@@ -158,74 +155,6 @@ sub checksum($)
return $checksum;
}
-sub fixChangeLogPatch($)
-{
- my $patch = shift;
- my $contextLineCount = 3;
-
- return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\n( .*\n)+(\+.*\n)+( .*\n){$contextLineCount}$/m;
- my ($oldLineCount, $newLineCount) = ($1, $2);
- return $patch if $oldLineCount <= $contextLineCount;
-
- # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
- # have lines of context at the top of a patch when the existing entry has the same
- # date and author as the new entry. This nifty loop alters a ChangeLog patch so
- # that the added lines ("+") in the patch always start at the beginning of the
- # patch and there are no initial lines of context.
- my $newPatch;
- my $lineCountInState = 0;
- my $oldContentLineCountReduction = $oldLineCount - $contextLineCount;
- my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction;
- my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4);
- my $state = $stateHeader;
- foreach my $line (split(/\n/, $patch)) {
- $lineCountInState++;
- if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) {
- $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@";
- $lineCountInState = 0;
- $state = $statePreContext;
- } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") {
- $line = "+" . substr($line, 1);
- if ($lineCountInState == $oldContentLineCountReduction) {
- $lineCountInState = 0;
- $state = $stateNewChanges;
- }
- } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") {
- # No changes to these lines
- if ($lineCountInState == $newContentLineCountWithoutContext) {
- $lineCountInState = 0;
- $state = $statePostContext;
- }
- } elsif ($state == $statePostContext) {
- if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) {
- $line = " " . substr($line, 1);
- } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") {
- next; # Discard
- }
- }
- $newPatch .= $line . "\n";
- }
-
- return $newPatch;
-}
-
-sub gitdiff2svndiff($)
-{
- $_ = shift @_;
- if (m#^diff --git a/(.+) b/(.+)#) {
- return "Index: $1";
- } elsif (m/^new file.*/) {
- return "";
- } elsif (m#^index [0-9a-f]{7}\.\.[0-9a-f]{7} [0-9]{6}#) {
- return "===================================================================";
- } elsif (m#^--- a/(.+)#) {
- return "--- $1";
- } elsif (m#^\+\+\+ b/(.+)#) {
- return "+++ $1";
- }
- return $_;
-}
-
sub patch($)
{
my ($patch) = @_;
@@ -338,38 +267,6 @@ sub removeEOL($)
return $line;
}
-sub svnStatus($)
-{
- my ($fullPath) = @_;
- my $svnStatus;
- open SVN, "svn status --non-interactive --non-recursive '$fullPath' |" or die;
- if (-d $fullPath) {
- # When running "svn stat" on a directory, we can't assume that only one
- # status will be returned (since any files with a status below the
- # directory will be returned), and we can't assume that the directory will
- # be first (since any files with unknown status will be listed first).
- my $normalizedFullPath = File::Spec->catdir(File::Spec->splitdir($fullPath));
- while (<SVN>) {
- # Input may use a different EOL sequence than $/, so avoid chomp.
- $_ = removeEOL($_);
- my $normalizedStatPath = File::Spec->catdir(File::Spec->splitdir(substr($_, 7)));
- if ($normalizedFullPath eq $normalizedStatPath) {
- $svnStatus = "$_\n";
- last;
- }
- }
- # Read the rest of the svn command output to avoid a broken pipe warning.
- local $/ = undef;
- <SVN>;
- }
- else {
- # Files will have only one status returned.
- $svnStatus = removeEOL(<SVN>) . "\n";
- }
- close SVN;
- return $svnStatus;
-}
-
sub unapplyPatch($$;$)
{
my ($patch, $fullPath, $options) = @_;
diff --git a/WebKitTools/Scripts/update-webkit b/WebKitTools/Scripts/update-webkit
index e562cc0..b503004 100755
--- a/WebKitTools/Scripts/update-webkit
+++ b/WebKitTools/Scripts/update-webkit
@@ -39,7 +39,6 @@ use VCSUtils;
use webkitdirs;
sub runSvnUpdate();
-sub normalizePath($);
# Handle options
my $quiet = '';
@@ -105,10 +104,3 @@ sub runSvnUpdate()
or die "Could not open resolve-ChangeLogs script: $!.\n";
}
}
-
-sub normalizePath($)
-{
- my ($path) = @_;
- $path =~ s/\\/\//g;
- return $path;
-}
diff --git a/WebKitTools/Scripts/webkitdirs.pm b/WebKitTools/Scripts/webkitdirs.pm
index d5177dd..16f9c26 100644
--- a/WebKitTools/Scripts/webkitdirs.pm
+++ b/WebKitTools/Scripts/webkitdirs.pm
@@ -117,7 +117,7 @@ sub determineBaseProductDir
unlink($personalPlistFile) || die "Could not delete $personalPlistFile: $!";
}
- open PRODUCT, "defaults read com.apple.Xcode PBXApplicationwideBuildSettings 2> /dev/null |" or die;
+ open PRODUCT, "defaults read com.apple.Xcode PBXApplicationwideBuildSettings 2> " . File::Spec->devnull() . " |" or die;
$baseProductDir = join '', <PRODUCT>;
close PRODUCT;
@@ -125,7 +125,7 @@ sub determineBaseProductDir
undef $baseProductDir unless $baseProductDir =~ /^\//;
if (!defined($baseProductDir)) {
- open PRODUCT, "defaults read com.apple.Xcode PBXProductDirectory 2> /dev/null |" or die;
+ open PRODUCT, "defaults read com.apple.Xcode PBXProductDirectory 2> " . File::Spec->devnull() . " |" or die;
$baseProductDir = <PRODUCT>;
close PRODUCT;
if ($baseProductDir) {
@@ -215,6 +215,14 @@ sub determineArchitecture
}
}
+sub jscPath($)
+{
+ my ($productDir) = @_;
+ my $jscName = "jsc";
+ $jscName .= "_debug" if (isCygwin() && ($configuration eq "Debug"));
+ return "$productDir/$jscName";
+}
+
sub argumentsForConfiguration()
{
determineConfiguration();
@@ -300,6 +308,16 @@ sub productDir
return $configurationProductDir;
}
+sub jscProductDir
+{
+ my $productDir = productDir();
+ $productDir .= "/JavaScriptCore" if isQt();
+ $productDir .= "/$configuration" if (isQt() && isWindows());
+ $productDir .= "/Programs" if isGtk();
+
+ return $productDir;
+}
+
sub configuration()
{
determineConfiguration();
@@ -792,7 +810,7 @@ sub determineIsQt()
}
# The presence of QTDIR only means Qt if --gtk is not on the command-line
- if (isGtk()) {
+ if (isGtk() || isWx()) {
$isQt = 0;
return;
}
@@ -1100,7 +1118,12 @@ sub buildVisualStudioProject
$action = "/clean";
}
- my @command = ($vcBuildPath, $winProjectPath, $action, $config);
+ my $useenv = "/useenv";
+ if (isChromium()) {
+ $useenv = "";
+ }
+
+ my @command = ($vcBuildPath, $useenv, $winProjectPath, $action, $config);
print join(" ", @command), "\n";
return system @command;