Title: [232274] trunk/Tools
Revision
232274
Author
commit-qu...@webkit.org
Date
2018-05-29 14:29:57 -0700 (Tue, 29 May 2018)

Log Message

Export changes to web-platform-test as part of the webkit-patch upload workflow
https://bugs.webkit.org/show_bug.cgi?id=184914

Patch by Brendan McLoughlin <bren...@bocoup.com> on 2018-05-29
Reviewed by Youenn Fablet.

* Scripts/webkitpy/tool/commands/upload.py:
(Upload):
(CreateBug.execute):
(WPTChangeExport):
* Scripts/webkitpy/tool/steps/__init__.py:
* Scripts/webkitpy/tool/steps/wptchangeexport.py: Added.
(WPTChangeExport):
(WPTChangeExport.options):
(WPTChangeExport.run):
* Scripts/webkitpy/w3c/common.py:
* Scripts/webkitpy/w3c/test_exporter.py:
(WebPlatformTestExporter):
(WebPlatformTestExporter.__init__):
(WebPlatformTestExporter.username):
(WebPlatformTestExporter.token):
(WebPlatformTestExporter._github):
(WebPlatformTestExporter._wpt_fork_branch_github_url):
(WebPlatformTestExporter._wpt_fork_remote):
(WebPlatformTestExporter._wpt_fork_push_url):
(WebPlatformTestExporter._git):
(WebPlatformTestExporter._branch_name):
(WebPlatformTestExporter._public_branch_name):
(WebPlatformTestExporter._wpt_patch):
(WebPlatformTestExporter.has_wpt_changes):
(WebPlatformTestExporter._find_filename):
(WebPlatformTestExporter._is_ignored_file):
(WebPlatformTestExporter._strip_ignored_files_from_diff):
(WebPlatformTestExporter.write_git_patch_file):
(WebPlatformTestExporter._prompt_for_token):
(WebPlatformTestExporter._prompt_for_username):
(WebPlatformTestExporter._ensure_username_and_token):
(WebPlatformTestExporter._validate_and_save_token):
(WebPlatformTestExporter.create_branch_with_patch):
(WebPlatformTestExporter.push_to_wpt_fork):
(WebPlatformTestExporter.make_pull_request):
(WebPlatformTestExporter.delete_local_branch):
(WebPlatformTestExporter.create_upload_remote_if_needed):
(WebPlatformTestExporter.do_export):
(parse_args):
(TestExporter): Deleted.
(TestExporter.__init__): Deleted.
(TestExporter._ensure_wpt_repository): Deleted.
(TestExporter._fetch_wpt_repository): Deleted.
(TestExporter._ensure_new_branch_name): Deleted.
(TestExporter.download_and_commit_patch): Deleted.
(TestExporter.clean): Deleted.
(TestExporter.create_branch_with_patch): Deleted.
(TestExporter.push_to_wpt_fork): Deleted.
(TestExporter.make_pull_request): Deleted.
(TestExporter.create_wpt_pull_request): Deleted.
(TestExporter.delete_local_branch): Deleted.
(TestExporter.create_git_patch): Deleted.
(TestExporter.create_upload_remote): Deleted.
(TestExporter.do_export): Deleted.
* Scripts/webkitpy/w3c/test_exporter_unittest.py:
(TestExporterTest.MockGit):
(TestExporterTest.MockGit.create_patch):
(TestExporterTest.test_export):
(TestExporterTest.test_export_with_specific_branch):
(TestExporterTest):
(TestExporterTest.test_export_interactive_mode):
(TestExporterTest.test_export_invalid_token):
(TestExporterTest.test_export_wrong_token):
(TestExporterTest.test_has_wpt_changes):
(TestExporterTest.test_has_no_wpt_changes_for_no_diff):
(TestExporterTest.test_ignore_changes_to_expected_file):

Modified Paths

Added Paths

Diff

Modified: trunk/Tools/ChangeLog (232273 => 232274)


