Skip to content

Commit 198d59a

Browse files
committed
Support resources in "pub run" and "pub global run".
Closes pub#22 [email protected] Review URL: https://codereview.chromium.org//1277773002 .
1 parent 1682e0b commit 198d59a

File tree

6 files changed

+322
-19
lines changed

6 files changed

+322
-19
lines changed

lib/src/command.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ library pub.command;
66

77
import 'package:args/args.dart';
88
import 'package:args/command_runner.dart';
9-
import 'package:path/path.dart' as path;
109

1110
import 'entrypoint.dart';
1211
import 'log.dart' as log;

lib/src/executable.dart

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import 'dart:io';
99

1010
import 'package:barback/barback.dart';
1111
import 'package:path/path.dart' as p;
12-
import 'package:stack_trace/stack_trace.dart';
1312

1413
import 'barback/asset_environment.dart';
1514
import 'entrypoint.dart';
@@ -114,8 +113,6 @@ Future<int> runExecutable(Entrypoint entrypoint, String package,
114113
// it knows where to load the packages. If it's a dependency's executable, for
115114
// example, it may not have the right packages directory itself.
116115
if (executableUrl.scheme == 'file' || executableUrl.scheme == '') {
117-
// TODO(nweiz): use a .packages file once sdk#23369 is fixed.
118-
119116
// We use an absolute path here not because the VM insists but because it's
120117
// helpful for the subprocess to be able to spawn Dart with
121118
// Platform.executableArguments and have that work regardless of the working
@@ -210,12 +207,22 @@ Future<Uri> _executableUrl(Entrypoint entrypoint, String package, String path,
210207
///
211208
/// This doesn't do any validation of the snapshot's SDK version.
212209
Future<int> runSnapshot(String path, Iterable<String> args, {recompile(),
213-
bool checked: false}) async {
214-
var vmArgs = [path]..addAll(args);
215-
210+
String packagesFile, bool checked: false}) async {
216211
// TODO(nweiz): pass a flag to silence the "Wrong full snapshot version"
217212
// message when issue 20784 is fixed.
218-
if (checked) vmArgs.insert(0, "--checked");
213+
var vmArgs = [];
214+
if (checked) vmArgs.add("--checked");
215+
216+
if (packagesFile != null) {
217+
// We use an absolute path here not because the VM insists but because it's
218+
// helpful for the subprocess to be able to spawn Dart with
219+
// Platform.executableArguments and have that work regardless of the working
220+
// directory.
221+
vmArgs.add("--packages=${p.toUri(p.absolute(packagesFile))}");
222+
}
223+
224+
vmArgs.add(path);
225+
vmArgs.addAll(args);
219226

220227
// We need to split stdin so that we can send the same input both to the
221228
// first and second process, if we start more than one.
@@ -269,7 +276,10 @@ void _forwardSignals(Process process) {
269276
/// Runs the executable snapshot at [snapshotPath].
270277
Future<int> _runCachedExecutable(Entrypoint entrypoint, String snapshotPath,
271278
List<String> args, {bool checked: false}) {
272-
return runSnapshot(snapshotPath, args, checked: checked, recompile: () {
279+
return runSnapshot(snapshotPath, args,
280+
packagesFile: entrypoint.packagesFile,
281+
checked: checked,
282+
recompile: () {
273283
log.fine("Precompiled executable is out of date.");
274284
return entrypoint.precompileExecutables();
275285
});

lib/src/global_packages.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
library pub.global_packages;
66

77
import 'dart:async';
8-
import 'dart:convert';
98
import 'dart:io';
109

1110
import 'package:path/path.dart' as p;
@@ -20,6 +19,7 @@ import 'io.dart';
2019
import 'lock_file.dart';
2120
import 'log.dart' as log;
2221
import 'package.dart';
22+
import 'package_locations.dart';
2323
import 'pubspec.dart';
2424
import 'sdk.dart' as sdk;
2525
import 'solver/version_solver.dart';
@@ -177,6 +177,7 @@ class GlobalPackages {
177177
.loadPackageGraph(result);
178178
var snapshots = await _precompileExecutables(graph.entrypoint, dep.name);
179179
_writeLockFile(dep.name, lockFile);
180+
writePackagesMap(graph, _getPackagesFilePath(dep.name));
180181

181182
_updateBinStubs(graph.packages[dep.name], executables,
182183
overwriteBinStubs: overwriteBinStubs, snapshots: snapshots);
@@ -354,7 +355,10 @@ class GlobalPackages {
354355
}
355356

356357
var snapshotPath = p.join(binDir, '$executable.dart.snapshot');
357-
return exe.runSnapshot(snapshotPath, args, checked: checked, recompile: () {
358+
return exe.runSnapshot(snapshotPath, args,
359+
checked: checked,
360+
packagesFile: _getPackagesFilePath(package),
361+
recompile: () {
358362
log.fine("$package:$executable is out of date and needs to be "
359363
"recompiled.");
360364
return find(package)
@@ -368,6 +372,11 @@ class GlobalPackages {
368372
String _getLockFilePath(String name) =>
369373
p.join(_directory, name, "pubspec.lock");
370374

375+
/// Gets the path to the .packages file for an activated cached package with
376+
/// [name].
377+
String _getPackagesFilePath(String name) =>
378+
p.join(_directory, name, ".packages");
379+
371380
/// Shows the user a formatted list of globally activated packages.
372381
void listActivePackages() {
373382
if (!dirExists(_directory)) return;

lib/src/package_locations.dart

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,23 @@
66
// TODO(lrn): Also move packages/ directory management to this library.
77
library pub.package_locations;
88

9-
import 'dart:async';
10-
119
import 'package:package_config/packages_file.dart' as packages_file;
1210
import 'package:path/path.dart' as p;
1311

1412
import 'package_graph.dart';
1513
import 'io.dart';
16-
import 'log.dart' as log;
1714
import 'utils.dart' show ordered;
1815

1916
/// Creates a `.packages` file with the locations of the packages in [graph].
2017
///
21-
/// The file is written in the root directory of the entrypoint of [graph].
18+
/// The file is written to [path], which defaults to the root directory of the
19+
/// entrypoint of [graph].
2220
///
2321
/// If the file already exists, it is deleted before the new content is written.
24-
void writePackagesMap(PackageGraph graph) {
25-
var packagesFilePath = graph.entrypoint.root.path(".packages");
22+
void writePackagesMap(PackageGraph graph, [String path]) {
23+
path ??= graph.entrypoint.root.path(".packages");
2624
var content = _createPackagesMap(graph);
27-
writeTextFile(packagesFilePath, content);
25+
writeTextFile(path, content);
2826
}
2927

3028
/// Template for header text put into `.packages` file.
@@ -46,7 +44,14 @@ String _createPackagesMap(PackageGraph packageGraph) {
4644
var packages = packageGraph.packages;
4745
var uriMap = {};
4846
for (var packageName in ordered(packages.keys)) {
49-
var location = packages[packageName].path("lib");
47+
var package = packages[packageName];
48+
49+
// This indicates an in-memory package, which is presumably a fake
50+
// entrypoint we created for something like "pub global activate". We don't
51+
// need to import from it anyway, so we can just not add it to the map.
52+
if (package.dir == null) continue;
53+
54+
var location = package.path("lib");
5055
uriMap[packageName] = p.toUri(location);
5156
}
5257

test/global/run/resource_test.dart

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
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+
import '../../descriptor.dart' as d;
6+
import '../../test_pub.dart';
7+
8+
main() {
9+
integration('the spawned application can load its own resource', () {
10+
servePackages((builder) {
11+
builder.serve("foo", "1.0.0", contents: [
12+
d.dir("lib", [
13+
d.file("resource.txt", "hello!")
14+
]),
15+
d.dir("bin", [
16+
d.file("script.dart", """
17+
main() async {
18+
var resource = new Resource("package:foo/resource.txt");
19+
20+
// TODO(nweiz): Enable this when sdk#23990 is fixed.
21+
// print(resource.uri);
22+
23+
print(await resource.readAsString());
24+
}
25+
""")
26+
])
27+
]);
28+
});
29+
30+
schedulePub(args: ["global", "activate", "foo"]);
31+
32+
var pub = pubRun(global: true, args: ["foo:script"]);
33+
34+
// TODO(nweiz): Enable this when sdk#23990 is fixed.
35+
// pub.stdout.expect(p.toUri(p.join(sandboxDir, "myapp/lib/resource.txt")));
36+
37+
pub.stdout.expect("hello!");
38+
pub.shouldExit(0);
39+
});
40+
41+
integration("the spawned application can load a dependency's resource", () {
42+
servePackages((builder) {
43+
builder.serve("bar", "1.0.0", contents: [
44+
d.dir("lib", [
45+
d.file("resource.txt", "hello!")
46+
])
47+
]);
48+
49+
builder.serve("foo", "1.0.0", deps: {
50+
"bar": "any"
51+
}, contents: [
52+
d.dir("bin", [
53+
d.file("script.dart", """
54+
main() async {
55+
var resource = new Resource("package:bar/resource.txt");
56+
57+
// TODO(nweiz): Enable this when sdk#23990 is fixed.
58+
// print(resource.uri);
59+
60+
print(await resource.readAsString());
61+
}
62+
""")
63+
])
64+
]);
65+
});
66+
67+
schedulePub(args: ["global", "activate", "foo"]);
68+
69+
var pub = pubRun(global: true, args: ["foo:script"]);
70+
71+
// TODO(nweiz): Enable this when sdk#23990 is fixed.
72+
// pub.stdout.expect(p.toUri(p.join(sandboxDir, "myapp/lib/resource.txt")));
73+
74+
pub.stdout.expect("hello!");
75+
pub.shouldExit(0);
76+
});
77+
78+
integration('a mutable application can load its own resource', () {
79+
d.dir("foo", [
80+
d.libPubspec("foo", "1.0.0"),
81+
d.dir("lib", [
82+
d.file("resource.txt", "hello!")
83+
]),
84+
d.dir("bin", [
85+
d.file("script.dart", """
86+
main() async {
87+
var resource = new Resource("package:foo/resource.txt");
88+
89+
// TODO(nweiz): Enable this when sdk#23990 is fixed.
90+
// print(resource.uri);
91+
92+
print(await resource.readAsString());
93+
}
94+
""")
95+
])
96+
]).create();
97+
98+
schedulePub(args: ["global", "activate", "--source", "path", "../foo"]);
99+
100+
var pub = pubRun(global: true, args: ["foo:script"]);
101+
102+
// TODO(nweiz): Enable this when sdk#23990 is fixed.
103+
// pub.stdout.expect(p.toUri(p.join(sandboxDir, "myapp/lib/resource.txt")));
104+
105+
pub.stdout.expect("hello!");
106+
pub.shouldExit(0);
107+
});
108+
}

0 commit comments

Comments
 (0)