#!/usr/bin/env python3 # Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file # for details. All rights reserved. Use of this source code is governed by a # BSD-style license that can be found in the LICENSE file. import argparse import os import shutil import subprocess import sys tools_dir = os.path.dirname(os.path.realpath(__file__)) sys.path.append(tools_dir) import utils def main(): parser = argparse.ArgumentParser(description='Builds the DevTools app.') parser.add_argument('--output', help='Output directory') args = parser.parse_args() if args.output: args.output = os.path.abspath(args.output) # Set up paths relative to the SDK root. sdk_root = utils.DART_DIR devtools_src_dir = os.path.join(sdk_root, 'third_party', 'devtools_src') devtools_app_dir = os.path.join(devtools_src_dir, 'packages', 'devtools_app') if not os.path.isdir(devtools_src_dir): print( f'Missing devtools dir in devtools sources "{devtools_src_dir}"; ' 'make sure that "../.client" has a `custom_vars` section with ' '"`"build_devtools_from_sources": True,` and then run `gclient sync`' '\n') return 1 if not os.path.isdir(devtools_app_dir): print( f'Error: DevTools app directory not found at {devtools_app_dir}\n') return 1 flutter_bin = os.path.normpath( os.path.join(sdk_root, 'third_party', 'flutter', 'bin', 'flutter')) if utils.GuessOS() == 'win32': flutter_bin += '.bat' if not os.path.isfile(flutter_bin): print( f'Missing Flutter SDK at "{flutter_bin}"; ' 'make sure that "../.client" has a `custom_vars` section with ' '"`"build_devtools_from_sources": True,` and then run `gclient sync`' '\n') return 1 try: os.chdir(devtools_app_dir) print(f'Running {flutter_bin} pub get...') subprocess.run([flutter_bin, 'pub', 'get'], check=True) print(f'Changing directory to {devtools_src_dir}') os.chdir(devtools_src_dir) # We use the 'dart' binary found in the same directory as the 'flutter' binary. dart_bin = os.path.join(os.path.dirname(flutter_bin), 'dart') if utils.GuessOS() == 'win32': dart_bin += '.exe' dt_path = os.path.join('tool', 'bin', 'dt.dart') print(f'Building DevTools web app using dt tool...') build_command = [ dart_bin, dt_path, f'--flutter-sdk-path={flutter_bin}', 'build' ] subprocess.run(build_command, check=True) build_dir = os.path.join(devtools_app_dir, 'build', 'web') main_js = os.path.join(build_dir, 'main.dart.js') main_wasm = os.path.join(build_dir, 'main.dart.wasm') if not os.path.isfile(main_js): print(f'Missing expected built JS app at "{main_js}"\n') return 1 if not os.path.isfile(main_wasm): print(f'Missing expected built WASM app at "{main_wasm}"\n') return 1 if args.output: print(f'Copying build results to {args.output}...') if os.path.isdir(args.output): shutil.rmtree(args.output) elif os.path.exists(args.output): os.remove(args.output) shutil.copytree(build_dir, args.output) print('DevTools build successful.') return 0 except subprocess.CalledProcessError as e: print(f'Error: Command failed with exit code {e.returncode}') return e.returncode except Exception as e: print(f'An unexpected error occurred: {e}') return 1 if __name__ == '__main__': sys.exit(main())