-
Notifications
You must be signed in to change notification settings - Fork 6k
Introduce a GN rule that (explicitly) generates a dart test wrapper
#55475
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # Copyright 2013 The Flutter Authors. All rights reserved. | ||
| # Use of this source code is governed by a BSD-style license that can be | ||
| # found in the LICENSE file. | ||
|
|
||
| import("//flutter/build/dart/internal/gen_executable_call.gni") | ||
| import("//flutter/common/config.gni") | ||
|
|
||
| # Generates an executable that runs `dart` with a command and set of arguments. | ||
| # | ||
| # Parameters: | ||
| # args (optional): | ||
| # Arguments to pass to the Dart CLI. | ||
| # | ||
| # cwd (optional): | ||
| # The working directory for the command. | ||
| # | ||
| # output (optional): | ||
| # Overrides the full output path. | ||
| # Defaults to $root_out_dir/gen/$target_path/$target_name; for example | ||
| # //flutter/foo/bar emits a binary at out/{variant}/gen/flutter/foo/bar. | ||
| template("gen_dartcli_call") { | ||
| # Build a reference to the Dart CLI (depending on prebuilt or source). | ||
| ext = "" | ||
| if (is_win) { | ||
| ext = ".exe" | ||
| } | ||
| dart = rebase_path("$host_prebuilt_dart_sdk/bin/dart$ext") | ||
|
|
||
| # Actually generate the shell script. | ||
| gen_executable_call(target_name) { | ||
| command = rebase_path(dart) | ||
| forward_variables_from(invoker, | ||
| [ | ||
| "args", | ||
| "cwd", | ||
| "output", | ||
| ]) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| # Copyright 2013 The Flutter Authors. All rights reserved. | ||
| # Use of this source code is governed by a BSD-style license that can be | ||
| # found in the LICENSE file. | ||
|
|
||
| # Generates an executable that runs a command and set of arguments. | ||
| # | ||
| # Parameters: | ||
| # command (required): | ||
| # The command to run, which is typically an absolute path to an executable. | ||
| # | ||
| # args (optional): | ||
| # Arguments to pass to the command. | ||
| # | ||
| # cwd (optional): | ||
| # The working directory for the command. | ||
| # | ||
| # output (optional): | ||
| # Overrides the full output path. | ||
| # Defaults to $root_out_dir/gen/$target_path/$target_name; for example | ||
| # //flutter/foo/bar emits a binary at out/{variant}/gen/flutter/foo/bar. | ||
| template("gen_executable_call") { | ||
| assert(defined(invoker.command), "Must specify 'command'") | ||
|
|
||
| # The command to run. | ||
| command = invoker.command | ||
|
|
||
| # The output path. | ||
| output = "$root_gen_dir/$target_name" | ||
| if (defined(invoker.output)) { | ||
| output = invoker.output | ||
| } else { | ||
| # Construct the output path. | ||
| output = get_label_info(target_name, "target_gen_dir") | ||
| } | ||
|
|
||
| # Build the command line arguments. | ||
| call_args = [ | ||
| "--output", | ||
| rebase_path(output), | ||
| "--command", | ||
| command, | ||
| ] | ||
| if (defined(invoker.cwd)) { | ||
| call_args += [ | ||
| "--cwd", | ||
| rebase_path(invoker.cwd), | ||
| ] | ||
| } | ||
| if (defined(invoker.args)) { | ||
| call_args += [ | ||
| "--", | ||
| string_join(" ", invoker.args), | ||
| ] | ||
| } | ||
|
|
||
| # Run build_cmd.py to generate the file and make it executable. | ||
| action(target_name) { | ||
| script = "//flutter/build/dart/internal/gen_executable_call.py" | ||
| outputs = [ output ] | ||
| args = call_args | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| #!/usr/bin/env python3 | ||
| # | ||
| # Copyright 2013 The Flutter Authors. All rights reserved. | ||
| # Use of this source code is governed by a BSD-style license that can be | ||
| # found in the LICENSE file. | ||
|
|
||
| """Generates a shell or batch script to run a command.""" | ||
|
|
||
| import argparse | ||
| import os | ||
| import string | ||
|
|
||
|
|
||
| def main(): | ||
| parser = argparse.ArgumentParser(description=__doc__) | ||
| parser.add_argument('--output', required=True, help='Output file') | ||
| parser.add_argument('--command', required=True, help='Command to run') | ||
| parser.add_argument('--cwd', required=False, help='Working directory') | ||
| parser.add_argument('rest', nargs='*', help='Arguments to pass to the command') | ||
|
|
||
| # Rest of the arguments are passed to the command. | ||
| args = parser.parse_args() | ||
|
|
||
| out_path = os.path.dirname(args.output) | ||
| if not os.path.exists(out_path): | ||
| os.makedirs(out_path) | ||
|
|
||
| script = string.Template( | ||
| '''#!/bin/sh | ||
|
|
||
| set -e | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dumb question because I get tripped up on this constantly. set -e makes sure that the exit code of this script is non zero if the dart test exit code is non zero right? Can you check that failed tests report non-zero exit codes through the shell script too?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any command or pipeline that has an error will exit the script automatically. Dart tests that fail set errno 1. |
||
|
|
||
| # Needed because if it is set, cd may print the path it changed to. | ||
| unset CDPATH | ||
|
|
||
| # Store the current working directory. | ||
| prev_cwd=$$(pwd) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could save yourself a variable with
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done, that's much simpler! Added a PWD "test" as well. |
||
|
|
||
| # Set a trap to restore the working directory. | ||
| trap 'cd "$$prev_cwd"' EXIT | ||
|
|
||
| CD_PATH="$cwd" | ||
| if [ -n "$$CD_PATH" ]; then | ||
| cd "$$CD_PATH" | ||
| fi | ||
|
|
||
| $command "$args" | ||
| ''' | ||
| ) | ||
|
|
||
| # Convert args into an escaped string. | ||
| escaped = [arg.replace('"', '\\"') for arg in args.rest] | ||
|
|
||
| params = { | ||
| 'command': args.command, | ||
| 'args': '" "'.join(escaped), | ||
| 'cwd': args.cwd if args.cwd else '', | ||
| } | ||
|
|
||
| with open(args.output, 'w') as f: | ||
| f.write(script.substitute(params)) | ||
|
|
||
| # Make the script executable. | ||
| os.chmod(args.output, 0o755) | ||
|
|
||
|
|
||
| if __name__ == '__main__': | ||
| main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| # Copyright 2013 The Flutter Authors. All rights reserved. | ||
| # Use of this source code is governed by a BSD-style license that can be | ||
| # found in the LICENSE file. | ||
|
|
||
| import("//flutter/build/dart/internal/gen_dartcli_call.gni") | ||
| import("//flutter/build/dart/internal/gen_executable_call.gni") | ||
|
|
||
| # Manual test targets that can be used to iterate on individual rules. | ||
|
|
||
| # ninja -C ../out/host_debug flutter/build/dart/test:gen_executable_call | ||
| # ../out/host_debug/gen/flutter/build/dart/test/gen_executable_call | ||
| # | ||
| # Expected output: "Hello, World!" | ||
| gen_executable_call("gen_executable_call") { | ||
| command = "echo" | ||
| args = [ "Hello, World!" ] | ||
| } | ||
|
|
||
| # ninja -C ../out/host_debug flutter/build/dart/test:gen_dartcli_call | ||
| # ../out/host_debug/gen/flutter/build/dart/test/gen_executable_call | ||
| # | ||
| # Expected output: Dart SDK version: 3.6.0-273.0.dev (dev) | ||
| # | ||
| # ... or something like ^, obviously it will constantly change as the SDK rolls. | ||
| gen_dartcli_call("gen_dartcli_call") { | ||
| args = [ "--version" ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # Copyright 2013 The Flutter Authors. All rights reserved. | ||
| # Use of this source code is governed by a BSD-style license that can be | ||
| # found in the LICENSE file. | ||
|
|
||
| import("//flutter/build/dart/internal/gen_dartcli_call.gni") | ||
|
|
||
| # TODO(matanl): WIP in https://github.com/flutter/flutter/issues/155769. | ||
| # | ||
| # Example usage: | ||
| # ninja -C ../out/host_debug flutter/tools/engine_tool:tests | ||
| # ../out/host_debug/gen/flutter/tools/engine_tool/tests | ||
| gen_dartcli_call("tests") { | ||
| args = [ "test" ] | ||
| cwd = "//flutter/tools/engine_tool" | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I <3
restvsargs+1