--- trunk/Tools/ChangeLog	2018-05-29 21:15:24 UTC (rev 232273)
+++ trunk/Tools/ChangeLog	2018-05-29 21:29:57 UTC (rev 232274)
@@ -1,3 +1,77 @@
+2018-05-29  Brendan McLoughlin  <bren...@bocoup.com>
+
+        Export changes to web-platform-test as part of the webkit-patch upload workflow
+        https://bugs.webkit.org/show_bug.cgi?id=184914
+
+        Reviewed by Youenn Fablet.
+
+        * Scripts/webkitpy/tool/commands/upload.py:
+        (Upload):
+        (CreateBug.execute):
+        (WPTChangeExport):
+        * Scripts/webkitpy/tool/steps/__init__.py:
+        * Scripts/webkitpy/tool/steps/wptchangeexport.py: Added.
+        (WPTChangeExport):
+        (WPTChangeExport.options):
+        (WPTChangeExport.run):
+        * Scripts/webkitpy/w3c/common.py:
+        * Scripts/webkitpy/w3c/test_exporter.py:
+        (WebPlatformTestExporter):
+        (WebPlatformTestExporter.__init__):
+        (WebPlatformTestExporter.username):
+        (WebPlatformTestExporter.token):
+        (WebPlatformTestExporter._github):
+        (WebPlatformTestExporter._wpt_fork_branch_github_url):
+        (WebPlatformTestExporter._wpt_fork_remote):
+        (WebPlatformTestExporter._wpt_fork_push_url):
+        (WebPlatformTestExporter._git):
+        (WebPlatformTestExporter._branch_name):
+        (WebPlatformTestExporter._public_branch_name):
+        (WebPlatformTestExporter._wpt_patch):
+        (WebPlatformTestExporter.has_wpt_changes):
+        (WebPlatformTestExporter._find_filename):
+        (WebPlatformTestExporter._is_ignored_file):
+        (WebPlatformTestExporter._strip_ignored_files_from_diff):
+        (WebPlatformTestExporter.write_git_patch_file):
+        (WebPlatformTestExporter._prompt_for_token):
+        (WebPlatformTestExporter._prompt_for_username):
+        (WebPlatformTestExporter._ensure_username_and_token):
+        (WebPlatformTestExporter._validate_and_save_token):
+        (WebPlatformTestExporter.create_branch_with_patch):
+        (WebPlatformTestExporter.push_to_wpt_fork):
+        (WebPlatformTestExporter.make_pull_request):
+        (WebPlatformTestExporter.delete_local_branch):
+        (WebPlatformTestExporter.create_upload_remote_if_needed):
+        (WebPlatformTestExporter.do_export):
+        (parse_args):
+        (TestExporter): Deleted.
+        (TestExporter.__init__): Deleted.
+        (TestExporter._ensure_wpt_repository): Deleted.
+        (TestExporter._fetch_wpt_repository): Deleted.
+        (TestExporter._ensure_new_branch_name): Deleted.
+        (TestExporter.download_and_commit_patch): Deleted.
+        (TestExporter.clean): Deleted.
+        (TestExporter.create_branch_with_patch): Deleted.
+        (TestExporter.push_to_wpt_fork): Deleted.
+        (TestExporter.make_pull_request): Deleted.
+        (TestExporter.create_wpt_pull_request): Deleted.
+        (TestExporter.delete_local_branch): Deleted.
+        (TestExporter.create_git_patch): Deleted.
+        (TestExporter.create_upload_remote): Deleted.
+        (TestExporter.do_export): Deleted.
+        * Scripts/webkitpy/w3c/test_exporter_unittest.py:
+        (TestExporterTest.MockGit):
+        (TestExporterTest.MockGit.create_patch):
+        (TestExporterTest.test_export):
+        (TestExporterTest.test_export_with_specific_branch):
+        (TestExporterTest):
+        (TestExporterTest.test_export_interactive_mode):
+        (TestExporterTest.test_export_invalid_token):
+        (TestExporterTest.test_export_wrong_token):
+        (TestExporterTest.test_has_wpt_changes):
+        (TestExporterTest.test_has_no_wpt_changes_for_no_diff):
+        (TestExporterTest.test_ignore_changes_to_expected_file):
+
 2018-05-29  Fujii Hironori  <hironori.fu...@sony.com>
 
         [Win][MiniBrowser] Move WK1 specific code from Common.cpp to MiniBrowser.cpp

Modified: trunk/Tools/Scripts/webkitpy/tool/commands/upload.py (232273 => 232274)


--- trunk/Tools/Scripts/webkitpy/tool/commands/upload.py	2018-05-29 21:15:24 UTC (rev 232273)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/upload.py	2018-05-29 21:29:57 UTC (rev 232274)
@@ -286,6 +286,7 @@
         steps.EnsureBugIsOpenAndAssigned,
         steps.PostDiff,
         steps.SubmitToEWS,
