| OLD | NEW |
| 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 package.map.provider; | 5 library package.map.provider; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 import 'dart:convert'; | 8 import 'dart:convert'; |
| 9 import 'dart:io' as io; | 9 import 'dart:io' as io; |
| 10 | 10 |
| 11 import 'package:analysis_server/src/analysis_server.dart'; | 11 import 'package:analysis_server/src/analysis_server.dart'; |
| 12 import 'package:analysis_server/src/resource.dart'; | 12 import 'package:analyzer/file_system/file_system.dart'; |
| 13 import 'package:analyzer/src/generated/engine.dart'; | 13 import 'package:analyzer/src/generated/engine.dart'; |
| 14 import 'package:path/path.dart'; | 14 import 'package:path/path.dart'; |
| 15 | 15 |
| 16 /** | 16 /** |
| 17 * A PackageMapProvider is an entity capable of determining the mapping from | |
| 18 * package name to source directory for a given folder. | |
| 19 */ | |
| 20 abstract class PackageMapProvider { | |
| 21 /** | |
| 22 * Compute a package map for the given folder, if possible. | |
| 23 * | |
| 24 * If a package map can't be computed (e.g. because an error occurred), a | |
| 25 * [PackageMapInfo] will still be returned, but its packageMap will be null. | |
| 26 */ | |
| 27 PackageMapInfo computePackageMap(Folder folder); | |
| 28 } | |
| 29 | |
| 30 /** | |
| 31 * Data structure output by PackageMapProvider. This contains both the package | 17 * Data structure output by PackageMapProvider. This contains both the package |
| 32 * map and dependency information. | 18 * map and dependency information. |
| 33 */ | 19 */ |
| 34 class PackageMapInfo { | 20 class PackageMapInfo { |
| 35 /** | 21 /** |
| 36 * The package map itself. This is a map from package name to a list of | 22 * The package map itself. This is a map from package name to a list of |
| 37 * the folders containing source code for the package. | 23 * the folders containing source code for the package. |
| 38 * | 24 * |
| 39 * `null` if an error occurred. | 25 * `null` if an error occurred. |
| 40 */ | 26 */ |
| 41 Map<String, List<Folder>> packageMap; | 27 Map<String, List<Folder>> packageMap; |
| 42 | 28 |
| 43 /** | 29 /** |
| 44 * Dependency information. This is a set of the paths which were consulted | 30 * Dependency information. This is a set of the paths which were consulted |
| 45 * in order to generate the package map. If any of these files is | 31 * in order to generate the package map. If any of these files is |
| 46 * modified, the package map will need to be regenerated. | 32 * modified, the package map will need to be regenerated. |
| 47 */ | 33 */ |
| 48 Set<String> dependencies; | 34 Set<String> dependencies; |
| 49 | 35 |
| 50 PackageMapInfo(this.packageMap, this.dependencies); | 36 PackageMapInfo(this.packageMap, this.dependencies); |
| 51 } | 37 } |
| 52 | 38 |
| 53 /** | 39 /** |
| 40 * A PackageMapProvider is an entity capable of determining the mapping from |
| 41 * package name to source directory for a given folder. |
| 42 */ |
| 43 abstract class PackageMapProvider { |
| 44 /** |
| 45 * Compute a package map for the given folder, if possible. |
| 46 * |
| 47 * 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. |
| 49 */ |
| 50 PackageMapInfo computePackageMap(Folder folder); |
| 51 } |
| 52 |
| 53 /** |
| 54 * Implementation of PackageMapProvider that operates by executing pub. | 54 * Implementation of PackageMapProvider that operates by executing pub. |
| 55 */ | 55 */ |
| 56 class PubPackageMapProvider implements PackageMapProvider { | 56 class PubPackageMapProvider implements PackageMapProvider { |
| 57 static const String PUB_LIST_COMMAND = 'list-package-dirs'; | 57 static const String PUB_LIST_COMMAND = 'list-package-dirs'; |
| 58 | 58 |
| 59 /** | 59 /** |
| 60 * The name of the 'pubspec.lock' file, which we assume is the dependency | 60 * The name of the 'pubspec.lock' file, which we assume is the dependency |
| 61 * in the event that [PUB_LIST_COMMAND] fails. | 61 * in the event that [PUB_LIST_COMMAND] fails. |
| 62 */ | 62 */ |
| 63 static const String PUBSPEC_LOCK_NAME = 'pubspec.lock'; | 63 static const String PUBSPEC_LOCK_NAME = 'pubspec.lock'; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 93 return parsePackageMap(result.stdout, folder); | 93 return parsePackageMap(result.stdout, folder); |
| 94 } catch (exception, stackTrace) { | 94 } catch (exception, stackTrace) { |
| 95 AnalysisEngine.instance.logger.logError( | 95 AnalysisEngine.instance.logger.logError( |
| 96 "Malformed output from pub $PUB_LIST_COMMAND\n${exception}\n${stackTra
ce}"); | 96 "Malformed output from pub $PUB_LIST_COMMAND\n${exception}\n${stackTra
ce}"); |
| 97 } | 97 } |
| 98 | 98 |
| 99 return _error(folder); | 99 return _error(folder); |
| 100 } | 100 } |
| 101 | 101 |
| 102 /** | 102 /** |
| 103 * Create a PackageMapInfo object representing an error condition. | |
| 104 */ | |
| 105 PackageMapInfo _error(Folder folder) { | |
| 106 // Even if an error occurs, we still need to know the dependencies, so that | |
| 107 // we'll know when to try running "pub list-package-dirs" again. | |
| 108 // Unfortunately, "pub list-package-dirs" doesn't tell us dependencies when | |
| 109 // an error occurs, so just assume there is one dependency, "pubspec.lock". | |
| 110 List<String> dependencies = <String>[join(folder.path, PUBSPEC_LOCK_NAME)]; | |
| 111 return new PackageMapInfo(null, dependencies.toSet()); | |
| 112 } | |
| 113 | |
| 114 /** | |
| 115 * Decode the JSON output from pub into a package map. Paths in the | 103 * Decode the JSON output from pub into a package map. Paths in the |
| 116 * output are considered relative to [folder]. | 104 * output are considered relative to [folder]. |
| 117 */ | 105 */ |
| 118 PackageMapInfo parsePackageMap(String jsonText, Folder folder) { | 106 PackageMapInfo parsePackageMap(String jsonText, Folder folder) { |
| 119 // The output of pub looks like this: | 107 // The output of pub looks like this: |
| 120 // { | 108 // { |
| 121 // "packages": { | 109 // "packages": { |
| 122 // "foo": "path/to/foo", | 110 // "foo": "path/to/foo", |
| 123 // "bar": ["path/to/bar1", "path/to/bar2"], | 111 // "bar": ["path/to/bar1", "path/to/bar2"], |
| 124 // "myapp": "path/to/myapp", // self link is included | 112 // "myapp": "path/to/myapp", // self link is included |
| (...skipping 30 matching lines...) Expand all Loading... |
| 155 List inputFiles = obj['input_files']; | 143 List inputFiles = obj['input_files']; |
| 156 if (inputFiles != null) { | 144 if (inputFiles != null) { |
| 157 for (var path in inputFiles) { | 145 for (var path in inputFiles) { |
| 158 if (path is String) { | 146 if (path is String) { |
| 159 dependencies.add(folder.canonicalizePath(path)); | 147 dependencies.add(folder.canonicalizePath(path)); |
| 160 } | 148 } |
| 161 } | 149 } |
| 162 } | 150 } |
| 163 return new PackageMapInfo(packageMap, dependencies); | 151 return new PackageMapInfo(packageMap, dependencies); |
| 164 } | 152 } |
| 153 |
| 154 /** |
| 155 * Create a PackageMapInfo object representing an error condition. |
| 156 */ |
| 157 PackageMapInfo _error(Folder folder) { |
| 158 // Even if an error occurs, we still need to know the dependencies, so that |
| 159 // we'll know when to try running "pub list-package-dirs" again. |
| 160 // Unfortunately, "pub list-package-dirs" doesn't tell us dependencies when |
| 161 // an error occurs, so just assume there is one dependency, "pubspec.lock". |
| 162 List<String> dependencies = <String>[join(folder.path, PUBSPEC_LOCK_NAME)]; |
| 163 return new PackageMapInfo(null, dependencies.toSet()); |
| 164 } |
| 165 } | 165 } |
| OLD | NEW |