Skip to content

Commit def32ce

Browse files
authored
Revert "Revert "Use the frontend server to compile pub executables (#2968)" (#3006)" (#3008)
This reverts commit d2ad13d.
1 parent 0dc7e50 commit def32ce

File tree

6 files changed

+78
-47
lines changed

6 files changed

+78
-47
lines changed

.github/workflows/test.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,5 @@ jobs:
7070
cat "$_TESTS_FILE.${{ matrix.shard }}"
7171
shell: bash
7272
- name: Run tests
73-
run: dart test --preset travis $(cat $_TESTS_FILE.${{ matrix.shard }})
73+
run: dart test --use-data-isolate-strategy --preset travis $(cat $_TESTS_FILE.${{ matrix.shard }})
7474
shell: bash

lib/src/dart.dart

Lines changed: 51 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import 'package:analyzer/dart/analysis/session.dart';
1818
import 'package:analyzer/dart/ast/ast.dart';
1919
import 'package:analyzer/error/error.dart';
2020
import 'package:cli_util/cli_util.dart';
21+
import 'package:frontend_server_client/frontend_server_client.dart';
22+
import 'package:meta/meta.dart';
2123
import 'package:path/path.dart' as p;
2224

2325
import 'exceptions.dart';
@@ -38,41 +40,6 @@ bool isEntrypoint(CompilationUnit dart) {
3840
});
3941
}
4042

