| // Copyright (c) 2019, 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. |
| |
| // @dart = 2.9 |
| |
| import 'dart:async'; |
| |
| import 'package:args/args.dart'; |
| import 'package:args/command_runner.dart'; |
| |
| import '../logging.dart'; |
| import '../serve/dev_workflow.dart'; |
| import 'configuration.dart'; |
| import 'shared.dart'; |
| |
| /// Command to run a server for local web development with the build daemon. |
| class ServeCommand extends Command<int> { |
| @override |
| final name = 'serve'; |
| |
| @override |
| final description = 'Run a local web development server and a file system' |
| ' watcher that rebuilds on changes.'; |
| |
| @override |
| final argParser = ArgParser(usageLineLength: lineLength) |
| ..addOption(autoOption, help: ''' |
| Automatically performs an action after each build: |
| |
| restart: Reload modules and re-invoke main (loses current state) |
| refresh: Performs a full page refresh. |
| ''', allowed: ['restart', 'refresh']) |
| ..addFlag(debugFlag, |
| help: 'Enable the launching of DevTools (Alt + D / Option + D). ' |
| 'This also enables --$launchInChromeFlag.') |
| ..addFlag(debugExtensionFlag, |
| help: 'Enable the backend for the Dart Debug Extension.') |
| ..addFlag(enableInjectedClientFlag, |
| help: 'Whether or not to inject the client.js script in web apps. This ' |
| 'is required for all debugging related features, but may interact ' |
| 'poorly with proxy servers or other environments.', |
| defaultsTo: true) |
| ..addSeparator('Advanced:') |
| ..addOption(chromeDebugPortFlag, |
| help: 'Specify which port the Chrome debugger is listening on. ' |
| 'If used with $launchInChromeFlag Chrome will be started with the' |
| ' debugger listening on this port.') |
| ..addOption(hostnameFlag, |
| help: 'Specify the hostname to serve on.', defaultsTo: 'localhost') |
| ..addFlag(hotRestartFlag, |
| negatable: false, |
| help: 'Automatically reloads changed modules after each build ' |
| 'and restarts your application.\n' |
| "Can't be used with $liveReloadFlag.", |
| hide: true) |
| ..addFlag(hotReloadFlag, negatable: false, hide: true) |
| ..addFlag(launchInChromeFlag, |
| help: 'Automatically launches your application in Chrome with the ' |
| 'debug port open. Use $chromeDebugPortFlag to specify a specific ' |
| 'port to attach to an already running chrome instance instead.') |
| ..addOption(userDataDirFlag, |
| defaultsTo: null, |
| help: 'Use with $launchInChromeFlag to specify user data directory ' |
| 'to pass to chrome. Will start chrome window logged into default ' |
| 'profile with enabled extensions. Use `auto` as a value to infer ' |
| 'the default directory for the current OS. ' |
| 'Note: only supported for Mac OS X and linux platforms.') |
| ..addFlag(liveReloadFlag, |
| negatable: false, |
| help: 'Automatically refreshes the page after each successful build.\n' |
| "Can't be used with $hotRestartFlag.", |
| hide: true) |
| ..addFlag(logRequestsFlag, |
| negatable: false, |
| help: 'Enables logging for each request to the server.') |
| ..addOption(tlsCertChainFlag, |
| help: |
| 'The file location to a TLS Certificate to create an HTTPs server.\n' |
| 'Must be used with $tlsCertKeyFlag.') |
| ..addOption(tlsCertKeyFlag, |
| help: 'The file location to a TLS Key to create an HTTPs server.\n' |
| 'Must be used with $tlsCertChainFlag.') |
| ..addSeparator('Common:'); |
| |
| ServeCommand() { |
| addSharedArgs(argParser, releaseDefault: false); |
| } |
| |
| @override |
| String get invocation => '${super.invocation} [<directory>[:<port>]]...'; |
| |
| @override |
| Future<int> run() async { |
| Configuration configuration; |
| configuration = Configuration.fromArgs(argResults); |
| configureLogWriter(configuration.verbose); |
| var pubspecLock = await readPubspecLock(configuration); |
| // Forward remaining arguments as Build Options to the Daemon. |
| // This isn't documented. Should it be advertised? |
| var buildOptions = buildRunnerArgs(pubspecLock, configuration) |
| ..addAll(argResults.rest.where((arg) => arg.startsWith('-')).toList()); |
| var directoryArgs = |
| argResults.rest.where((arg) => !arg.startsWith('-')).toList(); |
| var targetPorts = parseDirectoryArgs(directoryArgs); |
| validateLaunchApps(configuration.launchApps, targetPorts.keys); |
| |
| var workflow = |
| await DevWorkflow.start(configuration, buildOptions, targetPorts); |
| await workflow.done; |
| return 0; |
| } |
| } |