Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(767)

Side by Side Diff: analyzer/lib/source/pub_package_map_provider.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « analyzer/lib/source/package_map_resolver.dart ('k') | analyzer/lib/source/sdk_ext.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 source.pub_package_map_provider;
6
7 import 'dart:collection';
8 import 'dart:convert';
9 import 'dart:core' hide Resource;
10 import 'dart:io' as io;
11
12 import 'package:analyzer/file_system/file_system.dart';
13 import 'package:analyzer/source/package_map_provider.dart';
14 import 'package:analyzer/src/generated/engine.dart';
15 import 'package:analyzer/src/generated/sdk_io.dart';
16
17 /**
18 * The function used to run pub list.
19 */
20 typedef io.ProcessResult RunPubList(Folder folder);
21
22 /**
23 * Implementation of PackageMapProvider that operates by executing pub.
24 */
25 class PubPackageMapProvider implements PackageMapProvider {
26 static const String PUB_LIST_COMMAND = 'list-package-dirs';
27
28 /**
29 * The name of the 'pubspec.lock' file, which we assume is the dependency
30 * in the event that [PUB_LIST_COMMAND] fails.
31 */
32 static const String PUBSPEC_LOCK_NAME = 'pubspec.lock';
33
34 /**
35 * [ResourceProvider] that is used to create the [Folder]s that populate the
36 * package map.
37 */
38 final ResourceProvider resourceProvider;
39
40 /**
41 * Sdk that we use to find the pub executable.
42 */
43 final DirectoryBasedDartSdk sdk;
44
45 /**
46 * The function used to run pub list.
47 */
48 RunPubList _runPubList;
49
50 /**
51 * Construct a new instance.
52 * A [RunPubList] implementation may be injected for testing
53 */
54 PubPackageMapProvider(this.resourceProvider, this.sdk, [this._runPubList]) {
55 if (_runPubList == null) {
56 _runPubList = _runPubListDefault;
57 }
58 }
59
60 @override
61 PackageMapInfo computePackageMap(Folder folder) {
62 // TODO(paulberry) make this asynchronous so that we can (a) do other
63 // analysis while it's in progress, and (b) time out if it takes too long
64 // to respond.
65 io.ProcessResult result;
66 try {
67 result = _runPubList(folder);
68 } on io.ProcessException catch (exception, stackTrace) {
69 AnalysisEngine.instance.logger.logInformation(
70 "Error running pub $PUB_LIST_COMMAND\n$exception\n$stackTrace");
71 }
72 if (result == null || result.exitCode != 0) {
73 String exitCode =
74 result != null ? 'exit code ${result.exitCode}' : 'null';
75 AnalysisEngine.instance.logger
76 .logInformation("pub $PUB_LIST_COMMAND failed: $exitCode");
77 return computePackageMapError(folder);
78 }
79 try {
80 PackageMapInfo packageMap =
81 parsePackageMap(JSON.decode(result.stdout), folder);
82 return packageMap;
83 } catch (exception, stackTrace) {
84 AnalysisEngine.instance.logger.logError(
85 "Malformed output from pub $PUB_LIST_COMMAND\n$exception\n$stackTrace" );
86 }
87
88 return computePackageMapError(folder);
89 }
90
91 /**
92 * Create a PackageMapInfo object representing an error condition.
93 */
94 PackageMapInfo computePackageMapError(Folder folder) {
95 // Even if an error occurs, we still need to know the dependencies, so that
96 // we'll know when to try running "pub list-package-dirs" again.
97 // Unfortunately, "pub list-package-dirs" doesn't tell us dependencies when
98 // an error occurs, so just assume there is one dependency, "pubspec.lock".
99 List<String> dependencies = <String>[
100 resourceProvider.pathContext.join(folder.path, PUBSPEC_LOCK_NAME)
101 ];
102 return new PackageMapInfo(null, dependencies.toSet());
103 }
104
105 /**
106 * Decode the JSON output from pub into a package map. Paths in the
107 * output are considered relative to [folder].
108 */
109 PackageMapInfo parsePackageMap(Map obj, Folder folder) {
110 // The output of pub looks like this:
111 // {
112 // "packages": {
113 // "foo": "path/to/foo",
114 // "bar": ["path/to/bar1", "path/to/bar2"],
115 // "myapp": "path/to/myapp", // self link is included
116 // },
117 // "input_files": [
118 // "path/to/myapp/pubspec.lock"
119 // ]
120 // }
121 Map<String, List<Folder>> packageMap = new HashMap<String, List<Folder>>();
122 Map packages = obj['packages'];
123 processPaths(String packageName, List paths) {
124 List<Folder> folders = <Folder>[];
125 for (var path in paths) {
126 if (path is String) {
127 Resource resource = folder.getChildAssumingFolder(path);
128 if (resource is Folder) {
129 folders.add(resource);
130 }
131 }
132 }
133 if (folders.isNotEmpty) {
134 packageMap[packageName] = folders;
135 }
136 }
137 packages.forEach((key, value) {
138 if (value is String) {
139 processPaths(key, [value]);
140 } else if (value is List) {
141 processPaths(key, value);
142 }
143 });
144 Set<String> dependencies = new Set<String>();
145 List inputFiles = obj['input_files'];
146 if (inputFiles != null) {
147 for (var path in inputFiles) {
148 if (path is String) {
149 dependencies.add(folder.canonicalizePath(path));
150 }
151 }
152 }
153 return new PackageMapInfo(packageMap, dependencies);
154 }
155
156 /**
157 * Run pub list to determine the packages and input files.
158 */
159 io.ProcessResult _runPubListDefault(Folder folder) {
160 String executablePath = sdk.pubExecutable.getAbsolutePath();
161 List<String> arguments = [PUB_LIST_COMMAND];
162 String workingDirectory = folder.path;
163 int subprocessId = AnalysisEngine.instance.instrumentationService
164 .logSubprocessStart(executablePath, arguments, workingDirectory);
165 io.ProcessResult result = io.Process.runSync(executablePath, arguments,
166 workingDirectory: workingDirectory);
167 AnalysisEngine.instance.instrumentationService.logSubprocessResult(
168 subprocessId, result.exitCode, result.stdout, result.stderr);
169 return result;
170 }
171 }
OLDNEW
« no previous file with comments | « analyzer/lib/source/package_map_resolver.dart ('k') | analyzer/lib/source/sdk_ext.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698