mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
* Matrix in CI and mach try with presets * small fixups * names in trigger try run comment * let * f * rename step * fix running try on win * fix try branch full * py3.10 * typo * Make unit-tests default to false, except in basic os runs Fixes https://github.com/servo/servo/issues/31174 * make full use linux-wpt & linux-wpt also include unit-tests so full is equal to main workflow * Stylish fixes * cmp json as dict
308 lines
12 KiB
Python
308 lines
12 KiB
Python
# Copyright 2013 The Servo Project Developers. See the COPYRIGHT
|
|
# file at the top-level directory of this distribution.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
# option. This file may not be copied, modified, or distributed
|
|
# except according to those terms.
|
|
|
|
from os import path, listdir, getcwd
|
|
|
|
import signal
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import urllib
|
|
|
|
from mach.decorators import (
|
|
CommandArgument,
|
|
CommandProvider,
|
|
Command,
|
|
)
|
|
|
|
from servo.command_base import CommandBase, cd, call
|
|
from servo.try_parser import Config
|
|
|
|
|
|
@CommandProvider
|
|
class MachCommands(CommandBase):
|
|
@Command('check',
|
|
description='Run "cargo check"',
|
|
category='devenv')
|
|
@CommandArgument(
|
|
'params', default=None, nargs='...',
|
|
help="Command-line arguments to be passed through to cargo check")
|
|
@CommandBase.common_command_arguments(build_configuration=True, build_type=False)
|
|
def check(self, params, **kwargs):
|
|
if not params:
|
|
params = []
|
|
|
|
self.ensure_bootstrapped()
|
|
self.ensure_clobbered()
|
|
status = self.run_cargo_build_like_command("check", params, **kwargs)
|
|
if status == 0:
|
|
print('Finished checking, binary NOT updated. Consider ./mach build before ./mach run')
|
|
|
|
return status
|
|
|
|
@Command('cargo-update',
|
|
description='Same as update-cargo',
|
|
category='devenv')
|
|
@CommandArgument(
|
|
'params', default=None, nargs='...',
|
|
help='Command-line arguments to be passed through to cargo update')
|
|
@CommandArgument(
|
|
'--package', '-p', default=None,
|
|
help='Updates selected package')
|
|
@CommandArgument(
|
|
'--all-packages', '-a', action='store_true',
|
|
help='Updates all packages')
|
|
@CommandArgument(
|
|
'--dry-run', '-d', action='store_true',
|
|
help='Show outdated packages.')
|
|
def cargo_update(self, params=None, package=None, all_packages=None, dry_run=None):
|
|
self.update_cargo(params, package, all_packages, dry_run)
|
|
|
|
@Command('update-cargo',
|
|
description='Update Cargo dependencies',
|
|
category='devenv')
|
|
@CommandArgument(
|
|
'params', default=None, nargs='...',
|
|
help='Command-line arguments to be passed through to cargo update')
|
|
@CommandArgument(
|
|
'--package', '-p', default=None,
|
|
help='Updates the selected package')
|
|
@CommandArgument(
|
|
'--all-packages', '-a', action='store_true',
|
|
help='Updates all packages. NOTE! This is very likely to break your '
|
|
'working copy, making it impossible to build servo. Only do '
|
|
'this if you really know what you are doing.')
|
|
@CommandArgument(
|
|
'--dry-run', '-d', action='store_true',
|
|
help='Show outdated packages.')
|
|
def update_cargo(self, params=None, package=None, all_packages=None, dry_run=None):
|
|
if not params:
|
|
params = []
|
|
|
|
if not package and not all_packages:
|
|
print("Please choose package to update with the --package (-p) ")
|
|
print("flag or update all packages with --all-packages (-a) flag")
|
|
sys.exit(1)
|
|
|
|
if package:
|
|
params += ["-p", package]
|
|
if dry_run:
|
|
params.append("--dry-run")
|
|
|
|
self.ensure_bootstrapped()
|
|
with cd(self.context.topdir):
|
|
call(["cargo", "update"] + params, env=self.build_env())
|
|
|
|
@Command('rustc',
|
|
description='Run the Rust compiler',
|
|
category='devenv')
|
|
@CommandArgument(
|
|
'params', default=None, nargs='...',
|
|
help="Command-line arguments to be passed through to rustc")
|
|
def rustc(self, params):
|
|
if params is None:
|
|
params = []
|
|
|
|
self.ensure_bootstrapped()
|
|
return call(["rustc"] + params, env=self.build_env())
|
|
|
|
@Command('cargo-fix',
|
|
description='Run "cargo fix"',
|
|
category='devenv')
|
|
@CommandArgument(
|
|
'params', default=None, nargs='...',
|
|
help="Command-line arguments to be passed through to cargo-fix")
|
|
@CommandBase.common_command_arguments(build_configuration=True, build_type=False)
|
|
def cargo_fix(self, params, **kwargs):
|
|
if not params:
|
|
params = []
|
|
|
|
self.ensure_bootstrapped()
|
|
self.ensure_clobbered()
|
|
return self.run_cargo_build_like_command("fix", params, **kwargs)
|
|
|
|
@Command('cargo-clippy',
|
|
description='Run "cargo clippy"',
|
|
category='devenv')
|
|
@CommandArgument(
|
|
'params', default=None, nargs='...',
|
|
help="Command-line arguments to be passed through to cargo-clippy")
|
|
@CommandBase.common_command_arguments(build_configuration=True, build_type=False)
|
|
def cargo_clippy(self, params, **kwargs):
|
|
if not params:
|
|
params = []
|
|
|
|
self.ensure_bootstrapped()
|
|
self.ensure_clobbered()
|
|
return self.run_cargo_build_like_command("clippy", params, **kwargs)
|
|
|
|
@Command('grep',
|
|
description='`git grep` for selected directories.',
|
|
category='devenv')
|
|
@CommandArgument(
|
|
'params', default=None, nargs='...',
|
|
help="Command-line arguments to be passed through to `git grep`")
|
|
def grep(self, params):
|
|
if not params:
|
|
params = []
|
|
# get all directories under tests/
|
|
tests_dirs = listdir('tests')
|
|
# Directories to be excluded under tests/
|
|
excluded_tests_dirs = ['wpt', 'jquery']
|
|
tests_dirs = filter(lambda dir: dir not in excluded_tests_dirs, tests_dirs)
|
|
# Set of directories in project root
|
|
root_dirs = ['components', 'ports', 'python', 'etc', 'resources']
|
|
# Generate absolute paths for directories in tests/ and project-root/
|
|
tests_dirs_abs = [path.join(self.context.topdir, 'tests', s) for s in tests_dirs]
|
|
root_dirs_abs = [path.join(self.context.topdir, s) for s in root_dirs]
|
|
# Absolute paths for all directories to be considered
|
|
grep_paths = root_dirs_abs + tests_dirs_abs
|
|
return call(
|
|
["git"] + ["grep"] + params + ['--'] + grep_paths + [':(exclude)*.min.js', ':(exclude)*.min.css'],
|
|
env=self.build_env())
|
|
|
|
@Command('rustup',
|
|
description='Update the Rust version to latest Nightly',
|
|
category='devenv')
|
|
def rustup(self):
|
|
nightly_date = urllib.request.urlopen(
|
|
"https://static.rust-lang.org/dist/channel-rust-nightly-date.txt").read()
|
|
new_toolchain = f"nightly-{nightly_date.decode('utf-8')}"
|
|
old_toolchain = self.rust_toolchain()
|
|
|
|
filename = path.join(self.context.topdir, "rust-toolchain.toml")
|
|
with open(filename, "r", encoding="utf-8") as file:
|
|
contents = file.read()
|
|
contents = contents.replace(old_toolchain, new_toolchain)
|
|
with open(filename, "w", encoding="utf-8") as file:
|
|
file.write(contents)
|
|
|
|
self.ensure_bootstrapped()
|
|
|
|
@Command('fetch',
|
|
description='Fetch Rust, Cargo and Cargo dependencies',
|
|
category='devenv')
|
|
def fetch(self):
|
|
self.ensure_bootstrapped()
|
|
return call(["cargo", "fetch"], env=self.build_env())
|
|
|
|
@Command('ndk-stack',
|
|
description='Invoke the ndk-stack tool with the expected symbol paths',
|
|
category='devenv')
|
|
@CommandArgument('--release', action='store_true', help="Use release build symbols")
|
|
@CommandArgument('--target', action='store', default="armv7-linux-androideabi",
|
|
help="Build target")
|
|
@CommandArgument('logfile', action='store', help="Path to logcat output with crash report")
|
|
def stack(self, release, target, logfile):
|
|
if not path.isfile(logfile):
|
|
print(logfile + " doesn't exist")
|
|
return -1
|
|
|
|
self.cross_compile_target = target
|
|
env = self.build_env()
|
|
ndk_stack = path.join(env["ANDROID_NDK"], "ndk-stack")
|
|
self.setup_configuration_for_android_target(target)
|
|
sym_path = path.join(
|
|
"target",
|
|
target,
|
|
"release" if release else "debug",
|
|
"apk",
|
|
"obj",
|
|
"local",
|
|
self.config["android"]["lib"])
|
|
print(subprocess.check_output([ndk_stack, "-sym", sym_path, "-dump", logfile]))
|
|
|
|
@Command('ndk-gdb',
|
|
description='Invoke ndk-gdb tool with the expected symbol paths',
|
|
category='devenv')
|
|
@CommandArgument('--release', action='store_true', help="Use release build symbols")
|
|
@CommandArgument('--target', action='store', default="armv7-linux-androideabi",
|
|
help="Build target")
|
|
def ndk_gdb(self, release, target):
|
|
self.cross_compile_target = target
|
|
self.setup_configuration_for_android_target(target)
|
|
env = self.build_env()
|
|
ndk_gdb = path.join(env["ANDROID_NDK"], "ndk-gdb")
|
|
adb_path = path.join(env["ANDROID_SDK"], "platform-tools", "adb")
|
|
sym_paths = [
|
|
path.join(
|
|
getcwd(),
|
|
"target",
|
|
target,
|
|
"release" if release else "debug",
|
|
"apk",
|
|
"obj",
|
|
"local",
|
|
self.config["android"]["lib"]
|
|
),
|
|
path.join(
|
|
getcwd(),
|
|
"target",
|
|
target,
|
|
"release" if release else "debug",
|
|
"apk",
|
|
"libs",
|
|
self.config["android"]["lib"]
|
|
),
|
|
]
|
|
env["NDK_PROJECT_PATH"] = path.join(getcwd(), "support", "android", "apk")
|
|
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
|
|
|
with tempfile.NamedTemporaryFile(delete=False) as f:
|
|
f.write('\n'.join([
|
|
"python",
|
|
"param = gdb.parameter('solib-search-path')",
|
|
"param += ':{}'".format(':'.join(sym_paths)),
|
|
"gdb.execute('set solib-search-path ' + param)",
|
|
"end",
|
|
]))
|
|
|
|
p = subprocess.Popen([
|
|
ndk_gdb,
|
|
"--adb", adb_path,
|
|
"--project", "support/android/apk/servoapp/src/main/",
|
|
"--launch", "org.mozilla.servo.MainActivity",
|
|
"-x", f.name,
|
|
"--verbose",
|
|
], env=env)
|
|
return p.wait()
|
|
|
|
@Command('try',
|
|
description='Runs try jobs by force pushing to try branch',
|
|
category='devenv')
|
|
@CommandArgument(
|
|
'--remote', '-r', default="origin",
|
|
help='git remote to use for try pushes')
|
|
@CommandArgument(
|
|
'try_string', default=None, nargs='...',
|
|
help="Try string")
|
|
def try_jobs(self, remote="origin", try_string=None):
|
|
if not try_string:
|
|
try_string = "full"
|
|
else:
|
|
try_string = " ".join(try_string)
|
|
conf = Config(try_string)
|
|
result = call(["git", "commit", "--allow-empty", "-m", try_string, "-m", f"{conf.to_json()}"])
|
|
if result != 0:
|
|
return result
|
|
|
|
git_remote = subprocess.check_output(["git", "config", "--get", f"remote.{remote}.url"]).decode()
|
|
if "servo/servo" in git_remote:
|
|
print("WARNING: You are triggering try build in upstream repo!")
|
|
|
|
result = call(["git", "push", remote, "--force", "HEAD:try"])
|
|
if result != 0:
|
|
return result
|
|
|
|
git_remote = git_remote.replace(".git", "/actions")
|
|
print(f"You can find triggered workflow here: {git_remote}")
|
|
|
|
# Remove the last commit which only contains the try configuration.
|
|
result += call(["git", "reset", "--soft", "HEAD~1"])
|
|
return result
|