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 pub.global_packages; | 5 library pub.global_packages; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:io'; | 8 import 'dart:io'; |
9 | 9 |
10 import 'package:path/path.dart' as p; | 10 import 'package:path/path.dart' as p; |
11 import 'package:barback/barback.dart'; | 11 import 'package:barback/barback.dart'; |
12 import 'package:pub_semver/pub_semver.dart'; | 12 import 'package:pub_semver/pub_semver.dart'; |
13 | 13 |
14 import 'barback/asset_environment.dart'; | 14 import 'barback/asset_environment.dart'; |
15 import 'entrypoint.dart'; | 15 import 'entrypoint.dart'; |
16 import 'exceptions.dart'; | 16 import 'exceptions.dart'; |
17 import 'executable.dart' as exe; | 17 import 'executable.dart' as exe; |
18 import 'io.dart'; | 18 import 'io.dart'; |
19 import 'lock_file.dart'; | 19 import 'lock_file.dart'; |
20 import 'log.dart' as log; | 20 import 'log.dart' as log; |
21 import 'package.dart'; | 21 import 'package.dart'; |
22 import 'pubspec.dart'; | 22 import 'pubspec.dart'; |
23 import 'sdk.dart' as sdk; | 23 import 'sdk.dart' as sdk; |
24 import 'solver/version_solver.dart'; | 24 import 'solver/version_solver.dart'; |
25 import 'source/cached.dart'; | 25 import 'source/cached.dart'; |
26 import 'source/git.dart'; | 26 import 'source/git.dart'; |
| 27 import 'source/hosted.dart'; |
27 import 'source/path.dart'; | 28 import 'source/path.dart'; |
28 import 'system_cache.dart'; | 29 import 'system_cache.dart'; |
29 import 'utils.dart'; | 30 import 'utils.dart'; |
30 | 31 |
31 /// Maintains the set of packages that have been globally activated. | 32 /// Maintains the set of packages that have been globally activated. |
32 /// | 33 /// |
33 /// These have been hand-chosen by the user to make their executables in bin/ | 34 /// These have been hand-chosen by the user to make their executables in bin/ |
34 /// available to the entire system. This lets them access them even when the | 35 /// available to the entire system. This lets them access them even when the |
35 /// current working directory is not inside another entrypoint package. | 36 /// current working directory is not inside another entrypoint package. |
36 /// | 37 /// |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 var source = cache.sources["git"] as GitSource; | 85 var source = cache.sources["git"] as GitSource; |
85 var name = await source.getPackageNameFromRepo(repo); | 86 var name = await source.getPackageNameFromRepo(repo); |
86 // Call this just to log what the current active package is, if any. | 87 // Call this just to log what the current active package is, if any. |
87 _describeActive(name); | 88 _describeActive(name); |
88 | 89 |
89 // TODO(nweiz): Add some special handling for git repos that contain path | 90 // TODO(nweiz): Add some special handling for git repos that contain path |
90 // dependencies. Their executables shouldn't be cached, and there should | 91 // dependencies. Their executables shouldn't be cached, and there should |
91 // be a mechanism for redoing dependency resolution if a path pubspec has | 92 // be a mechanism for redoing dependency resolution if a path pubspec has |
92 // changed (see also issue 20499). | 93 // changed (see also issue 20499). |
93 await _installInCache( | 94 await _installInCache( |
94 new PackageDep(name, "git", VersionConstraint.any, repo), | 95 GitSource.refFor(name, repo).withConstraint(VersionConstraint.any), |
95 executables, overwriteBinStubs: overwriteBinStubs); | 96 executables, overwriteBinStubs: overwriteBinStubs); |
96 } | 97 } |
97 | 98 |
98 /// Finds the latest version of the hosted package with [name] that matches | 99 /// Finds the latest version of the hosted package with [name] that matches |
99 /// [constraint] and makes it the active global version. | 100 /// [constraint] and makes it the active global version. |
100 /// | 101 /// |
101 /// [executables] is the names of the executables that should have binstubs. | 102 /// [executables] is the names of the executables that should have binstubs. |
102 /// If `null`, all executables in the package will get binstubs. If empty, no | 103 /// If `null`, all executables in the package will get binstubs. If empty, no |
103 /// binstubs will be created. | 104 /// binstubs will be created. |
104 /// | 105 /// |
105 /// if [overwriteBinStubs] is `true`, any binstubs that collide with | 106 /// if [overwriteBinStubs] is `true`, any binstubs that collide with |
106 /// existing binstubs in other packages will be overwritten by this one's. | 107 /// existing binstubs in other packages will be overwritten by this one's. |
107 /// Otherwise, the previous ones will be preserved. | 108 /// Otherwise, the previous ones will be preserved. |
108 Future activateHosted(String name, VersionConstraint constraint, | 109 Future activateHosted(String name, VersionConstraint constraint, |
109 List<String> executables, {bool overwriteBinStubs}) async { | 110 List<String> executables, {bool overwriteBinStubs}) async { |
110 _describeActive(name); | 111 _describeActive(name); |
111 await _installInCache(new PackageDep(name, "hosted", constraint, name), | 112 await _installInCache(HostedSource.refFor(name).withConstraint(constraint), |
112 executables, overwriteBinStubs: overwriteBinStubs); | 113 executables, overwriteBinStubs: overwriteBinStubs); |
113 } | 114 } |
114 | 115 |
115 /// Makes the local package at [path] globally active. | 116 /// Makes the local package at [path] globally active. |
116 /// | 117 /// |
117 /// [executables] is the names of the executables that should have binstubs. | 118 /// [executables] is the names of the executables that should have binstubs. |
118 /// If `null`, all executables in the package will get binstubs. If empty, no | 119 /// If `null`, all executables in the package will get binstubs. If empty, no |
119 /// binstubs will be created. | 120 /// binstubs will be created. |
120 /// | 121 /// |
121 /// if [overwriteBinStubs] is `true`, any binstubs that collide with | 122 /// if [overwriteBinStubs] is `true`, any binstubs that collide with |
122 /// existing binstubs in other packages will be overwritten by this one's. | 123 /// existing binstubs in other packages will be overwritten by this one's. |
123 /// Otherwise, the previous ones will be preserved. | 124 /// Otherwise, the previous ones will be preserved. |
124 Future activatePath(String path, List<String> executables, | 125 Future activatePath(String path, List<String> executables, |
125 {bool overwriteBinStubs}) async { | 126 {bool overwriteBinStubs}) async { |
126 var entrypoint = new Entrypoint(path, cache, isGlobal: true); | 127 var entrypoint = new Entrypoint(path, cache, isGlobal: true); |
127 | 128 |
128 // Get the package's dependencies. | 129 // Get the package's dependencies. |
129 await entrypoint.acquireDependencies(SolveType.GET); | 130 await entrypoint.acquireDependencies(SolveType.GET); |
130 var name = entrypoint.root.name; | 131 var name = entrypoint.root.name; |
131 | 132 |
132 // Call this just to log what the current active package is, if any. | 133 // Call this just to log what the current active package is, if any. |
133 _describeActive(name); | 134 _describeActive(name); |
134 | 135 |
135 // Write a lockfile that points to the local package. | 136 // Write a lockfile that points to the local package. |
136 var fullPath = canonicalize(entrypoint.root.dir); | 137 var fullPath = canonicalize(entrypoint.root.dir); |
137 var id = new PackageId(name, "path", entrypoint.root.version, | 138 var id = PathSource.idFor(name, entrypoint.root.version, fullPath); |
138 PathSource.describePath(fullPath)); | |
139 | 139 |
140 // TODO(rnystrom): Look in "bin" and display list of binaries that | 140 // TODO(rnystrom): Look in "bin" and display list of binaries that |
141 // user can run. | 141 // user can run. |
142 _writeLockFile(name, new LockFile([id], cache.sources)); | 142 _writeLockFile(name, new LockFile([id], cache.sources)); |
143 | 143 |
144 var binDir = p.join(_directory, name, 'bin'); | 144 var binDir = p.join(_directory, name, 'bin'); |
145 if (dirExists(binDir)) deleteEntry(binDir); | 145 if (dirExists(binDir)) deleteEntry(binDir); |
146 | 146 |
147 _updateBinStubs(entrypoint.root, executables, | 147 _updateBinStubs(entrypoint.root, executables, |
148 overwriteBinStubs: overwriteBinStubs); | 148 overwriteBinStubs: overwriteBinStubs); |
(...skipping 11 matching lines...) Expand all Loading... |
160 if (!result.succeeded) { | 160 if (!result.succeeded) { |
161 // If the package specified by the user doesn't exist, we want to | 161 // If the package specified by the user doesn't exist, we want to |
162 // surface that as a [DataError] with the associated exit code. | 162 // surface that as a [DataError] with the associated exit code. |
163 if (result.error.package != dep.name) throw result.error; | 163 if (result.error.package != dep.name) throw result.error; |
164 if (result.error is NoVersionException) dataError(result.error.message); | 164 if (result.error is NoVersionException) dataError(result.error.message); |
165 throw result.error; | 165 throw result.error; |
166 } | 166 } |
167 result.showReport(SolveType.GET); | 167 result.showReport(SolveType.GET); |
168 | 168 |
169 // Make sure all of the dependencies are locally installed. | 169 // Make sure all of the dependencies are locally installed. |
170 var ids = await Future.wait(result.packages.map(_cacheDependency)); | 170 await Future.wait(result.packages.map(_cacheDependency)); |
171 var lockFile = new LockFile(ids, cache.sources); | 171 var lockFile = new LockFile(result.packages, cache.sources); |
172 | 172 |
173 // Load the package graph from [result] so we don't need to re-parse all | 173 // Load the package graph from [result] so we don't need to re-parse all |
174 // the pubspecs. | 174 // the pubspecs. |
175 var entrypoint = new Entrypoint.fromSolveResult(root, cache, result, | 175 var entrypoint = new Entrypoint.fromSolveResult(root, cache, result, |
176 isGlobal: true); | 176 isGlobal: true); |
177 var snapshots = await _precompileExecutables(entrypoint, dep.name); | 177 var snapshots = await _precompileExecutables(entrypoint, dep.name); |
178 _writeLockFile(dep.name, lockFile); | 178 _writeLockFile(dep.name, lockFile); |
179 writeTextFile(_getPackagesFilePath(dep.name), lockFile.packagesFile()); | 179 writeTextFile(_getPackagesFilePath(dep.name), lockFile.packagesFile()); |
180 | 180 |
181 _updateBinStubs(entrypoint.packageGraph.packages[dep.name], executables, | 181 _updateBinStubs(entrypoint.packageGraph.packages[dep.name], executables, |
(...skipping 17 matching lines...) Expand all Loading... |
199 useDart2JS: false); | 199 useDart2JS: false); |
200 environment.barback.errors.listen((error) { | 200 environment.barback.errors.listen((error) { |
201 log.error(log.red("Build error:\n$error")); | 201 log.error(log.red("Build error:\n$error")); |
202 }); | 202 }); |
203 | 203 |
204 return environment.precompileExecutables(package, binDir); | 204 return environment.precompileExecutables(package, binDir); |
205 }); | 205 }); |
206 } | 206 } |
207 | 207 |
208 /// Downloads [id] into the system cache if it's a cached package. | 208 /// Downloads [id] into the system cache if it's a cached package. |
209 /// | 209 Future _cacheDependency(PackageId id) async { |
210 /// Returns the resolved [PackageId] for [id]. | 210 if (id.isRoot) return; |
211 Future<PackageId> _cacheDependency(PackageId id) async { | 211 |
212 var source = cache.sources[id.source]; | 212 var source = cache.sources[id.source]; |
| 213 if (source is! CachedSource) return; |
213 | 214 |
214 if (!id.isRoot && source is CachedSource) { | 215 await source.downloadToSystemCache(id); |
215 await source.downloadToSystemCache(id); | |
216 } | |
217 | |
218 return source.resolveId(id); | |
219 } | 216 } |
220 | 217 |
221 /// Finishes activating package [package] by saving [lockFile] in the cache. | 218 /// Finishes activating package [package] by saving [lockFile] in the cache. |
222 void _writeLockFile(String package, LockFile lockFile) { | 219 void _writeLockFile(String package, LockFile lockFile) { |
223 ensureDir(p.join(_directory, package)); | 220 ensureDir(p.join(_directory, package)); |
224 | 221 |
225 // TODO(nweiz): This cleans up Dart 1.6's old lockfile location. Remove it | 222 // TODO(nweiz): This cleans up Dart 1.6's old lockfile location. Remove it |
226 // when Dart 1.6 is old enough that we don't think anyone will have these | 223 // when Dart 1.6 is old enough that we don't think anyone will have these |
227 // lockfiles anymore (issue 20703). | 224 // lockfiles anymore (issue 20703). |
228 var oldPath = p.join(_directory, "$package.lock"); | 225 var oldPath = p.join(_directory, "$package.lock"); |
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
794 } | 791 } |
795 | 792 |
796 /// Returns the value of the property named [name] in the bin stub script | 793 /// Returns the value of the property named [name] in the bin stub script |
797 /// [source]. | 794 /// [source]. |
798 String _binStubProperty(String source, String name) { | 795 String _binStubProperty(String source, String name) { |
799 var pattern = new RegExp(quoteRegExp(name) + r": ([a-zA-Z0-9_-]+)"); | 796 var pattern = new RegExp(quoteRegExp(name) + r": ([a-zA-Z0-9_-]+)"); |
800 var match = pattern.firstMatch(source); | 797 var match = pattern.firstMatch(source); |
801 return match == null ? null : match[1]; | 798 return match == null ? null : match[1]; |
802 } | 799 } |
803 } | 800 } |
OLD | NEW |