+        steps.WPTChangeExport,
     ]
     long_help = """upload uploads the current diff to bugs.webkit.org.
     If no bug id is provided, upload will create a bug.
@@ -531,3 +532,25 @@
             self.create_bug_from_commit(options, args, tool)
         else:
             self.create_bug_from_patch(options, args, tool)
+
+
+class WPTChangeExport(AbstractPatchUploadingCommand):
+    name = "wpt-change-export"
+    help_text = "Opens a pull request to synchronize any changes in the LayoutTests/imported/w3c/web-platform-tests directory"
+    argument_names = "[BUGID]"
+    steps = [
+        steps.WPTChangeExport,
+    ]
+
+    long_help = """Opens a pull request to the w3c/web-platform-tests
+    github repo for any changes in the
+    LayoutTests/imported/w3c/web-platform-tests directory. This step
+    will noop if there are no changes in the web-platform-tests directory.
+    The user will be prompted to provide a github username and OAuth token
+    the first time this is run.
+    """
+
+    def _prepare_state(self, options, args, tool):
+        state = {}
+        state["bug_id"] = self._bug_id(options, args, tool, state)
+        return state

Modified: trunk/Tools/Scripts/webkitpy/tool/steps/__init__.py (232273 => 232274)


--- trunk/Tools/Scripts/webkitpy/tool/steps/__init__.py	2018-05-29 21:15:24 UTC (rev 232273)
+++ trunk/Tools/Scripts/webkitpy/tool/steps/__init__.py	2018-05-29 21:29:57 UTC (rev 232274)
@@ -66,3 +66,4 @@
 from webkitpy.tool.steps.updatechangelogswithreviewer import UpdateChangeLogsWithReviewer
 from webkitpy.tool.steps.validatechangelogs import ValidateChangeLogs
 from webkitpy.tool.steps.validatereviewer import ValidateReviewer
+from webkitpy.tool.steps.wptchangeexport import WPTChangeExport

Added: trunk/Tools/Scripts/webkitpy/tool/steps/wptchangeexport.py (0 => 232274)


--- trunk/Tools/Scripts/webkitpy/tool/steps/wptchangeexport.py	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/tool/steps/wptchangeexport.py	2018-05-29 21:29:57 UTC (rev 232274)
@@ -0,0 +1,54 @@
+# Copyright (c) 2018, Bocoup LLC. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  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.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. AND ITS 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.
+
+from webkitpy.common.system.executive import ScriptError
+from webkitpy.tool.steps.abstractstep import AbstractStep
+from webkitpy.tool.steps.options import Options
+from webkitpy.w3c.test_exporter import WebPlatformTestExporter, parse_args
+
+
+class WPTChangeExport(AbstractStep):
+    @classmethod
+    def options(cls):
+        return AbstractStep.options() + [
+            Options.non_interactive,
+            Options.git_commit,
+        ]
+
+    def run(self, state):
+        if self._options.non_interactive:
+            return
+
+        bug_id = state.get("bug_id")
+        if not bug_id:
+            return
+
+        args = ["--bug", str(bug_id), "--create-pr"]
+
+        if self._options.git_commit:
+            args.append("--git-commit")
+            args.append(self._options.git_commit)
+
+        test_exporter = WebPlatformTestExporter(self._tool, parse_args(args))
+        message = 'Would you like to export the web-platform-tests changes to a WPT GitHub repository?'
+        if test_exporter.has_wpt_changes() and self._tool.user.confirm(message):
+            test_exporter.do_export()

Modified: trunk/Tools/Scripts/webkitpy/w3c/common.py (232273 => 232274)


--- trunk/Tools/Scripts/webkitpy/w3c/common.py	2018-05-29 21:15:24 UTC (rev 232273)
+++ trunk/Tools/Scripts/webkitpy/w3c/common.py	2018-05-29 21:29:57 UTC (rev 232274)
@@ -30,10 +30,11 @@
 
 import json
 import logging
+import os
 
 
-WPT_GH_ORG = 'w3c'
-WPT_GH_REPO_NAME = 'web-platform-tests'
+WPT_GH_ORG = os.environ.get('WPT_GH_ORG', 'w3c')
+WPT_GH_REPO_NAME = os.environ.get('WPT_GH_REPO_NAME', 'web-platform-tests')
 WPT_GH_URL = 'https://github.com/%s/%s/' % (WPT_GH_ORG, WPT_GH_REPO_NAME)
 WPT_MIRROR_URL = 'https://chromium.googlesource.com/external/w3c/web-platform-tests.git'
 WPT_GH_SSH_URL_TEMPLATE = 'https://{}@github.com/%s/%s.git' % (WPT_GH_ORG, WPT_GH_REPO_NAME)

Modified: trunk/Tools/Scripts/webkitpy/w3c/test_exporter.py (232273 => 232274)


--- trunk/Tools/Scripts/webkitpy/w3c/test_exporter.py	2018-05-29 21:15:24 UTC (rev 232273)
+++ trunk/Tools/Scripts/webkitpy/w3c/test_exporter.py	2018-05-29 21:29:57 UTC (rev 232274)
@@ -28,6 +28,8 @@
 import logging
 import os
 import time
+import json
+from urllib2 import HTTPError
 
 from webkitpy.common.checkout.scm.git import Git
 from webkitpy.common.host import Host
@@ -35,16 +37,19 @@
 from webkitpy.common.webkit_finder import WebKitFinder
 from webkitpy.w3c.wpt_github import WPTGitHub
 from webkitpy.w3c.wpt_linter import WPTLinter
+from webkitpy.w3c.common import WPT_GH_ORG
+from webkitpy.common.memoized import memoized
 
 _log = logging.getLogger(__name__)
 
 WEBKIT_WPT_DIR = 'LayoutTests/imported/w3c/web-platform-tests'
-WPT_PR_URL = "https://github.com/w3c/web-platform-tests/pull/"
+WPT_PR_URL = "https://github.com/%s/web-platform-tests/pull/" % WPT_GH_ORG
 WEBKIT_EXPORT_PR_LABEL = 'webkit-export'
 
+EXCLUDED_FILE_SUFFIXES = ['-expected.txt', '.worker.html', '.any.html', '.any.worker.html']
 
-class TestExporter(object):
 
+class WebPlatformTestExporter(object):
     def __init__(self, host, options, gitClass=Git, bugzillaClass=Bugzilla, WPTGitHubClass=WPTGitHub, WPTLinterClass=WPTLinter):
         self._host = host
         self._filesystem = host.filesystem
@@ -52,6 +57,8 @@
 
         self._host.initialize_scm()
 
+        self._WPTGitHubClass = WPTGitHubClass
+        self._gitClass = gitClass
         self._bugzilla = bugzillaClass()
         self._bug_id = options.bug_id
         if not self._bug_id:
@@ -64,18 +71,141 @@
             webkit_finder = WebKitFinder(self._filesystem)
             self._options.repository_directory = webkit_finder.path_from_webkit_base('WebKitBuild', 'w3c-tests', 'web-platform-tests')
 
-        self._git = self._ensure_wpt_repository("https://github.com/w3c/web-platform-tests.git", self._options.repository_directory, gitClass)
         self._linter = WPTLinterClass(self._options.repository_directory, host.filesystem)
 
+        self._bugzilla_url = "https://bugs.webkit.org/show_bug.cgi?id=" + str(self._bug_id)
+        self._commit_message = options.message
+        if not self._commit_message:
+            self._commit_message = 'WebKit export of ' + self._bugzilla_url if self._bug_id else 'Export made from a WebKit repository'
+
+    @property
+    def username(self):
+        if hasattr(self, '_username'):
+            return self._username
+
+        self._ensure_username_and_token(self._options)
+        return self._username
+
+    @property
+    def token(self):
+        if hasattr(self, '_token'):
+            return self._token
+
+        self._ensure_username_and_token(self._options)
+        return self._token
+
+    @property
+    @memoized
+    def _github(self):
+        return self._WPTGitHubClass(self._host, self.username, self.token) if self.username and self.token else None
+
+    @property
+    @memoized
+    def _wpt_fork_branch_github_url(self):
+        return "https://github.com/" + self.username + "/web-platform-tests/tree/" + self._public_branch_name
+
+    @property
+    @memoized
+    def _wpt_fork_remote(self):
+        wpt_fork_remote = self._options.repository_remote
+        if not wpt_fork_remote:
+            wpt_fork_remote = self.username
+
+        return wpt_fork_remote
+
+    @property
+    @memoized
+    def _wpt_fork_push_url(self):
+        wpt_fork_push_url = self._options.repository_remote_url
+        if not wpt_fork_push_url:
+            wpt_fork_push_url = "https://" + self.username + "@github.com/" + self.username + "/web-platform-tests.git"
+
+        return wpt_fork_push_url
+
+    @property
+    @memoized
+    def _git(self):
+        return self._ensure_wpt_repository("https://github.com/w3c/web-platform-tests.git", self._options.repository_directory, self._gitClass)
+
+    @property
+    @memoized
+    def _branch_name(self):
+        return self._ensure_new_branch_name()
+
+    @property
+    @memoized
+    def _public_branch_name(self):
+        options = self._options
+        return options.public_branch_name if options.public_branch_name else self._branch_name
+
+    @property
+    @memoized
+    def _wpt_patch(self):
+        patch_data = self._host.scm().create_patch(self._options.git_commit, [WEBKIT_WPT_DIR]) or ''
+        patch_data = self._strip_ignored_files_from_diff(patch_data)
+        if not 'diff' in patch_data:
+            return ''
+        return patch_data
+
+    def has_wpt_changes(self):
+        return bool(self._wpt_patch)
+
+    def _find_filename(self, line):
+        return line.split(' ')[-1]
+
+    def _is_ignored_file(self, filename):
+        for suffix in EXCLUDED_FILE_SUFFIXES:
+            if filename.endswith(suffix):
+                return True
+        return False
+
+    def _strip_ignored_files_from_diff(self, diff):
+        lines = diff.split('\n')
+        include_file = True
+        new_lines = []
+        for line in lines:
+            if line.startswith('diff'):
+                include_file = True
+                filename = self._find_filename(line)
+                if self._is_ignored_file(filename):
+                    include_file = False
+            if include_file:
+                new_lines.append(line)
+
+        return '\n'.join(new_lines)
+
+    def write_git_patch_file(self):
+        _, patch_file = self._filesystem.open_binary_tempfile('wpt_export_patch')
+        patch_data = self._wpt_patch
+        if not 'diff' in patch_data:
+            _log.info('No changes to upstream, patch data is: "%s"' % (patch_data))
+            return ''
+        # FIXME: We can probably try to use --relative git parameter to not do that replacement.
+        patch_data = patch_data.replace(WEBKIT_WPT_DIR + '/', '')
+        self._filesystem.write_text_file(patch_file, patch_data)
+        return patch_file
+
+    def _prompt_for_token(self, options):
+        if options.non_interactive:
+            return None
+        return self._host.user.prompt_password('Enter GitHub OAuth token (or empty string to skip creating a pull request): ')
+
+    def _prompt_for_username(self, options):
+        if options.non_interactive:
+            return None
+        return self._host.user.prompt('Enter your GitHub username: ')
+
+    def _ensure_username_and_token(self, options):
         self._username = options.username
         if not self._username:
+            # FIXME: Use the keychain to store username and oauth token instead of .git/config
             self._username = self._git.local_config('github.username').rstrip()
             if not self._username:
                 self._username = os.environ.get('GITHUB_USERNAME')
             if not self._username:
+                self._username = self._prompt_for_username(options)
+            if not self._username:
                 raise ValueError("Missing GitHub username, please provide it as a command argument (see help for the command).")
-        elif not self._git.local_config('github.username'):
-            self._git.set_local_config('github.username', self._username)
 
         self._token = options.token
         if not self._token:
@@ -83,27 +213,31 @@
             if not self._token:
                 self._token = os.environ.get('GITHUB_TOKEN')
             if not self._token:
+                self._token = self._prompt_for_token(options)
+            if not self._token:
                 _log.info("Missing GitHub token, the script will not be able to create a pull request to W3C web-platform-tests repository.")
-        elif not self._git.local_config('github.token'):
-            self._git.set_local_config('github.token', self._token)
 
-        self._github = WPTGitHubClass(self._host, self._username, self._token) if self._username and self._token else None
+        if self._token:
+            self._validate_and_save_token(self._username, self._token)
 
-        self._branch_name = self._ensure_new_branch_name()
-        self._public_branch_name = options.public_branch_name if options.public_branch_name else self._branch_name
-        self._bugzilla_url = "https://bugs.webkit.org/show_bug.cgi?id=" + str(self._bug_id)
-        self._commit_message = options.message
-        if not self._commit_message:
-            self._commit_message = 'WebKit export of ' + self._bugzilla_url if self._bug_id else 'Export made from a WebKit repository'
+    def _validate_and_save_token(self, username, token):
+        url = '' % (token,)
+        try:
+            response = self._host.web.request(method='GET', url="" data=""
+        except HTTPError as e:
+            raise Exception("OAuth token is not valid")
+        data = ""
+        login = data.get('login', None)
+        if login != username:
+            raise Exception("OAuth token does not match the provided username. Provided user: %s, github login: %s" % (username, login))
+        else:
+            # Username and token are valid. Save them in the git config so we
+            # do not need to ask for them again
+            if not self._git.local_config('github.token'):
+                self._git.set_local_config('github.token', token)
+            if not self._git.local_config('github.username'):
+                self._git.set_local_config('github.username', username)
 
-        self._wpt_fork_remote = options.repository_remote
-        if not self._wpt_fork_remote:
-            self._wpt_fork_remote = self._username
-
-        self._wpt_fork_push_url = options.repository_remote_url
-        if not self._wpt_fork_push_url:
-            self._wpt_fork_push_url = "https://" + self._username + "@github.com/" + self._username + "/web-platform-tests.git"
-
     def _ensure_wpt_repository(self, url, wpt_repository_directory, gitClass):
         git = None
         if not self._filesystem.exists(wpt_repository_directory):
@@ -156,7 +290,7 @@
             self._git.delete_branch(self._branch_name)
             self._git.checkout_new_branch(self._branch_name)
         try:
-            self._git.apply_mail_patch([patch, '--exclude', '*-expected.txt', '--exclude', '*.worker.html', '--exclude', '*.any.html', '--exclude', '*.any.worker.html'])
+            self._git.apply_mail_patch([patch])
         except Exception as e:
             _log.warning(e)
             self._git.apply_mail_patch(['--abort'])
@@ -165,17 +299,16 @@
         return True
 
     def push_to_wpt_fork(self):
-        self.create_upload_remote()
-        wpt_fork_branch_github_url = "https://github.com/" + self._username + "/web-platform-tests/tree/" + self._public_branch_name
+        self.create_upload_remote_if_needed()
         _log.info('Pushing branch ' + self._branch_name + " to " + self._git.remote(["get-url", self._wpt_fork_remote]).rstrip())
         _log.info('This may take some time')
         self._git.push([self._wpt_fork_remote, self._branch_name + ":" + self._public_branch_name, '-f'])
-        _log.info('Branch available at ' + wpt_fork_branch_github_url)
+        _log.info('Branch available at ' + self._wpt_fork_branch_github_url)
         return True
 
     def make_pull_request(self):
         if not self._github:
-            _log.info('Missing information to create a pull request')
+            _log.info('Skipping pull request because OAuth token was not provided. You can open the pull request manually using the branch ' + self._wpt_fork_branch_github_url)
             return
 
         _log.info('Making pull request')
@@ -189,7 +322,7 @@
                 self._github.add_label(pr_number, WEBKIT_EXPORT_PR_LABEL)
             except Exception as e:
                 _log.warning(e)
-                _log.info('Could not add label "%s" to pr #%s. User "%s" may not have permission to update labels in the w3c/web-platform-test repo.' % (WEBKIT_EXPORT_PR_LABEL, pr_number, self._username))
+                _log.info('Could not add label "%s" to pr #%s. User "%s" may not have permission to update labels in the w3c/web-platform-test repo.' % (WEBKIT_EXPORT_PR_LABEL, pr_number, self.username))
         if self._bug_id and pr_number:
             self._bugzilla.post_comment_to_bug(self._bug_id, "Submitted web-platform-tests pull request: " + WPT_PR_URL + str(pr_number))
 
@@ -206,30 +339,16 @@
         return pr_number
 
     def delete_local_branch(self):
-        _log.info('Removing branch ' + self._branch_name)
+        _log.info('Removing local branch ' + self._branch_name)
         self._git.checkout('master')
         self._git.delete_branch(self._branch_name)
 
-    def create_git_patch(self):
-        patch_file = './patch.temp.' + str(time.clock())
-        git_commit = "HEAD...." if not self._options.git_commit else self._options.git_commit + "~1.." + self._options.git_commit
-        patch_data = self._host.scm().create_patch(git_commit, [WEBKIT_WPT_DIR])
-        if not patch_data or not 'diff' in patch_data:
-            _log.info('No changes to upstream, patch data is: "%s"' % (patch_data))
-            return ''
-        # FIXME: We can probably try to use --relative git parameter to not do that replacement.
-        patch_data = patch_data.replace(WEBKIT_WPT_DIR + '/', '')
-        patch_file = self._filesystem.abspath(patch_file)
-        self._filesystem.write_text_file(patch_file, patch_data)
-        return patch_file
+    def create_upload_remote_if_needed(self):
+        if not self._wpt_fork_remote in self._git.remote([]):
+            self._git.remote(["add", self._wpt_fork_remote, self._wpt_fork_push_url])
 
-    def create_upload_remote(self):
-        if self._wpt_fork_remote in self._git.remote([]).splitlines():
-            self._git.remote(["remove", self._wpt_fork_remote])
-        self._git.remote(["add", self._wpt_fork_remote, self._wpt_fork_push_url])
-
     def do_export(self):
-        git_patch_file = self.create_git_patch()
+        git_patch_file = self.write_git_patch_file()
 
         if not git_patch_file:
             _log.error("Unable to create a patch to apply to web-platform-tests repository")
@@ -294,6 +413,7 @@
     parser.add_argument('-u', '--remote-url', dest='repository_remote_url', default=None, help='repository url to use to push')
     parser.add_argument('-d', '--repository', dest='repository_directory', default=None, help='repository directory')
     parser.add_argument('-c', '--create-pr', dest='create_pull_request', action='', default=False, help='create pull request to w3c web-platform-tests')
+    parser.add_argument('--non-interactive', action='', dest='non_interactive', default=False, help='Never prompt the user, fail as fast as possible.')
 
     options, args = parser.parse_known_args(args)
 
@@ -309,6 +429,7 @@
             return record.getMessage()
 
     logger = logging.getLogger('webkitpy.w3c.test_exporter')
+    logger.propagate = False
     logger.setLevel(logging.INFO)
     handler = LogHandler()
     handler.setLevel(logging.INFO)
@@ -320,7 +441,10 @@
     options = parse_args(_argv)
 
     configure_logging()
+    test_exporter = WebPlatformTestExporter(Host(), options)
 
-    test_exporter = TestExporter(Host(), options)
+    if not test_exporter.has_wpt_changes():
+        _log.info('No changes to upstream. Exiting...')
+        return
 
     test_exporter.do_export()

Modified: trunk/Tools/Scripts/webkitpy/w3c/test_exporter_unittest.py (232273 => 232274)


--- trunk/Tools/Scripts/webkitpy/w3c/test_exporter_unittest.py	2018-05-29 21:15:24 UTC (rev 232273)
+++ trunk/Tools/Scripts/webkitpy/w3c/test_exporter_unittest.py	2018-05-29 21:29:57 UTC (rev 232274)
@@ -25,7 +25,7 @@
 from webkitpy.common.host_mock import MockHost
 from webkitpy.common.system.filesystem_mock import MockFileSystem
 from webkitpy.common.system.executive_mock import MockExecutive2
-from webkitpy.w3c.test_exporter import TestExporter, parse_args
+from webkitpy.w3c.test_exporter import WebPlatformTestExporter, parse_args
 from webkitpy.w3c.wpt_github_mock import MockWPTGitHub
 
 mock_linter = None
@@ -46,6 +46,8 @@
             return True
 
     class MockGit(object):
+        mock_format_patch_result = 'my patch containing some diffs'
+
         @classmethod
         def clone(cls, url, directory, executive=None):
             return True
@@ -94,7 +96,7 @@
 
         def create_patch(self, commit, arguments):
             self.calls.append('create_patch ' + commit + ' ' + str(arguments))
-            return 'my patch containing some diffs'
+            return self.mock_format_patch_result
 
     class MyMockHost(MockHost):
         def __init__(self):
@@ -122,8 +124,9 @@
 
     def test_export(self):
         host = TestExporterTest.MyMockHost()
+        host.web.responses.append({'status_code': 200, 'body': '{"login": "USER"}'})
         options = parse_args(['test_exporter.py', '-g', 'HEAD', '-b', '1234', '-c', '-n', 'USER', '-t', 'TOKEN'])
-        exporter = TestExporter(host, options, TestExporterTest.MockGit, TestExporterTest.MockBugzilla, MockWPTGitHub, TestExporterTest.MockWPTLinter)
+        exporter = WebPlatformTestExporter(host, options, TestExporterTest.MockGit, TestExporterTest.MockBugzilla, MockWPTGitHub, TestExporterTest.MockWPTLinter)
         exporter.do_export()
         self.assertEquals(exporter._github.calls, ['create_pr', 'add_label "webkit-export"'])
         self.assertTrue('WebKit export' in exporter._github.pull_requests_created[0][1])
@@ -133,7 +136,7 @@
             'checkout master',
             'reset hard origin/master',
             'checkout new branch wpt-export-for-webkit-1234',
-            'apply_mail_patch patch.temp --exclude *-expected.txt --exclude *.worker.html --exclude *.any.html --exclude *.any.worker.html',
+            'apply_mail_patch patch.temp ',
             'commit -a -m WebKit export of https://bugs.webkit.org/show_bug.cgi?id=1234',
             'remote ',
             'remote add USER https://u...@github.com/USER/web-platform-tests.git',
@@ -150,8 +153,9 @@
 
     def test_export_with_specific_branch(self):
         host = TestExporterTest.MyMockHost()
+        host.web.responses.append({'status_code': 200, 'body': '{"login": "USER"}'})
         options = parse_args(['test_exporter.py', '-g', 'HEAD', '-b', '1234', '-c', '-n', 'USER', '-t', 'TOKEN', '-bn', 'wpt-export-branch'])
-        exporter = TestExporter(host, options, TestExporterTest.MockGit, TestExporterTest.MockBugzilla, MockWPTGitHub, TestExporterTest.MockWPTLinter)
+        exporter = WebPlatformTestExporter(host, options, TestExporterTest.MockGit, TestExporterTest.MockBugzilla, MockWPTGitHub, TestExporterTest.MockWPTLinter)
         exporter.do_export()
         self.assertEquals(exporter._git.calls, [
             '/mock-checkout/WebKitBuild/w3c-tests/web-platform-tests',
@@ -159,7 +163,7 @@
             'checkout master',
             'reset hard origin/master',
             'checkout new branch wpt-export-for-webkit-1234',
-            'apply_mail_patch patch.temp --exclude *-expected.txt --exclude *.worker.html --exclude *.any.html --exclude *.any.worker.html',
+            'apply_mail_patch patch.temp ',
             'commit -a -m WebKit export of https://bugs.webkit.org/show_bug.cgi?id=1234',
             'remote ',
             'remote add USER https://u...@github.com/USER/web-platform-tests.git',
@@ -169,3 +173,53 @@
             'delete branch wpt-export-for-webkit-1234',
             'checkout master',
             'reset hard origin/master'])
+
+    def test_export_interactive_mode(self):
+        host = TestExporterTest.MyMockHost()
+        host.web.responses.append({'status_code': 200, 'body': '{"login": "USER"}'})
+        options = parse_args(['test_exporter.py', '-g', 'HEAD', '-b', '1234', '-c', '-n', 'USER', '-t', 'TOKEN', '--interactive'])
+        exporter = WebPlatformTestExporter(host, options, TestExporterTest.MockGit, TestExporterTest.MockBugzilla, MockWPTGitHub, TestExporterTest.MockWPTLinter)
+        exporter.do_export()
+
+    def test_export_invalid_token(self):
+        host = TestExporterTest.MyMockHost()
+        host.web.responses.append({'status_code': 401})
+        options = parse_args(['test_exporter.py', '-g', 'HEAD', '-b', '1234', '-c', '-n', 'USER', '-t', 'TOKEN'])
+        exporter = WebPlatformTestExporter(host, options, TestExporterTest.MockGit, TestExporterTest.MockBugzilla, MockWPTGitHub, TestExporterTest.MockWPTLinter)
+        with self.assertRaises(Exception) as context:
+            exporter.do_export()
+        self.assertIn('OAuth token is not valid', str(context.exception))
+
+    def test_export_wrong_token(self):
+        host = TestExporterTest.MyMockHost()
+        host.web.responses.append({'status_code': 200, 'body': '{"login": "DIFF_USER"}'})
+        options = parse_args(['test_exporter.py', '-g', 'HEAD', '-b', '1234', '-c', '-n', 'USER', '-t', 'TOKEN'])
+        exporter = WebPlatformTestExporter(host, options, TestExporterTest.MockGit, TestExporterTest.MockBugzilla, MockWPTGitHub, TestExporterTest.MockWPTLinter)
+        with self.assertRaises(Exception) as context:
+            exporter.do_export()
+        self.assertIn('OAuth token does not match the provided username', str(context.exception))
+
+    def test_has_wpt_changes(self):
+        host = TestExporterTest.MyMockHost()
+        options = parse_args(['test_exporter.py', '-g', 'HEAD', '-b', '1234', '-c', '-n', 'USER', '-t', 'TOKEN'])
+        exporter = WebPlatformTestExporter(host, options, TestExporterTest.MockGit, TestExporterTest.MockBugzilla, MockWPTGitHub, TestExporterTest.MockWPTLinter)
+        self.assertTrue(exporter.has_wpt_changes())
+
+    def test_has_no_wpt_changes_for_no_diff(self):
+        host = TestExporterTest.MyMockHost()
+        host._mockSCM.mock_format_patch_result = None
+        options = parse_args(['test_exporter.py', '-g', 'HEAD', '-b', '1234', '-c', '-n', 'USER', '-t', 'TOKEN'])
+        exporter = WebPlatformTestExporter(host, options, TestExporterTest.MockGit, TestExporterTest.MockBugzilla, MockWPTGitHub, TestExporterTest.MockWPTLinter)
+        self.assertFalse(exporter.has_wpt_changes())
+
+    def test_ignore_changes_to_expected_file(self):
+        host = TestExporterTest.MyMockHost()
+        host._mockSCM.mock_format_patch_result = """
+Subversion Revision: 231920
+diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/headers/header-values-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/headers/header-values-expected.txt
+
++change to expected
+"""
+        options = parse_args(['test_exporter.py', '-g', 'HEAD', '-b', '1234', '-c', '-n', 'USER', '-t', 'TOKEN'])
+        exporter = WebPlatformTestExporter(host, options, TestExporterTest.MockGit, TestExporterTest.MockBugzilla, MockWPTGitHub, TestExporterTest.MockWPTLinter)
+        self.assertFalse(exporter.has_wpt_changes())
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to