41-
/// Snapshots the Dart executable at [executablePath] to a snapshot at
42-
/// [snapshotPath].
43-
///
44-
/// If [packageConfigFile] is passed, it's used to resolve `package:` URIs in
45-
/// the executable. Otherwise, a `packages/` directory or a package spec is
46-
/// inferred from the executable's location.
47-
///
48-
/// If [name] is passed, it is used to describe the executable in logs and error
49-
/// messages.
50-
Future snapshot(
51-
String executablePath,
52-
String snapshotPath, {
53-
String packageConfigFile,
54-
String name,
55-
}) async {
56-
final args = [
57-
if (packageConfigFile != null) '--packages=$packageConfigFile',
58-
'--snapshot=$snapshotPath',
59-
p.toUri(executablePath).toString()
60-
];
61-
62-
final result = await runProcess(Platform.executable, args);
63-
final highlightedName = name = log.bold(name ?? executablePath.toString());
64-
if (result.success) {
65-
log.message('Precompiled $highlightedName.');
66-
} else {
67-
// Don't leave partial results.
68-
deleteEntry(snapshotPath);
69-
70-
throw ApplicationException(
71-
log.yellow('Failed to precompile $highlightedName:\n') +
72-
result.stderr.join('\n'));
73-
}
74-
}
75-
7643
class AnalysisContextManager {
7744
/// The map from a context root directory to to the context.
7845
final Map<String, AnalysisContext> _contexts = {};
@@ -181,3 +148,52 @@ class AnalyzerErrorGroup implements Exception {
181148
@override
182149
String toString() => errors.join('\n');
183150
}
151+
152+
/// Precompiles the Dart executable at [executablePath] to a kernel file at
153+
/// [outputPath].
154+
///
155+
/// This file is also cached at [incrementalDillOutputPath] which is used to
156+
/// initialize the compiler on future runs.
157+
///
158+
/// The [packageConfigPath] should point at the package config file to be used
159+
/// for `package:` uri resolution.
160+
///
161+
/// The [name] is used to describe the executable in logs and error messages.
162+
Future<void> precompile({
163+
@required String executablePath,
164+
@required String incrementalDillOutputPath,
165+
@required String name,
166+
@required String outputPath,
167+
@required String packageConfigPath,
168+
}) async {
169+
ensureDir(p.dirname(outputPath));
170+
ensureDir(p.dirname(incrementalDillOutputPath));
171+
const platformDill = 'lib/_internal/vm_platform_strong.dill';
172+
final sdkRoot = p.relative(p.dirname(p.dirname(Platform.resolvedExecutable)));
173+
var client = await FrontendServerClient.start(
174+
executablePath,
175+
incrementalDillOutputPath,
176+
platformDill,
177+
sdkRoot: sdkRoot,
178+
packagesJson: packageConfigPath,
179+
printIncrementalDependencies: false,
180+
);
181+
try {
182+
var result = await client.compile();
183+
184+
final highlightedName = log.bold(name);
185+
if (result?.errorCount == 0) {
186+
log.message('Precompiled $highlightedName.');
187+
await File(incrementalDillOutputPath).copy(outputPath);
188+
} else {
189+
// Don't leave partial results.
190+
deleteEntry(outputPath);
191+
192+
throw ApplicationException(
193+
log.yellow('Failed to precompile $highlightedName:\n') +
194+
(result?.compilerOutputLines?.join('\n') ?? ''));
195+
}
196+
} finally {
197+
client.kill();
198+
}
199+
}

lib/src/entrypoint.dart

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ class Entrypoint {
171171
/// The path to the directory containing dependency executable snapshots.
172172
String get _snapshotPath => p.join(cachePath, 'bin');
173173

174+
/// The path to the directory containing previous dill files for incremental
175+
/// builds.
176+
String get _incrementalDillsPath => p.join(cachePath, 'incremental');
177+
174178
/// Loads the entrypoint from a package at [rootDir].
175179
Entrypoint(String rootDir, this.cache)
176180
: root = Package.load(null, rootDir, cache.sources),
@@ -334,7 +338,7 @@ class Entrypoint {
334338
ensureDir(_snapshotPath);
335339
}
336340
return waitAndPrintErrors(executables.map((executable) {
337-
var dir = p.dirname(snapshotPathOfExecutable(executable));
341+
var dir = p.dirname(pathOfExecutable(executable));
338342
cleanDir(dir);
339343
return _precompileExecutable(executable);
340344
}));
@@ -344,16 +348,18 @@ class Entrypoint {
344348
/// Precompiles executable .dart file at [path] to a snapshot.
345349
Future<void> precompileExecutable(Executable executable) async {
346350
return await log.progress('Precompiling executable', () async {
347-
ensureDir(p.dirname(snapshotPathOfExecutable(executable)));
351+
ensureDir(p.dirname(pathOfExecutable(executable)));
348352
return waitAndPrintErrors([_precompileExecutable(executable)]);
349353
});
350354
}
351355

352356
Future<void> _precompileExecutable(Executable executable) async {
353357
final package = executable.package;
354-
await dart.snapshot(
355-
resolveExecutable(executable), snapshotPathOfExecutable(executable),
356-
packageConfigFile: packageConfigFile,
358+
await dart.precompile(
359+
executablePath: resolveExecutable(executable),
360+
outputPath: pathOfExecutable(executable),
361+
incrementalDillOutputPath: incrementalDillPathOfExecutable(executable),
362+
packageConfigPath: packageConfigFile,
357363
name:
358364
'$package:${p.basenameWithoutExtension(executable.relativePath)}');
359365
}
@@ -365,7 +371,7 @@ class Entrypoint {
365371
/// different sdk.
366372
///
367373
/// [path] must be relative.
368-
String snapshotPathOfExecutable(Executable executable) {
374+
String pathOfExecutable(Executable executable) {
369375
assert(p.isRelative(executable.relativePath));
370376
final versionSuffix = sdk.version;
371377
return isGlobal
@@ -375,6 +381,15 @@ class Entrypoint {
375381
'${p.basename(executable.relativePath)}-$versionSuffix.snapshot');
376382
}
377383

384+
String incrementalDillPathOfExecutable(Executable executable) {
385+
assert(p.isRelative(executable.relativePath));
386+
return isGlobal
387+
? p.join(_incrementalDillsPath,
388+
'${p.basename(executable.relativePath)}.incremental.dill')
389+
: p.join(_incrementalDillsPath, executable.package,
390+
'${p.basename(executable.relativePath)}.incremental.dill');
391+
}
392+
378393
/// The absolute path of [executable] resolved relative to [this].
379394
String resolveExecutable(Executable executable) {
380395
return p.join(

lib/src/executable.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ Future<int> runExecutable(
7272

7373
entrypoint.migrateCache();
7474

75-
var snapshotPath = entrypoint.snapshotPathOfExecutable(executable);
75+
var snapshotPath = entrypoint.pathOfExecutable(executable);
7676

7777
// Don't compile snapshots for mutable packages, since their code may
7878
// change later on.
@@ -327,7 +327,7 @@ Future<String> getExecutableForCommand(
327327
if (!allowSnapshot || entrypoint.packageGraph.isPackageMutable(package)) {
328328
return p.relative(path, from: root);
329329
} else {
330-
final snapshotPath = entrypoint.snapshotPathOfExecutable(executable);
330+
final snapshotPath = entrypoint.pathOfExecutable(executable);
331331
if (!fileExists(snapshotPath)) {
332332
await warningsOnlyUnlessTerminal(
333333
() => entrypoint.precompileExecutable(executable),

lib/src/global_packages.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -590,8 +590,7 @@ To recompile executables, first run `global deactivate ${dep.name}`.
590590
deleteEntry(file);
591591
_createBinStub(
592592
entrypoint.root, p.basenameWithoutExtension(file), binStubScript,
593-
overwrite: true,
594-
snapshot: entrypoint.snapshotPathOfExecutable(executable));
593+
overwrite: true, snapshot: entrypoint.pathOfExecutable(executable));
595594
}
596595
}
597596
}
@@ -641,7 +640,7 @@ To recompile executables, first run `global deactivate ${dep.name}`.
641640
executable,
642641
script,
643642
overwrite: overwriteBinStubs,
644-
snapshot: entrypoint.snapshotPathOfExecutable(
643+
snapshot: entrypoint.pathOfExecutable(
645644
exec.Executable.adaptProgramName(package.name, script),
646645
),
647646
);

pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ dependencies:
1212
cli_util: ^0.3.0
1313
collection: ^1.15.0
1414
crypto: ^3.0.1
15+
frontend_server_client: ^2.0.0
1516
http: ^0.13.3
1617
http_multi_server: ^3.0.1
1718
meta: ^1.3.0

0 commit comments

Comments
 (0)