| // Copyright (c) 2014, 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 'dart:async'; |
| import 'dart:io'; |
| |
| import 'package:args/args.dart'; |
| import 'package:analysis_server/src/analysis_manager.dart'; |
| |
| /** |
| * Start analysis server as a separate process and use the websocket protocol |
| * to analyze the application specified on the command line. |
| */ |
| void main(List<String> args) { |
| new _DartDependencyAnalyzer(args).run() |
| .catchError((error, stack) { |
| print('Analysis failed: $error'); |
| if (stack != null) { |
| print(stack); |
| } |
| }); |
| } |
| |
| /** |
| * Instances of [_DartDependencyAnalyzer] launch an analysis server and use |
| * that server to analyze the dependencies of an application. |
| */ |
| class _DartDependencyAnalyzer { |
| /** |
| * The name of the application that is used to start the analyzer. |
| */ |
| static const BINARY_NAME = 'dartdeps'; |
| |
| /** |
| * The name of the option used to specify the Dart SDK. |
| */ |
| static const String DART_SDK_OPTION = 'dart-sdk'; |
| |
| /** |
| * The name of the option used to print usage information. |
| */ |
| static const String HELP_OPTION = 'help'; |
| |
| /** |
| * The name of the option used to specify an already running server. |
| */ |
| static const String SERVER_OPTION = 'server'; |
| |
| /** |
| * The command line arguments. |
| */ |
| final List<String> args; |
| |
| /** |
| * The path to the Dart SDK used during analysis. |
| */ |
| String sdkPath; |
| |
| /** |
| * The manager for the analysis server. |
| */ |
| AnalysisManager manager; |
| |
| _DartDependencyAnalyzer(this.args); |
| |
| /** |
| * Parse the command line arguments to determine the application to be |
| * analyzed, then launch and manage an analysis server to do the work. |
| */ |
| Future run() { |
| return new Future(start).then(analyze).whenComplete(stop); |
| } |
| |
| /** |
| * Parse the command line arguments to determine the application to be |
| * analyzed, then launch an analysis server. |
| * Return `null` if the command line arguments are invalid. |
| */ |
| Future<AnalysisManager> start() { |
| ArgParser parser = new ArgParser(); |
| parser.addOption( |
| DART_SDK_OPTION, |
| help: '[sdkPath] path to Dart SDK'); |
| parser.addFlag(HELP_OPTION, |
| help: 'print this help message without starting analysis', |
| defaultsTo: false, |
| negatable: false); |
| parser.addOption( |
| SERVER_OPTION, |
| help: '[serverUrl] use an analysis server thats already running'); |
| |
| // Parse arguments |
| ArgResults results; |
| try { |
| results = parser.parse(args); |
| } on FormatException catch(e) { |
| print(e.message); |
| print(''); |
| printUsage(parser); |
| exitCode = 1; |
| return null; |
| } |
| if (results[HELP_OPTION]) { |
| printUsage(parser); |
| return null; |
| } |
| sdkPath = results[DART_SDK_OPTION]; |
| if (sdkPath is! String) { |
| print('Missing path to Dart SDK'); |
| printUsage(parser); |
| return null; |
| } |
| Directory sdkDir = new Directory(sdkPath); |
| if (!sdkDir.existsSync()) { |
| print('Specified Dart SDK does not exist: $sdkPath'); |
| printUsage(parser); |
| return null; |
| } |
| if (results.rest.length == 0) { |
| printUsage(parser); |
| exitCode = 1; |
| return null; |
| } |
| Directory appDir = new Directory(results.rest[0]); |
| if (!appDir.existsSync()) { |
| print('Specified application directory does not exist: $appDir'); |
| print(''); |
| printUsage(parser); |
| exitCode = 1; |
| return null; |
| } |
| if (results.rest.length > 1) { |
| print('Unexpected arguments after $appDir'); |
| print(''); |
| printUsage(parser); |
| exitCode = 1; |
| return null; |
| } |
| |
| // Connect to an already running analysis server |
| String serverUrl = results[SERVER_OPTION]; |
| if (serverUrl != null) { |
| return AnalysisManager.connect(serverUrl); |
| } |
| |
| // Launch and connect to a new analysis server |
| // Assume that the analysis server entry point is in the same directory |
| StringBuffer path = new StringBuffer(); |
| path.write(FileSystemEntity.parentOf(Platform.script.toFilePath())); |
| path.write(Platform.pathSeparator); |
| path.write('server.dart'); |
| return AnalysisManager.start(path.toString()); |
| } |
| |
| /** |
| * Use the given manager to perform the analysis. |
| */ |
| void analyze(AnalysisManager manager) { |
| if (manager == null) { |
| return; |
| } |
| this.manager = manager; |
| print('Analyzing...'); |
| } |
| |
| /** |
| * Stop the analysis server. |
| */ |
| void stop() { |
| if (manager != null) { |
| manager.stop(); |
| } |
| } |
| |
| /** |
| * Print information about how to use the server. |
| */ |
| void printUsage(ArgParser parser) { |
| print('Usage: $BINARY_NAME [flags] <application_directory>'); |
| print(''); |
| print('Supported flags are:'); |
| print(parser.getUsage()); |
| } |
| } |