Commit 99e5157e authored by Robert Ma's avatar Robert Ma Committed by Commit Bot

Roll WPT internal tools to 358439343c2878d6a3784964a11e43644d49c452

Due to https://github.com/web-platform-tests/wpt/pull/25471,
wpt/tools/ci/tc/github_checks_output.py is now included in the internal
tools even though it is not used.

Change-Id: I1b29dadd07243a6156489c44db4b49611ef99501
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2419575
Auto-Submit: Robert Ma <robertma@chromium.org>
Commit-Queue: Stephen McGruer <smcgruer@chromium.org>
Reviewed-by: default avatarStephen McGruer <smcgruer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#808682}
parent 818f45b6
......@@ -22,7 +22,7 @@ Local Modifications: None
Name: web-platform-tests - Test Suites for Web Platform specifications
Short Name: wpt
URL: https://github.com/web-platform-tests/wpt/
Version: d7d965cb51cb8a87ff9f87668f00b242e597d499
Version: 358439343c2878d6a3784964a11e43644d49c452
License: LICENSES FOR W3C TEST SUITES (https://www.w3.org/Consortium/Legal/2008/03-bsd-license.html)
License File: wpt/wpt/LICENSE.md
Security Critical: no
......
......@@ -4,7 +4,10 @@
./LICENSE.md
./serve.py
./tools/__init__.py
./tools/ci/__init__.py
./tools/ci/commands.json
./tools/ci/tc/__init__.py
./tools/ci/tc/github_checks_output.py
./tools/conftest.py
./tools/docker/commands.json
./tools/gitignore/__init__.py
......
......@@ -9,7 +9,7 @@ cd $DIR
TARGET_DIR=$DIR/wpt
REMOTE_REPO="https://github.com/web-platform-tests/wpt.git"
WPT_HEAD=d7d965cb51cb8a87ff9f87668f00b242e597d499
WPT_HEAD=358439343c2878d6a3784964a11e43644d49c452
function clone {
# Remove existing repo if already exists.
......
......@@ -13,6 +13,13 @@
"help": "Output a hosts file to stdout",
"virtualenv": false
},
"regen-certs": {
"path": "regen_certs.py",
"script": "run",
"parser": "get_parser",
"help": "Regenerate the WPT certificates",
"virtualenv": false
},
"tc-download": {
"path": "tc/download.py",
"script": "run",
......
MYPY = False
if MYPY:
# MYPY is set to True when run under Mypy.
from typing import Any
from typing import Optional
from typing import Text
class GitHubChecksOutputter(object):
"""Provides a method to output data to be shown in the GitHub Checks UI.
This can be useful to provide a summary of a given check (e.g. the lint)
to enable developers to quickly understand what has gone wrong. The output
supports markdown format.
See https://docs.taskcluster.net/docs/reference/integrations/github/checks#custom-text-output-in-checks
"""
def __init__(self, path):
# type: (Text) -> None
self.path = path
def output(self, line):
# type: (Any) -> None
# TODO(stephenmcgruer): Once mypy 0.790 is released, we can change this
# to AnyStr, as that release teaches mypy about the mode flags of open.
# See https://github.com/python/typeshed/pull/4146
with open(self.path, 'a') as f:
f.write(line)
f.write('\n')
__outputter = None
def get_gh_checks_outputter(filepath):
# type: (Optional[Text]) -> Optional[GitHubChecksOutputter]
"""Return the outputter for GitHub Checks output, if enabled.
:param filepath: The filepath to write GitHub Check output information to,
or None if not enabled.
"""
global __outputter
if filepath and __outputter is None:
__outputter = GitHubChecksOutputter(filepath)
return __outputter
......@@ -17,6 +17,7 @@ from collections import defaultdict
from . import fnmatch
from . import rules
from .. import localpaths
from ..ci.tc.github_checks_output import get_gh_checks_outputter, GitHubChecksOutputter
from ..gitignore.gitignore import PathFilter
from ..wpt import testfiles
from ..manifest.vcs import walk
......@@ -30,6 +31,7 @@ MYPY = False
if MYPY:
# MYPY is set to True when run under Mypy.
from typing import Any
from typing import Callable
from typing import Dict
from typing import IO
from typing import Iterable
......@@ -809,41 +811,61 @@ def check_file_contents(repo_root, path, f):
return errors
def output_errors_text(errors):
# type: (List[rules.Error]) -> None
assert logger is not None
def output_errors_text(log, errors):
# type: (Callable[[Any], None], List[rules.Error]) -> None
for error_type, description, path, line_number in errors:
pos_string = path
if line_number:
pos_string += ":%s" % line_number
logger.error("%s: %s (%s)" % (pos_string, description, error_type))
log("%s: %s (%s)" % (pos_string, description, error_type))
def output_errors_markdown(errors):
# type: (List[rules.Error]) -> None
def output_errors_markdown(log, errors):
# type: (Callable[[Any], None], List[rules.Error]) -> None
if not errors:
return
assert logger is not None
heading = """Got lint errors:
| Error Type | Position | Message |
|------------|----------|---------|"""
for line in heading.split("\n"):
logger.error(line)
log(line)
for error_type, description, path, line_number in errors:
pos_string = path
if line_number:
pos_string += ":%s" % line_number
logger.error("%s | %s | %s |" % (error_type, pos_string, description))
log("%s | %s | %s |" % (error_type, pos_string, description))
def output_errors_json(errors):
# type: (List[rules.Error]) -> None
def output_errors_json(log, errors):
# type: (Callable[[Any], None], List[rules.Error]) -> None
for error_type, error, path, line_number in errors:
# We use 'print' rather than the log function to ensure that the output
# is valid JSON (e.g. with no logger preamble).
print(json.dumps({"path": path, "lineno": line_number,
"rule": error_type, "message": error}))
def output_errors_github_checks(outputter, errors, first_reported):
# type: (GitHubChecksOutputter, List[rules.Error], bool) -> None
"""Output errors to the GitHub Checks output markdown format.
:param outputter: the GitHub Checks outputter
:param errors: a list of error tuples (error type, message, path, line number)
:param first_reported: True if these are the first reported errors
"""
if first_reported:
outputter.output(
"\nChanges in this PR contain lint errors, listed below. These "
"errors must either be fixed or added to the list of ignored "
"errors; see [the documentation]("
"https://web-platform-tests.org/writing-tests/lint-tool.html). "
"For help, please tag `@web-platform-tests/wpt-core-team` in a "
"comment.\n")
outputter.output("```")
output_errors_text(outputter.output, errors)
def output_error_count(error_count):
# type: (Dict[Text, int]) -> None
if not error_count:
......@@ -910,6 +932,8 @@ def create_parser():
"using fnmatch, except that path separators are normalized.")
parser.add_argument("--all", action="store_true", help="If no paths are passed, try to lint the whole "
"working directory, not just files that changed")
parser.add_argument("--github-checks-text-file", type=ensure_text,
help="Path to GitHub checks output file for Taskcluster runs")
return parser
......@@ -935,11 +959,13 @@ def main(**kwargs_str):
ignore_glob = kwargs.get("ignore_glob", [])
return lint(repo_root, paths, output_format, ignore_glob)
github_checks_outputter = get_gh_checks_outputter(kwargs["github_checks_text_file"])
return lint(repo_root, paths, output_format, ignore_glob, github_checks_outputter)
def lint(repo_root, paths, output_format, ignore_glob=None):
# type: (Text, List[Text], Text, Optional[List[Text]]) -> int
def lint(repo_root, paths, output_format, ignore_glob=None, github_checks_outputter=None):
# type: (Text, List[Text], Text, Optional[List[Text]], Optional[GitHubChecksOutputter]) -> int
error_count = defaultdict(int) # type: Dict[Text, int]
last = None
......@@ -964,11 +990,16 @@ def lint(repo_root, paths, output_format, ignore_glob=None):
"""
errors = filter_ignorelist_errors(ignorelist, errors)
if not errors:
return None
output_errors(errors)
assert logger is not None
output_errors(logger.error, errors)
if github_checks_outputter:
first_output = len(error_count) == 0
output_errors_github_checks(github_checks_outputter, errors, first_output)
for error_type, error, path, line in errors:
error_count[error_type] += 1
......@@ -1002,6 +1033,10 @@ def lint(repo_root, paths, output_format, ignore_glob=None):
assert logger is not None
for line in (ERROR_MSG % (last[0], last[1], last[0], last[1])).split("\n"):
logger.info(line)
if error_count and github_checks_outputter:
github_checks_outputter.output("```")
return sum(itervalues(error_count))
......
......@@ -940,6 +940,7 @@ def get_parser():
parser.add_argument("--no-h2", action="store_false", dest="h2", default=None,
help="Disable the HTTP/2.0 server")
parser.add_argument("--quic-transport", action="store_true", help="Enable QUIC server for WebTransport")
parser.add_argument("--exit-after-start", action="store_true", help="Exit after starting servers")
parser.set_defaults(report=False)
parser.set_defaults(is_wave=False)
return parser
......@@ -990,7 +991,7 @@ def run(config_cls=ConfigBuilder, route_builder=None, **kwargs):
signal.signal(signal.SIGINT, handle_signal)
while (all(subproc.is_alive() for subproc in iter_procs(servers)) and
not received_signal.is_set()):
not received_signal.is_set() and not kwargs["exit_after_start"]):
for subproc in iter_procs(servers):
subproc.join(1)
......
......@@ -649,7 +649,10 @@ class Chrome(Browser):
# All other channels share the same path on macOS.
return "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
if uname[0] == "Windows":
return os.path.expandvars(r"$SYSTEMDRIVE\Program Files (x86)\Google\Chrome\Application\chrome.exe")
path = os.path.expandvars(r"$SYSTEMDRIVE\Program Files (x86)\Google\Chrome\Application\chrome.exe")
if not os.path.exists(path):
path = os.path.expandvars(r"$SYSTEMDRIVE\Program Files\Google\Chrome\Application\chrome.exe")
return path
self.logger.warning("Unable to find the browser binary.")
return None
......
......@@ -407,7 +407,7 @@ class AsIsHandler(object):
path = filesystem_path(self.base_path, request, self.url_base)
try:
with open(path) as f:
with open(path, 'rb') as f:
response.writer.write_raw_content(f.read())
wrap_pipeline(path, request, response)
response.close_connection = True
......
......@@ -169,6 +169,10 @@ class Request(object):
Regexp match object from matching the request path to the route
selected for the request.
.. attribute:: client_address
Contains a tuple of the form (host, port) representing the client's address.
.. attribute:: protocol_version
HTTP version specified in the request.
......@@ -245,6 +249,7 @@ class Request(object):
def __init__(self, request_handler):
self.doc_root = request_handler.server.router.doc_root
self.route_match = None # Set by the router
self.client_address = request_handler.client_address
self.protocol_version = request_handler.protocol_version
self.method = request_handler.command
......
......@@ -528,6 +528,7 @@ class H2HandlerCopy(object):
self.h2_stream_id = req_frame.stream_id
self.server = handler.server
self.protocol_version = handler.protocol_version
self.client_address = handler.client_address
self.raw_requestline = ''
self.rfile = rfile
self.request = handler.request
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment