Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library package.map.provider; | |
| 6 | |
| 7 import 'dart:convert'; | |
| 8 import 'dart:io' as io; | |
| 9 | |
| 10 import 'package:analysis_server/src/analysis_server.dart'; | |
| 11 import 'package:analysis_server/src/resource.dart'; | |
| 12 import 'package:analyzer/src/generated/engine.dart'; | |
| 13 | |
| 14 /** | |
| 15 * A PackageMapProvider is an entity capable of determining the mapping from | |
| 16 * package name to source directory for a given folder. | |
| 17 */ | |
| 18 abstract class PackageMapProvider { | |
| 19 /** | |
| 20 * Compute a package map for the given folder, if possible. | |
| 21 * | |
| 22 * If a package map can't be computed, return null. | |
| 23 */ | |
| 24 Map<String, Folder> computePackageMap(Folder folder); | |
| 25 } | |
| 26 | |
| 27 /** | |
| 28 * Implementation of PackageMapProvider that operates by executing pub. | |
| 29 */ | |
| 30 class PubPackageMapProvider implements PackageMapProvider { | |
| 31 static const String PUB_LIST_COMMAND = 'list-package-dirs'; | |
| 32 | |
| 33 /** | |
| 34 * [ResourceProvider] that is used to create the [Folder]s that populate the | |
| 35 * package map. | |
| 36 */ | |
| 37 final ResourceProvider resourceProvider; | |
| 38 | |
| 39 PubPackageMapProvider(this.resourceProvider); | |
| 40 | |
| 41 @override | |
| 42 Map<String, Folder> computePackageMap(Folder folder) { | |
| 43 // TODO(paulberry) make this asynchronous so that we can (a) do other | |
| 44 // analysis while it's in progress, and (b) time out if it takes too long | |
| 45 // to respond. | |
| 46 String executable = SHARED_SDK.pubExecutable.getAbsolutePath(); | |
| 47 io.ProcessResult result; | |
| 48 try { | |
| 49 result = io.Process.runSync( | |
| 50 executable, [PUB_LIST_COMMAND], workingDirectory: folder.path); | |
| 51 } on io.ProcessException catch (exception, stackTrace) { | |
| 52 AnalysisEngine.instance.logger.logInformation( | |
|
Brian Wilkerson
2014/06/20 14:42:46
These errors seems like something we should report
| |
| 53 "Error running pub $PUB_LIST_COMMAND\n${exception}\n${stackTrace}"); | |
| 54 } | |
| 55 if (result.exitCode != 0) { | |
| 56 AnalysisEngine.instance.logger.logInformation( | |
| 57 "pub $PUB_LIST_COMMAND failed: exit code ${result.exitCode}"); | |
| 58 return null; | |
| 59 } | |
| 60 try { | |
| 61 return parsePackageMap(result.stdout); | |
| 62 } catch (exception, stackTrace) { | |
| 63 AnalysisEngine.instance.logger.logError( | |
| 64 "Malformed output from pub $PUB_LIST_COMMAND\n${exception}\n${stackTra ce}"); | |
| 65 } | |
| 66 | |
| 67 return null; | |
| 68 } | |
| 69 | |
| 70 /** | |
| 71 * Decode the JSON output from pub into a package map. | |
| 72 */ | |
| 73 Map<String, Folder> parsePackageMap(String jsonText) { | |
| 74 // The output of pub looks like this: | |
| 75 // { | |
| 76 // "packages": { | |
| 77 // "foo": "path/to/foo", | |
| 78 // "bar": ["path/to/bar1", "path/to/bar2"], | |
| 79 // "myapp": "path/to/myapp", // self link is included | |
| 80 // }, | |
| 81 // "input_files": [ | |
| 82 // "path/to/myapp/pubspec.lock" | |
| 83 // ] | |
| 84 // } | |
| 85 Map<String, Folder> packageMap = <String, Folder>{}; | |
| 86 Map obj = JSON.decode(jsonText); | |
| 87 Map packages = obj['packages']; | |
| 88 packages.forEach((key, value) { | |
| 89 if (value is String) { | |
| 90 Resource resource = resourceProvider.getResource(value); | |
| 91 if (resource is Folder) { | |
| 92 packageMap[key] = resource; | |
| 93 } | |
| 94 } else if (value is List) { | |
| 95 // TODO(paulberry): support string lists. | |
| 96 } | |
| 97 }); | |
| 98 return packageMap; | |
| 99 } | |
| 100 } | |
| OLD | NEW |