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

Side by Side Diff: lib/src/entrypoint.dart

Issue 2250643003: Add a --[no]-packages-dir flag. (Closed) Base URL: git@github.com:dart-lang/pub.git@master
Patch Set: Created 4 years, 4 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 | « lib/src/command_runner.dart ('k') | test/no_package_symlinks_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 import 'dart:async'; 5 import 'dart:async';
6 import 'dart:io'; 6 import 'dart:io';
7 7
8 import 'package:barback/barback.dart'; 8 import 'package:barback/barback.dart';
9 import 'package:package_config/packages_file.dart' as packages_file; 9 import 'package:package_config/packages_file.dart' as packages_file;
10 import 'package:path/path.dart' as p; 10 import 'package:path/path.dart' as p;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 /// contains a reusable library may not be the entrypoint when used by an app, 64 /// contains a reusable library may not be the entrypoint when used by an app,
65 /// but may be the entrypoint when you're running its tests. 65 /// but may be the entrypoint when you're running its tests.
66 class Entrypoint { 66 class Entrypoint {
67 /// The root package this entrypoint is associated with. 67 /// The root package this entrypoint is associated with.
68 final Package root; 68 final Package root;
69 69
70 /// The system-wide cache which caches packages that need to be fetched over 70 /// The system-wide cache which caches packages that need to be fetched over
71 /// the network. 71 /// the network.
72 final SystemCache cache; 72 final SystemCache cache;
73 73
74 /// Whether to create and symlink a "packages" directory containing links to
75 /// the installed packages.
76 final bool _packageSymlinks;
77
78 /// Whether this entrypoint is in memory only, as opposed to representing a 74 /// Whether this entrypoint is in memory only, as opposed to representing a
79 /// real directory on disk. 75 /// real directory on disk.
80 final bool _inMemory; 76 final bool _inMemory;
81 77
82 /// Whether this is an entrypoint for a globally-activated package. 78 /// Whether this is an entrypoint for a globally-activated package.
83 final bool isGlobal; 79 final bool isGlobal;
84 80
85 /// The lockfile for the entrypoint. 81 /// The lockfile for the entrypoint.
86 /// 82 ///
87 /// If not provided to the entrypoint, it will be loaded lazily from disk. 83 /// If not provided to the entrypoint, it will be loaded lazily from disk.
(...skipping 24 matching lines...) Expand all
112 key: (id) => id.name, 108 key: (id) => id.name,
113 value: (id) => cache.load(id)); 109 value: (id) => cache.load(id));
114 packages[root.name] = root; 110 packages[root.name] = root;
115 111
116 _packageGraph = new PackageGraph(this, lockFile, packages); 112 _packageGraph = new PackageGraph(this, lockFile, packages);
117 return _packageGraph; 113 return _packageGraph;
118 } 114 }
119 PackageGraph _packageGraph; 115 PackageGraph _packageGraph;
120 116
121 /// The path to the entrypoint's "packages" directory. 117 /// The path to the entrypoint's "packages" directory.
122 String get packagesDir => root.path('packages'); 118 String get packagesPath => root.path('packages');
123 119
124 /// The path to the entrypoint's ".packages" file. 120 /// The path to the entrypoint's ".packages" file.
125 String get packagesFile => root.path('.packages'); 121 String get packagesFile => root.path('.packages');
126 122
127 /// The path to the entrypoint package's pubspec. 123 /// The path to the entrypoint package's pubspec.
128 String get pubspecPath => root.path('pubspec.yaml'); 124 String get pubspecPath => root.path('pubspec.yaml');
129 125
130 /// The path to the entrypoint package's lockfile. 126 /// The path to the entrypoint package's lockfile.
131 String get lockFilePath => root.path('pubspec.lock'); 127 String get lockFilePath => root.path('pubspec.lock');
132 128
133 /// The path to the directory containing precompiled dependencies. 129 /// The path to the directory containing precompiled dependencies.
134 /// 130 ///
135 /// We just precompile the debug version of a package. We're mostly interested 131 /// We just precompile the debug version of a package. We're mostly interested
136 /// in improving speed for development iteration loops, which usually use 132 /// in improving speed for development iteration loops, which usually use
137 /// debug mode. 133 /// debug mode.
138 String get _precompiledDepsPath => root.path('.pub', 'deps', 'debug'); 134 String get _precompiledDepsPath => root.path('.pub', 'deps', 'debug');
139 135
140 /// The path to the directory containing dependency executable snapshots. 136 /// The path to the directory containing dependency executable snapshots.
141 String get _snapshotPath => root.path('.pub', 'bin'); 137 String get _snapshotPath => root.path('.pub', 'bin');
142 138
143 /// Loads the entrypoint from a package at [rootDir]. 139 /// Loads the entrypoint from a package at [rootDir].
144 /// 140 Entrypoint(String rootDir, SystemCache cache, {this.isGlobal: false})
145 /// If [packageSymlinks] is `true`, this will create a "packages" directory
146 /// with symlinks to the installed packages. This directory will be symlinked
147 /// into any directory that might contain an entrypoint.
148 Entrypoint(String rootDir, SystemCache cache, {bool packageSymlinks: true,
149 this.isGlobal: false})
150 : root = new Package.load(null, rootDir, cache.sources), 141 : root = new Package.load(null, rootDir, cache.sources),
151 cache = cache, 142 cache = cache,
152 _packageSymlinks = packageSymlinks,
153 _inMemory = false; 143 _inMemory = false;
154 144
155 /// Creates an entrypoint given package and lockfile objects. 145 /// Creates an entrypoint given package and lockfile objects.
156 Entrypoint.inMemory(this.root, this._lockFile, this.cache, 146 Entrypoint.inMemory(this.root, this._lockFile, this.cache,
157 {this.isGlobal: false}) 147 {this.isGlobal: false})
158 : _packageSymlinks = false, 148 : _inMemory = true;
159 _inMemory = true;
160 149
161 /// Creates an entrypoint given a package and a [solveResult], from which the 150 /// Creates an entrypoint given a package and a [solveResult], from which the
162 /// package graph and lockfile will be computed. 151 /// package graph and lockfile will be computed.
163 Entrypoint.fromSolveResult(this.root, this.cache, SolveResult solveResult, 152 Entrypoint.fromSolveResult(this.root, this.cache, SolveResult solveResult,
164 {this.isGlobal: false}) 153 {this.isGlobal: false})
165 : _packageSymlinks = false, 154 : _inMemory = true {
166 _inMemory = true {
167 _packageGraph = new PackageGraph.fromSolveResult(this, solveResult); 155 _packageGraph = new PackageGraph.fromSolveResult(this, solveResult);
168 _lockFile = _packageGraph.lockFile; 156 _lockFile = _packageGraph.lockFile;
169 } 157 }
170 158
171 /// Gets all dependencies of the [root] package. 159 /// Gets all dependencies of the [root] package.
172 /// 160 ///
173 /// Performs version resolution according to [SolveType]. 161 /// Performs version resolution according to [SolveType].
174 /// 162 ///
175 /// [useLatest], if provided, defines a list of packages that will be 163 /// [useLatest], if provided, defines a list of packages that will be
176 /// unlocked and forced to their latest versions. If [upgradeAll] is 164 /// unlocked and forced to their latest versions. If [upgradeAll] is
177 /// true, the previous lockfile is ignored and all packages are re-resolved 165 /// true, the previous lockfile is ignored and all packages are re-resolved
178 /// from scratch. Otherwise, it will attempt to preserve the versions of all 166 /// from scratch. Otherwise, it will attempt to preserve the versions of all
179 /// previously locked packages. 167 /// previously locked packages.
180 /// 168 ///
181 /// Shows a report of the changes made relative to the previous lockfile. If 169 /// Shows a report of the changes made relative to the previous lockfile. If
182 /// this is an upgrade or downgrade, all transitive dependencies are shown in 170 /// this is an upgrade or downgrade, all transitive dependencies are shown in
183 /// the report. Otherwise, only dependencies that were changed are shown. If 171 /// the report. Otherwise, only dependencies that were changed are shown. If
184 /// [dryRun] is `true`, no physical changes are made. 172 /// [dryRun] is `true`, no physical changes are made.
185 /// 173 ///
186 /// If [precompile] is `true` (the default), this snapshots dependencies' 174 /// If [precompile] is `true` (the default), this snapshots dependencies'
187 /// executables and runs transformers on transformed dependencies. 175 /// executables and runs transformers on transformed dependencies.
188 /// 176 ///
177 /// If [packagesDir] is `true`, this will create "packages" directory with
178 /// symlinks to the installed packages. This directory will be symlinked into
179 /// any directory that might contain an entrypoint.
180 ///
189 /// Updates [lockFile] and [packageRoot] accordingly. 181 /// Updates [lockFile] and [packageRoot] accordingly.
190 Future acquireDependencies(SolveType type, {List<String> useLatest, 182 Future acquireDependencies(SolveType type, {List<String> useLatest,
191 bool dryRun: false, bool precompile: true}) async { 183 bool dryRun: false, bool precompile: true, bool packagesDir: false})
Bob Nystrom 2016/08/16 22:19:43 The name "packagesDir" reads like it *is* the pack
nweiz 2016/08/16 22:27:57 I generally prefer short names to totally unambigu
184 async {
192 var result = await resolveVersions(type, cache, root, 185 var result = await resolveVersions(type, cache, root,
193 lockFile: lockFile, useLatest: useLatest); 186 lockFile: lockFile, useLatest: useLatest);
194 if (!result.succeeded) throw result.error; 187 if (!result.succeeded) throw result.error;
195 188
196 result.showReport(type); 189 result.showReport(type);
197 190
198 if (dryRun) { 191 if (dryRun) {
199 result.summarizeChanges(type, dryRun: dryRun); 192 result.summarizeChanges(type, dryRun: dryRun);
200 return; 193 return;
201 } 194 }
202 195
203 // Install the packages and maybe link them into the entrypoint. 196 // Install the packages and maybe link them into the entrypoint.
204 if (_packageSymlinks) { 197 if (packagesDir) {
205 cleanDir(packagesDir); 198 cleanDir(packagesPath);
206 } else { 199 } else {
207 deleteEntry(packagesDir); 200 deleteEntry(packagesPath);
208 } 201 }
209 202
210 await Future.wait(result.packages.map(_get)); 203 await Future.wait(result.packages
204 .map((id) => _get(id, packagesDir: packagesDir)));
211 _saveLockFile(result); 205 _saveLockFile(result);
212 206
213 if (_packageSymlinks) _linkSelf(); 207 if (packagesDir) _linkSelf();
214 _linkOrDeleteSecondaryPackageDirs(); 208 _linkOrDeleteSecondaryPackageDirs(packagesDir: packagesDir);
215 209
216 result.summarizeChanges(type, dryRun: dryRun); 210 result.summarizeChanges(type, dryRun: dryRun);
217 211
218 /// Build a package graph from the version solver results so we don't 212 /// Build a package graph from the version solver results so we don't
219 /// have to reload and reparse all the pubspecs. 213 /// have to reload and reparse all the pubspecs.
220 _packageGraph = new PackageGraph.fromSolveResult(this, result); 214 _packageGraph = new PackageGraph.fromSolveResult(this, result);
221 packageGraph.loadTransformerCache().clearIfOutdated(result.changedPackages); 215 packageGraph.loadTransformerCache().clearIfOutdated(result.changedPackages);
222 216
223 try { 217 try {
224 if (precompile) { 218 if (precompile) {
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 436
443 // Otherwise, we don't need to recompile. 437 // Otherwise, we don't need to recompile.
444 return []; 438 return [];
445 } 439 }
446 440
447 /// Makes sure the package at [id] is locally available. 441 /// Makes sure the package at [id] is locally available.
448 /// 442 ///
449 /// This automatically downloads the package to the system-wide cache as well 443 /// This automatically downloads the package to the system-wide cache as well
450 /// if it requires network access to retrieve (specifically, if the package's 444 /// if it requires network access to retrieve (specifically, if the package's
451 /// source is a [CachedSource]). 445 /// source is a [CachedSource]).
452 Future _get(PackageId id) async { 446 Future _get(PackageId id, {bool packagesDir: false}) async {
453 if (id.isRoot) return; 447 if (id.isRoot) return;
454 448
455 var source = cache.source(id.source); 449 var source = cache.source(id.source);
456 if (!_packageSymlinks) { 450 if (!packagesDir) {
457 if (source is CachedSource) await source.downloadToSystemCache(id); 451 if (source is CachedSource) await source.downloadToSystemCache(id);
458 return; 452 return;
459 } 453 }
460 454
461 var packageDir = p.join(packagesDir, id.name); 455 var packagePath = p.join(packagesPath, id.name);
462 if (entryExists(packageDir)) deleteEntry(packageDir); 456 if (entryExists(packagePath)) deleteEntry(packagePath);
463 await source.get(id, packageDir); 457 await source.get(id, packagePath);
464 } 458 }
465 459
466 /// Throws a [DataError] if the `.packages` file doesn't exist or if it's 460 /// Throws a [DataError] if the `.packages` file doesn't exist or if it's
467 /// out-of-date relative to the lockfile or the pubspec. 461 /// out-of-date relative to the lockfile or the pubspec.
468 void assertUpToDate() { 462 void assertUpToDate() {
469 if (_inMemory) return; 463 if (_inMemory) return;
470 464
471 if (!entryExists(lockFilePath)) { 465 if (!entryExists(lockFilePath)) {
472 dataError('No pubspec.lock file found, please run "pub get" first.'); 466 dataError('No pubspec.lock file found, please run "pub get" first.');
473 } 467 }
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 /// Saves a list of concrete package versions to the `pubspec.lock` file. 641 /// Saves a list of concrete package versions to the `pubspec.lock` file.
648 void _saveLockFile(SolveResult result) { 642 void _saveLockFile(SolveResult result) {
649 _lockFile = result.lockFile; 643 _lockFile = result.lockFile;
650 var lockFilePath = root.path('pubspec.lock'); 644 var lockFilePath = root.path('pubspec.lock');
651 writeTextFile(lockFilePath, _lockFile.serialize(root.dir)); 645 writeTextFile(lockFilePath, _lockFile.serialize(root.dir));
652 } 646 }
653 647
654 /// Creates a self-referential symlink in the `packages` directory that allows 648 /// Creates a self-referential symlink in the `packages` directory that allows
655 /// a package to import its own files using `package:`. 649 /// a package to import its own files using `package:`.
656 void _linkSelf() { 650 void _linkSelf() {
657 var linkPath = p.join(packagesDir, root.name); 651 var linkPath = p.join(packagesPath, root.name);
658 // Create the symlink if it doesn't exist. 652 // Create the symlink if it doesn't exist.
659 if (entryExists(linkPath)) return; 653 if (entryExists(linkPath)) return;
660 ensureDir(packagesDir); 654 ensureDir(packagesPath);
661 createPackageSymlink(root.name, root.dir, linkPath, 655 createPackageSymlink(root.name, root.dir, linkPath,
662 isSelfLink: true, relative: true); 656 isSelfLink: true, relative: true);
663 } 657 }
664 658
665 /// If [packageSymlinks] is true, add "packages" directories to the whitelist 659 /// If [packagesDir] is true, add "packages" directories to the whitelist of
666 /// of directories that may contain Dart entrypoints. 660 /// directories that may contain Dart entrypoints.
667 /// 661 ///
668 /// Otherwise, delete any "packages" directories in the whitelist of 662 /// Otherwise, delete any "packages" directories in the whitelist of
669 /// directories that may contain Dart entrypoints. 663 /// directories that may contain Dart entrypoints.
670 void _linkOrDeleteSecondaryPackageDirs() { 664 void _linkOrDeleteSecondaryPackageDirs({bool packagesDir: false}) {
671 // Only the main "bin" directory gets a "packages" directory, not its 665 // Only the main "bin" directory gets a "packages" directory, not its
672 // subdirectories. 666 // subdirectories.
673 var binDir = root.path('bin'); 667 var binDir = root.path('bin');
674 if (dirExists(binDir)) _linkOrDeleteSecondaryPackageDir(binDir); 668 if (dirExists(binDir)) {
669 _linkOrDeleteSecondaryPackageDir(binDir, packagesDir: packagesDir);
670 }
675 671
676 // The others get "packages" directories in subdirectories too. 672 // The others get "packages" directories in subdirectories too.
677 for (var dir in ['benchmark', 'example', 'test', 'tool', 'web']) { 673 for (var dir in ['benchmark', 'example', 'test', 'tool', 'web']) {
678 _linkOrDeleteSecondaryPackageDirsRecursively(root.path(dir)); 674 _linkOrDeleteSecondaryPackageDirsRecursively(root.path(dir),
675 packagesDir: packagesDir);
679 } 676 }
680 } 677 }
681 678
682 /// If [packageSymlinks] is true, creates a symlink to the "packages" 679 /// If [packagesDir] is true, creates a symlink to the "packages" directory in
683 /// directory in [dir] and all its subdirectories. 680 /// [dir] and all its subdirectories.
684 /// 681 ///
685 /// Otherwise, deletes any "packages" directories in [dir] and all its 682 /// Otherwise, deletes any "packages" directories in [dir] and all its
686 /// subdirectories. 683 /// subdirectories.
687 void _linkOrDeleteSecondaryPackageDirsRecursively(String dir) { 684 void _linkOrDeleteSecondaryPackageDirsRecursively(String dir,
685 {bool packagesDir: false}) {
688 if (!dirExists(dir)) return; 686 if (!dirExists(dir)) return;
689 _linkOrDeleteSecondaryPackageDir(dir); 687 _linkOrDeleteSecondaryPackageDir(dir, packagesDir: packagesDir);
690 _listDirWithoutPackages(dir) 688 for (var subdir in _listDirWithoutPackages(dir)) {
691 .where(dirExists) 689 if (!dirExists(subdir)) continue;
692 .forEach(_linkOrDeleteSecondaryPackageDir); 690 _linkOrDeleteSecondaryPackageDir(subdir, packagesDir: packagesDir);
691 }
693 } 692 }
694 693
695 // TODO(nweiz): roll this into [listDir] in io.dart once issue 4775 is fixed. 694 // TODO(nweiz): roll this into [listDir] in io.dart once issue 4775 is fixed.
696 /// Recursively lists the contents of [dir], excluding hidden `.DS_Store` 695 /// Recursively lists the contents of [dir], excluding hidden `.DS_Store`
697 /// files and `package` files. 696 /// files and `package` files.
698 List<String> _listDirWithoutPackages(dir) { 697 List<String> _listDirWithoutPackages(dir) {
699 return listDir(dir).expand/*<String>*/((file) { 698 return listDir(dir).expand/*<String>*/((file) {
700 if (p.basename(file) == 'packages') return []; 699 if (p.basename(file) == 'packages') return [];
701 if (!dirExists(file)) return []; 700 if (!dirExists(file)) return [];
702 var fileAndSubfiles = [file]; 701 var fileAndSubfiles = [file];
703 fileAndSubfiles.addAll(_listDirWithoutPackages(file)); 702 fileAndSubfiles.addAll(_listDirWithoutPackages(file));
704 return fileAndSubfiles; 703 return fileAndSubfiles;
705 }); 704 });
706 } 705 }
707 706
708 /// If [packageSymlinks] is true, creates a symlink to the "packages" 707 /// If [packagesDir] is true, creates a symlink to the "packages" directory in
709 /// directory in [dir]. 708 /// [dir].
710 /// 709 ///
711 /// Otherwise, deletes a "packages" directories in [dir] if one exists. 710 /// Otherwise, deletes a "packages" directories in [dir] if one exists.
712 void _linkOrDeleteSecondaryPackageDir(String dir) { 711 void _linkOrDeleteSecondaryPackageDir(String dir, {bool packagesDir: false}) {
713 var symlink = p.join(dir, 'packages'); 712 var symlink = p.join(dir, 'packages');
714 if (entryExists(symlink)) deleteEntry(symlink); 713 if (entryExists(symlink)) deleteEntry(symlink);
715 if (_packageSymlinks) createSymlink(packagesDir, symlink, relative: true); 714 if (packagesDir) createSymlink(packagesPath, symlink, relative: true);
716 } 715 }
717 } 716 }
OLDNEW
« no previous file with comments | « lib/src/command_runner.dart ('k') | test/no_package_symlinks_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698