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

Side by Side Diff: pkg/analyzer/lib/source/package_map_provider.dart

Issue 599133002: Move PubPackageMapProvider to its own file. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library source.package_map_provider; 5 library source.package_map_provider;
6 6
7 import 'dart:collection';
8 import 'dart:convert';
9 import 'dart:io' as io;
10
11 import 'package:analyzer/file_system/file_system.dart'; 7 import 'package:analyzer/file_system/file_system.dart';
12 import 'package:analyzer/src/generated/engine.dart';
13 import 'package:analyzer/src/generated/sdk_io.dart';
14 import 'package:path/path.dart';
15 8
16 /** 9 /**
17 * Data structure output by PackageMapProvider. This contains both the package 10 * Data structure output by PackageMapProvider. This contains both the package
18 * map and dependency information. 11 * map and dependency information.
19 */ 12 */
20 class PackageMapInfo { 13 class PackageMapInfo {
21 /** 14 /**
22 * The package map itself. This is a map from package name to a list of 15 * The package map itself. This is a map from package name to a list of
23 * the folders containing source code for the package. 16 * the folders containing source code for the package.
24 * 17 *
(...skipping 17 matching lines...) Expand all
42 */ 35 */
43 abstract class PackageMapProvider { 36 abstract class PackageMapProvider {
44 /** 37 /**
45 * Compute a package map for the given folder, if possible. 38 * Compute a package map for the given folder, if possible.
46 * 39 *
47 * If a package map can't be computed (e.g. because an error occurred), a 40 * If a package map can't be computed (e.g. because an error occurred), a
48 * [PackageMapInfo] will still be returned, but its packageMap will be null. 41 * [PackageMapInfo] will still be returned, but its packageMap will be null.
49 */ 42 */
50 PackageMapInfo computePackageMap(Folder folder); 43 PackageMapInfo computePackageMap(Folder folder);
51 } 44 }
52
53 /**
54 * Implementation of PackageMapProvider that operates by executing pub.
55 */
56 class PubPackageMapProvider implements PackageMapProvider {
57 static const String PUB_LIST_COMMAND = 'list-package-dirs';
58
59 /**
60 * The name of the 'pubspec.lock' file, which we assume is the dependency
61 * in the event that [PUB_LIST_COMMAND] fails.
62 */
63 static const String PUBSPEC_LOCK_NAME = 'pubspec.lock';
64
65 /**
66 * [ResourceProvider] that is used to create the [Folder]s that populate the
67 * package map.
68 */
69 final ResourceProvider resourceProvider;
70
71 /**
72 * Sdk that we use to find the pub executable.
73 */
74 final DirectoryBasedDartSdk sdk;
75
76 PubPackageMapProvider(this.resourceProvider, this.sdk);
77
78 @override
79 PackageMapInfo computePackageMap(Folder folder) {
80 // TODO(paulberry) make this asynchronous so that we can (a) do other
81 // analysis while it's in progress, and (b) time out if it takes too long
82 // to respond.
83 String executable = sdk.pubExecutable.getAbsolutePath();
84 io.ProcessResult result;
85 try {
86 result = io.Process.runSync(
87 executable, [PUB_LIST_COMMAND], workingDirectory: folder.path);
88 } on io.ProcessException catch (exception, stackTrace) {
89 AnalysisEngine.instance.logger.logInformation(
90 "Error running pub $PUB_LIST_COMMAND\n${exception}\n${stackTrace}");
91 }
92 if (result.exitCode != 0) {
93 AnalysisEngine.instance.logger.logInformation(
94 "pub $PUB_LIST_COMMAND failed: exit code ${result.exitCode}");
95 return _error(folder);
96 }
97 try {
98 return parsePackageMap(result.stdout, folder);
99 } catch (exception, stackTrace) {
100 AnalysisEngine.instance.logger.logError(
101 "Malformed output from pub $PUB_LIST_COMMAND\n${exception}\n${stackTra ce}");
102 }
103
104 return _error(folder);
105 }
106
107 /**
108 * Decode the JSON output from pub into a package map. Paths in the
109 * output are considered relative to [folder].
110 */
111 PackageMapInfo parsePackageMap(String jsonText, Folder folder) {
112 // The output of pub looks like this:
113 // {
114 // "packages": {
115 // "foo": "path/to/foo",
116 // "bar": ["path/to/bar1", "path/to/bar2"],
117 // "myapp": "path/to/myapp", // self link is included
118 // },
119 // "input_files": [
120 // "path/to/myapp/pubspec.lock"
121 // ]
122 // }
123 Map<String, List<Folder>> packageMap = new HashMap<String, List<Folder>>();
124 Map obj = JSON.decode(jsonText);
125 Map packages = obj['packages'];
126 processPaths(String packageName, List paths) {
127 List<Folder> folders = <Folder>[];
128 for (var path in paths) {
129 if (path is String) {
130 Resource resource = folder.getChild(path);
131 if (resource is Folder) {
132 folders.add(resource);
133 }
134 }
135 }
136 if (folders.isNotEmpty) {
137 packageMap[packageName] = folders;
138 }
139 }
140 packages.forEach((key, value) {
141 if (value is String) {
142 processPaths(key, [value]);
143 } else if (value is List) {
144 processPaths(key, value);
145 }
146 });
147 Set<String> dependencies = new Set<String>();
148 List inputFiles = obj['input_files'];
149 if (inputFiles != null) {
150 for (var path in inputFiles) {
151 if (path is String) {
152 dependencies.add(folder.canonicalizePath(path));
153 }
154 }
155 }
156 return new PackageMapInfo(packageMap, dependencies);
157 }
158
159 /**
160 * Create a PackageMapInfo object representing an error condition.
161 */
162 PackageMapInfo _error(Folder folder) {
163 // Even if an error occurs, we still need to know the dependencies, so that
164 // we'll know when to try running "pub list-package-dirs" again.
165 // Unfortunately, "pub list-package-dirs" doesn't tell us dependencies when
166 // an error occurs, so just assume there is one dependency, "pubspec.lock".
167 List<String> dependencies = <String>[join(folder.path, PUBSPEC_LOCK_NAME)];
168 return new PackageMapInfo(null, dependencies.toSet());
169 }
170 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/lib/src/socket_server.dart ('k') | pkg/analyzer/lib/source/pub_package_map_provider.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698