| // Copyright 2023 The Flutter Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd. |
| |
| import 'dart:io'; |
| |
| import 'package:args/command_runner.dart'; |
| import 'package:devtools_tool/commands/shared.dart'; |
| import 'package:devtools_tool/model.dart'; |
| import 'package:io/io.dart'; |
| import 'package:path/path.dart' as path; |
| |
| import '../utils.dart'; |
| |
| /// This command builds the DevTools Flutter web app. |
| /// |
| /// By default, this command builds DevTools in release mode, but this can be |
| /// overridden by passing 'debug' or 'profile' as the |
| /// [SharedCommandArgs.buildMode] argument. For testing embedded content in |
| /// VS Code, 'profile' or the default 'release' mode must be used because |
| /// the '--dart2js-optimization=O1' flag that is passed for 'debug' builds |
| /// will cause issues with the VS Code embedding. |
| /// |
| /// If the [SharedCommandArgs.useFlutterFromPath] argument is present, the |
| /// Flutter SDK will not be updated to the latest Flutter candidate before |
| /// building DevTools. Use this flag to save the cost of updating the Flutter |
| /// SDK when you already have the proper SDK checked out. This is helpful when |
| /// developing with the DevTools server. |
| /// |
| /// If the [SharedCommandArgs.updatePerfetto] argument is present, the |
| /// precompiled bits for Perfetto will be updated from the |
| /// `dt update-perfetto` command as part of the DevTools build |
| /// process. |
| /// |
| /// If [SharedCommandArgs.pubGet] argument is negated (e.g. --no-pub-get), then |
| /// `dt pub-get --only-main` command will not be run before building |
| /// the DevTools web app. Use this flag to save the cost of updating pub |
| /// packages if your pub cahce does not need to be updated. This is helpful when |
| /// developing with the DevTools server. |
| class BuildCommand extends Command { |
| BuildCommand() { |
| argParser |
| ..addUpdateFlutterFlag() |
| ..addUpdatePerfettoFlag() |
| ..addPubGetFlag() |
| ..addBulidModeOption() |
| ..addWasmFlag() |
| ..addNoStripWasmFlag() |
| ..addNoMinifyWasmFlag(); |
| } |
| |
| @override |
| String get name => 'build'; |
| |
| @override |
| String get description => 'Prepares a release build of DevTools.'; |
| |
| @override |
| Future run() async { |
| final repo = DevToolsRepo.getInstance(); |
| final processManager = ProcessManager(); |
| final results = argResults!; |
| final updateFlutter = |
| results[SharedCommandArgs.updateFlutter.flagName] as bool; |
| final updatePerfetto = |
| results[SharedCommandArgs.updatePerfetto.flagName] as bool; |
| final runPubGet = results[SharedCommandArgs.pubGet.flagName] as bool; |
| final buildMode = results[SharedCommandArgs.buildMode.flagName] as String; |
| final useWasm = results[SharedCommandArgs.wasm.flagName] as bool; |
| final noStripWasm = results[SharedCommandArgs.noStripWasm.flagName] as bool; |
| final noMinifyWasm = |
| results[SharedCommandArgs.noMinifyWasm.flagName] as bool; |
| |
| final webBuildDir = Directory( |
| path.join(repo.devtoolsAppDirectoryPath, 'build', 'web'), |
| ); |
| |
| if (updateFlutter) { |
| logStatus('updating tool/flutter-sdk to the latest flutter candidate'); |
| await processManager.runProcess(CliCommand.tool(['update-flutter-sdk'])); |
| } |
| |
| if (updatePerfetto) { |
| logStatus('updating the bundled Perfetto assets'); |
| await processManager.runProcess(CliCommand.tool(['update-perfetto'])); |
| } |
| |
| logStatus('cleaning project'); |
| if (webBuildDir.existsSync()) { |
| webBuildDir.deleteSync(recursive: true); |
| } |
| await processManager.runProcess( |
| CliCommand.flutter(['clean']), |
| workingDirectory: repo.devtoolsAppDirectoryPath, |
| ); |
| |
| logStatus( |
| 'building DevTools in $buildMode mode with ' |
| '${useWasm ? 'dart2wasm' : 'dart2js'}', |
| ); |
| await processManager.runAll( |
| commands: [ |
| if (runPubGet) CliCommand.tool(['pub-get', '--only-main']), |
| CliCommand.flutter([ |
| 'build', |
| 'web', |
| '--source-maps', |
| if (useWasm) ...[ |
| SharedCommandArgs.wasm.asArg(), |
| if (noStripWasm) SharedCommandArgs.noStripWasm.asArg(), |
| if (noMinifyWasm) SharedCommandArgs.noMinifyWasm.asArg(), |
| ] else ...[ |
| // Do not minify stack traces in debug mode. |
| if (buildMode == 'debug') '--dart2js-optimization=O1', |
| if (buildMode != 'debug') '--$buildMode', |
| ], |
| '--pwa-strategy=offline-first', |
| '--no-tree-shake-icons', |
| ]), |
| ], |
| workingDirectory: repo.devtoolsAppDirectoryPath, |
| ); |
| |
| // TODO(kenz): investigate if we need to perform a windows equivalent of |
| // `chmod` or if we even need to perform `chmod` for linux / mac anymore. |
| if (!Platform.isWindows) { |
| final canvaskitDir = Directory(path.join(webBuildDir.path, 'canvaskit')); |
| for (final file in canvaskitDir.listSync()) { |
| if (RegExp(r'canvaskit\..*').hasMatch(file.path)) { |
| await processManager.runProcess( |
| CliCommand('chmod', ['0755', file.path]), |
| ); |
| } |
| } |
| } |
| } |
| } |