support running et fetch from anywhere (#162712)
Support running `et fetch` from any directory.
This commit is contained in:
parent
1d85de0fc8
commit
1f5cb0d665
@ -52,7 +52,7 @@ void main() {
|
||||
Map<String, String>? dimensions,
|
||||
String? prefix,
|
||||
bool verbose = false,
|
||||
io.ProcessResult Function(List<String> command) onRun = _runUnhandled,
|
||||
io.ProcessResult Function(FakeCommandLogEntry entry) onRun = _runUnhandled,
|
||||
}) {
|
||||
return SkiaGoldClient.forTesting(
|
||||
fixture.workDirectory,
|
||||
@ -97,8 +97,8 @@ void main() {
|
||||
final SkiaGoldClient client = createClient(
|
||||
fixture,
|
||||
environment: {...presubmitEnv, 'GIT_BRANCH': 'merge-queue-foo'},
|
||||
onRun: (List<String> command) {
|
||||
expect(command, <String>[
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
expect(entry.command, <String>[
|
||||
'python tools/goldctl.py',
|
||||
'auth',
|
||||
'--work-dir',
|
||||
@ -132,8 +132,8 @@ void main() {
|
||||
final SkiaGoldClient client = createClient(
|
||||
fixture,
|
||||
environment: {...presubmitEnv, 'GIT_BRANCH': 'merge-queue-foo'},
|
||||
onRun: (List<String> command) {
|
||||
expect(command, <String>[
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
expect(entry.command, <String>[
|
||||
'python tools/goldctl.py',
|
||||
'auth',
|
||||
'--work-dir',
|
||||
@ -165,8 +165,8 @@ void main() {
|
||||
final SkiaGoldClient client = createClient(
|
||||
fixture,
|
||||
environment: presubmitEnv,
|
||||
onRun: (List<String> command) {
|
||||
expect(command, <String>[
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
expect(entry.command, <String>[
|
||||
'python tools/goldctl.py',
|
||||
'auth',
|
||||
'--work-dir',
|
||||
@ -190,9 +190,9 @@ void main() {
|
||||
final SkiaGoldClient client = createClient(
|
||||
fixture,
|
||||
environment: presubmitEnv,
|
||||
onRun: (List<String> command) {
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
callsToGoldctl++;
|
||||
expect(command, <String>[
|
||||
expect(entry.command, <String>[
|
||||
'python tools/goldctl.py',
|
||||
'auth',
|
||||
'--work-dir',
|
||||
@ -219,8 +219,8 @@ void main() {
|
||||
fixture,
|
||||
environment: presubmitEnv,
|
||||
verbose: true,
|
||||
onRun: (List<String> command) {
|
||||
expect(command, <String>[
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
expect(entry.command, <String>[
|
||||
'python tools/goldctl.py',
|
||||
'auth',
|
||||
'--verbose',
|
||||
@ -246,7 +246,7 @@ void main() {
|
||||
final SkiaGoldClient client = createClient(
|
||||
fixture,
|
||||
environment: presubmitEnv,
|
||||
onRun: (List<String> command) {
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
return io.ProcessResult(1, 0, 'stdout-text', 'stderr-text');
|
||||
},
|
||||
);
|
||||
@ -270,14 +270,14 @@ void main() {
|
||||
final SkiaGoldClient client = createClient(
|
||||
fixture,
|
||||
environment: presubmitEnv,
|
||||
onRun: (List<String> command) {
|
||||
if (command case ['git', ...]) {
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
if (entry.command case ['git', ...]) {
|
||||
return io.ProcessResult(0, 0, mockCommitHash, '');
|
||||
}
|
||||
if (command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
if (entry.command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
return io.ProcessResult(0, 0, '', '');
|
||||
}
|
||||
expect(command, <String>[
|
||||
expect(entry.command, <String>[
|
||||
'python tools/goldctl.py',
|
||||
'imgtest',
|
||||
'add',
|
||||
@ -315,14 +315,14 @@ void main() {
|
||||
fixture,
|
||||
environment: presubmitEnv,
|
||||
prefix: 'engine.',
|
||||
onRun: (List<String> command) {
|
||||
if (command case ['git', ...]) {
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
if (entry.command case ['git', ...]) {
|
||||
return io.ProcessResult(0, 0, mockCommitHash, '');
|
||||
}
|
||||
if (command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
if (entry.command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
return io.ProcessResult(0, 0, '', '');
|
||||
}
|
||||
expect(command, <String>[
|
||||
expect(entry.command, <String>[
|
||||
'python tools/goldctl.py',
|
||||
'imgtest',
|
||||
'add',
|
||||
@ -363,14 +363,14 @@ void main() {
|
||||
final SkiaGoldClient client = createClient(
|
||||
fixture,
|
||||
environment: presubmitEnv,
|
||||
onRun: (List<String> command) {
|
||||
if (command case ['git', ...]) {
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
if (entry.command case ['git', ...]) {
|
||||
return io.ProcessResult(0, 0, mockCommitHash, '');
|
||||
}
|
||||
if (command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
if (entry.command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
return io.ProcessResult(0, 0, '', '');
|
||||
}
|
||||
expect(command, <String>[
|
||||
expect(entry.command, <String>[
|
||||
'python tools/goldctl.py',
|
||||
'imgtest',
|
||||
'add',
|
||||
@ -409,14 +409,14 @@ void main() {
|
||||
fixture,
|
||||
environment: presubmitEnv,
|
||||
verbose: true,
|
||||
onRun: (List<String> command) {
|
||||
if (command case ['git', ...]) {
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
if (entry.command case ['git', ...]) {
|
||||
return io.ProcessResult(0, 0, mockCommitHash, '');
|
||||
}
|
||||
if (command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
if (entry.command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
return io.ProcessResult(0, 0, '', '');
|
||||
}
|
||||
expect(command, <String>[
|
||||
expect(entry.command, <String>[
|
||||
'python tools/goldctl.py',
|
||||
'imgtest',
|
||||
'add',
|
||||
@ -458,14 +458,14 @@ void main() {
|
||||
final SkiaGoldClient client = createClient(
|
||||
fixture,
|
||||
environment: presubmitEnv,
|
||||
onRun: (List<String> command) {
|
||||
if (command case ['git', ...]) {
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
if (entry.command case ['git', ...]) {
|
||||
return io.ProcessResult(0, 0, mockCommitHash, '');
|
||||
}
|
||||
if (command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
if (entry.command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
return io.ProcessResult(0, 0, '', '');
|
||||
}
|
||||
expect(command, <String>[
|
||||
expect(entry.command, <String>[
|
||||
'python tools/goldctl.py',
|
||||
'imgtest',
|
||||
'add',
|
||||
@ -507,11 +507,11 @@ void main() {
|
||||
final SkiaGoldClient client = createClient(
|
||||
fixture,
|
||||
environment: presubmitEnv,
|
||||
onRun: (List<String> command) {
|
||||
if (command case ['git', ...]) {
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
if (entry.command case ['git', ...]) {
|
||||
return io.ProcessResult(0, 0, mockCommitHash, '');
|
||||
}
|
||||
if (command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
if (entry.command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
return io.ProcessResult(0, 0, '', '');
|
||||
}
|
||||
return io.ProcessResult(1, 0, 'stdout-text', 'stderr-text');
|
||||
@ -541,14 +541,14 @@ void main() {
|
||||
final SkiaGoldClient client = createClient(
|
||||
fixture,
|
||||
environment: postsubmitEnv,
|
||||
onRun: (List<String> command) {
|
||||
if (command case ['git', ...]) {
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
if (entry.command case ['git', ...]) {
|
||||
return io.ProcessResult(0, 0, mockCommitHash, '');
|
||||
}
|
||||
if (command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
if (entry.command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
return io.ProcessResult(0, 0, '', '');
|
||||
}
|
||||
expect(command, <String>[
|
||||
expect(entry.command, <String>[
|
||||
'python tools/goldctl.py',
|
||||
'imgtest',
|
||||
'add',
|
||||
@ -587,14 +587,14 @@ void main() {
|
||||
fixture,
|
||||
environment: postsubmitEnv,
|
||||
verbose: true,
|
||||
onRun: (List<String> command) {
|
||||
if (command case ['git', ...]) {
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
if (entry.command case ['git', ...]) {
|
||||
return io.ProcessResult(0, 0, mockCommitHash, '');
|
||||
}
|
||||
if (command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
if (entry.command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
return io.ProcessResult(0, 0, '', '');
|
||||
}
|
||||
expect(command, <String>[
|
||||
expect(entry.command, <String>[
|
||||
'python tools/goldctl.py',
|
||||
'imgtest',
|
||||
'add',
|
||||
@ -636,11 +636,11 @@ void main() {
|
||||
final SkiaGoldClient client = createClient(
|
||||
fixture,
|
||||
environment: postsubmitEnv,
|
||||
onRun: (List<String> command) {
|
||||
if (command case ['git', ...]) {
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
if (entry.command case ['git', ...]) {
|
||||
return io.ProcessResult(0, 0, mockCommitHash, '');
|
||||
}
|
||||
if (command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
if (entry.command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
|
||||
return io.ProcessResult(0, 0, '', '');
|
||||
}
|
||||
return io.ProcessResult(1, 0, 'stdout-text', 'stderr-text');
|
||||
@ -670,8 +670,8 @@ void main() {
|
||||
final SkiaGoldClient client = createClient(
|
||||
fixture,
|
||||
environment: presubmitEnv,
|
||||
onRun: (List<String> command) {
|
||||
expect(command, <String>[
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
expect(entry.command, <String>[
|
||||
'python tools/goldctl.py',
|
||||
'imgtest',
|
||||
'get',
|
||||
@ -728,8 +728,8 @@ final class _TestFixture {
|
||||
}
|
||||
}
|
||||
|
||||
io.ProcessResult _runUnhandled(List<String> command) {
|
||||
throw UnimplementedError('Unhandled run: ${command.join(' ')}');
|
||||
io.ProcessResult _runUnhandled(FakeCommandLogEntry entry) {
|
||||
throw UnimplementedError('Unhandled run: ${entry.command.join(' ')}');
|
||||
}
|
||||
|
||||
/// An in-memory fake of [io.HttpClient] that allows [getUrl] to be mocked.
|
||||
|
@ -340,12 +340,12 @@ void main() {
|
||||
lintTarget: const LintChanged(),
|
||||
),
|
||||
processManager: FakeProcessManager(
|
||||
onStart: (List<String> command) {
|
||||
if (command.first == 'git') {
|
||||
onStart: (FakeCommandLogEntry entry) {
|
||||
if (entry.command.first == 'git') {
|
||||
// This just allows git to not actually be called.
|
||||
return FakeProcess();
|
||||
}
|
||||
return FakeProcessManager.unhandledStart(command);
|
||||
return FakeProcessManager.unhandledStart(entry);
|
||||
},
|
||||
),
|
||||
);
|
||||
@ -360,12 +360,12 @@ void main() {
|
||||
lintTarget: const LintRegex(r'.*test.*\.cc$'),
|
||||
),
|
||||
processManager: FakeProcessManager(
|
||||
onStart: (List<String> command) {
|
||||
if (command.first == 'git') {
|
||||
onStart: (FakeCommandLogEntry entry) {
|
||||
if (entry.command.first == 'git') {
|
||||
// This just allows git to not actually be called.
|
||||
return FakeProcess();
|
||||
}
|
||||
return FakeProcessManager.unhandledStart(command);
|
||||
return FakeProcessManager.unhandledStart(entry);
|
||||
},
|
||||
),
|
||||
);
|
||||
@ -377,12 +377,12 @@ void main() {
|
||||
final Fixture fixture = Fixture.fromOptions(
|
||||
Options(buildCommandsPath: io.File(buildCommands), lintTarget: const LintAll()),
|
||||
processManager: FakeProcessManager(
|
||||
onStart: (List<String> command) {
|
||||
if (command.first == 'git') {
|
||||
onStart: (FakeCommandLogEntry entry) {
|
||||
if (entry.command.first == 'git') {
|
||||
// This just allows git to not actually be called.
|
||||
return FakeProcess();
|
||||
}
|
||||
return FakeProcessManager.unhandledStart(command);
|
||||
return FakeProcessManager.unhandledStart(entry);
|
||||
},
|
||||
),
|
||||
);
|
||||
@ -622,11 +622,11 @@ void main() {
|
||||
final String firstFilePath = (await fileListFixture.tool.computeFilesOfInterest()).first.path;
|
||||
|
||||
final FakeProcessManager fakeProcessManager = FakeProcessManager(
|
||||
onStart: (List<String> command) {
|
||||
if (command.first.endsWith('clang-tidy')) {
|
||||
onStart: (FakeCommandLogEntry entry) {
|
||||
if (entry.command.first.endsWith('clang-tidy')) {
|
||||
return FakeProcess(exitCode: -io.ProcessSignal.sigsegv.signalNumber);
|
||||
}
|
||||
return FakeProcessManager.unhandledStart(command);
|
||||
return FakeProcessManager.unhandledStart(entry);
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -2,6 +2,9 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:io' as io;
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'environment.dart';
|
||||
|
||||
@ -14,3 +17,21 @@ String findDartBinDirectory(Environment env) {
|
||||
String findDartBinary(Environment env) {
|
||||
return p.join(findDartBinDirectory(env), 'dart');
|
||||
}
|
||||
|
||||
/// Returns the path to `.gclient` file, or null if it cannot be found.
|
||||
String? findDotGclient(Environment env) {
|
||||
io.Directory directory = env.engine.srcDir;
|
||||
io.File? dotGclientFile;
|
||||
while (dotGclientFile == null) {
|
||||
dotGclientFile = directory.listSync().whereType<io.File>().firstWhereOrNull((file) {
|
||||
return p.basename(file.path) == '.gclient';
|
||||
});
|
||||
|
||||
final parent = directory.parent;
|
||||
if (parent.path == directory.path) {
|
||||
break;
|
||||
}
|
||||
directory = parent;
|
||||
}
|
||||
return dotGclientFile?.path;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import 'dart:io' as io;
|
||||
|
||||
import 'package:process_runner/process_runner.dart';
|
||||
|
||||
import 'dart_utils.dart';
|
||||
import 'environment.dart';
|
||||
import 'logger.dart';
|
||||
|
||||
@ -16,8 +17,21 @@ Future<int> fetchDependencies(Environment environment) async {
|
||||
return 1;
|
||||
}
|
||||
|
||||
final dotGclientPath = findDotGclient(environment);
|
||||
|
||||
if (dotGclientPath == null) {
|
||||
environment.logger.error(
|
||||
'Failed to find the .gclient file. Make sure your local engine build '
|
||||
'environment is configured as described in '
|
||||
'https://github.com/flutter/flutter/blob/master/engine/README.md',
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
|
||||
environment.logger.status('Fetching dependencies... ', newline: environment.verbose);
|
||||
|
||||
final dotGclient = io.File(dotGclientPath);
|
||||
|
||||
Spinner? spinner;
|
||||
ProcessRunnerResult result;
|
||||
try {
|
||||
@ -30,6 +44,7 @@ Future<int> fetchDependencies(Environment environment) async {
|
||||
runInShell: true,
|
||||
startMode:
|
||||
environment.verbose ? io.ProcessStartMode.inheritStdio : io.ProcessStartMode.normal,
|
||||
workingDirectory: dotGclient.parent,
|
||||
);
|
||||
} finally {
|
||||
spinner?.finish();
|
||||
|
@ -25,8 +25,8 @@ void main() {
|
||||
|
||||
final Map<String, BuilderConfig> configs = <String, BuilderConfig>{};
|
||||
|
||||
(Environment, List<List<String>>) linuxEnv(Logger logger) {
|
||||
final List<List<String>> runHistory = <List<String>>[];
|
||||
(Environment, List<FakeCommandLogEntry>) linuxEnv(Logger logger) {
|
||||
final runHistory = <FakeCommandLogEntry>[];
|
||||
return (
|
||||
Environment(
|
||||
abi: ffi.Abi.linuxX64,
|
||||
@ -38,12 +38,12 @@ void main() {
|
||||
),
|
||||
processRunner: ProcessRunner(
|
||||
processManager: FakeProcessManager(
|
||||
onStart: (List<String> command) {
|
||||
runHistory.add(command);
|
||||
onStart: (FakeCommandLogEntry entry) {
|
||||
runHistory.add(entry);
|
||||
return FakeProcess();
|
||||
},
|
||||
onRun: (List<String> command) {
|
||||
runHistory.add(command);
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
runHistory.add(entry);
|
||||
return io.ProcessResult(81, 0, '', '');
|
||||
},
|
||||
),
|
||||
@ -56,21 +56,22 @@ void main() {
|
||||
|
||||
test('fetch command invokes gclient sync -D', () async {
|
||||
final Logger logger = Logger.test((_) {});
|
||||
final (Environment env, List<List<String>> runHistory) = linuxEnv(logger);
|
||||
final (Environment env, List<FakeCommandLogEntry> runHistory) = linuxEnv(logger);
|
||||
final ToolCommandRunner runner = ToolCommandRunner(environment: env, configs: configs);
|
||||
final int result = await runner.run(<String>['fetch']);
|
||||
expect(result, equals(0));
|
||||
expect(runHistory.length, greaterThanOrEqualTo(1));
|
||||
expect(runHistory[0], containsAllInOrder(<String>['gclient', 'sync', '-D']));
|
||||
expect(runHistory[0].command, containsAllInOrder(<String>['gclient', 'sync', '-D']));
|
||||
});
|
||||
|
||||
test('fetch command has sync alias', () async {
|
||||
final Logger logger = Logger.test((_) {});
|
||||
final (Environment env, List<List<String>> runHistory) = linuxEnv(logger);
|
||||
final (Environment env, List<FakeCommandLogEntry> runHistory) = linuxEnv(logger);
|
||||
final ToolCommandRunner runner = ToolCommandRunner(environment: env, configs: configs);
|
||||
final int result = await runner.run(<String>['sync']);
|
||||
expect(result, equals(0));
|
||||
expect(runHistory.length, greaterThanOrEqualTo(1));
|
||||
expect(runHistory[0], containsAllInOrder(<String>['gclient', 'sync', '-D']));
|
||||
expect(runHistory[0].command, containsAllInOrder(<String>['gclient', 'sync', '-D']));
|
||||
expect(runHistory[0].workingDirectory, env.engine.flutterDir.parent.parent.parent.path);
|
||||
});
|
||||
}
|
||||
|
@ -222,11 +222,11 @@ FakeProcessManager _formatProcessManager({
|
||||
return FakeProcessManager(
|
||||
canRun: canRun ?? (Object? exe, {String? workingDirectory}) => true,
|
||||
onRun:
|
||||
(List<String> cmd) => switch (cmd) {
|
||||
(FakeCommandLogEntry entry) => switch (entry.command) {
|
||||
_ => failUnknown ? io.ProcessResult(1, 1, '', '') : success,
|
||||
},
|
||||
onStart:
|
||||
(List<String> cmd) => switch (cmd) {
|
||||
(FakeCommandLogEntry entry) => switch (entry.command) {
|
||||
[final String exe, final String fmt, ...final List<String> rest]
|
||||
when exe.endsWith('dart') &&
|
||||
fmt.endsWith('ci/bin/format.dart') &&
|
||||
|
@ -30,11 +30,11 @@ void main() {
|
||||
),
|
||||
processRunner: ProcessRunner(
|
||||
processManager: FakeProcessManager(
|
||||
onStart: (command) {
|
||||
runHistory.add(command);
|
||||
onStart: (FakeCommandLogEntry entry) {
|
||||
runHistory.add(entry.command);
|
||||
return FakeProcess();
|
||||
},
|
||||
onRun: (command) {
|
||||
onRun: (_) {
|
||||
// Should not be executed.
|
||||
assert(false);
|
||||
return io.ProcessResult(81, 1, '', '');
|
||||
|
@ -153,21 +153,21 @@ void main() {
|
||||
// Be very permissive on process execution, and check usage below instead.
|
||||
final permissiveProcessManager = FakeProcessManager(
|
||||
canRun: (_, {workingDirectory}) => true,
|
||||
onRun: (command) {
|
||||
commandsRun.add(command);
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
commandsRun.add(entry.command);
|
||||
return io.ProcessResult(81, 0, '', '');
|
||||
},
|
||||
onStart: (command) {
|
||||
commandsRun.add(command);
|
||||
for (final entry in interceptCommands) {
|
||||
if (command.first.endsWith(entry.$1)) {
|
||||
final result = entry.$2(command);
|
||||
onStart: (FakeCommandLogEntry entry) {
|
||||
commandsRun.add(entry.command);
|
||||
for (final intercept in interceptCommands) {
|
||||
if (entry.command.first.endsWith(intercept.$1)) {
|
||||
final result = intercept.$2(entry.command);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (command) {
|
||||
switch (entry.command) {
|
||||
case ['flutter', 'devices', '--machine', ..._]:
|
||||
return FakeProcess(stdout: jsonEncode(attachedDevices));
|
||||
default:
|
||||
|
@ -38,9 +38,9 @@ void main() {
|
||||
),
|
||||
processRunner: ProcessRunner(
|
||||
processManager: FakeProcessManager(
|
||||
onStart: (List<String> command) {
|
||||
runHistory.add(command);
|
||||
switch (command) {
|
||||
onStart: (FakeCommandLogEntry entry) {
|
||||
runHistory.add(entry.command);
|
||||
switch (entry.command) {
|
||||
case ['success']:
|
||||
return FakeProcess(stdout: 'stdout success');
|
||||
case ['failure']:
|
||||
@ -49,7 +49,7 @@ void main() {
|
||||
return FakeProcess();
|
||||
}
|
||||
},
|
||||
onRun: (List<String> command) {
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
// Should not be executed.
|
||||
assert(false);
|
||||
return io.ProcessResult(81, 1, '', '');
|
||||
|
@ -73,18 +73,18 @@ class TestEnvironment {
|
||||
),
|
||||
processRunner: ProcessRunner(
|
||||
processManager: FakeProcessManager(
|
||||
onStart: (List<String> command) {
|
||||
final FakeProcess processResult = _getCannedResult(command, cannedProcesses);
|
||||
onStart: (FakeCommandLogEntry entry) {
|
||||
final FakeProcess processResult = _getCannedResult(entry.command, cannedProcesses);
|
||||
processResult.exitCode.then((int exitCode) {
|
||||
processHistory.add(ExecutedProcess(command, processResult, exitCode));
|
||||
processHistory.add(ExecutedProcess(entry.command, processResult, exitCode));
|
||||
});
|
||||
return processResult;
|
||||
},
|
||||
onRun: (List<String> command) {
|
||||
final io.ProcessResult result = _getCannedProcessResult(command, cannedProcesses);
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
final io.ProcessResult result = _getCannedProcessResult(entry.command, cannedProcesses);
|
||||
processHistory.add(
|
||||
ExecutedProcess(
|
||||
command,
|
||||
entry.command,
|
||||
FakeProcess(
|
||||
exitCode: result.exitCode,
|
||||
stdout: result.stdout as String,
|
||||
|
@ -76,9 +76,9 @@ void main() {
|
||||
platform: FakePlatform(operatingSystem: Platform.macOS, pathSeparator: '/'),
|
||||
processRunner: ProcessRunner(
|
||||
processManager: FakeProcessManager(
|
||||
onStart: (List<String> command) {
|
||||
runHistory.add(command);
|
||||
switch (command) {
|
||||
onStart: (FakeCommandLogEntry entry) {
|
||||
runHistory.add(entry.command);
|
||||
switch (entry.command) {
|
||||
case ['success']:
|
||||
return FakeProcess(stdout: 'stdout success');
|
||||
case ['failure']:
|
||||
@ -87,7 +87,7 @@ void main() {
|
||||
return FakeProcess();
|
||||
}
|
||||
},
|
||||
onRun: (List<String> command) {
|
||||
onRun: (FakeCommandLogEntry entry) {
|
||||
// Should not be executed.
|
||||
assert(false);
|
||||
return io.ProcessResult(81, 1, '', '');
|
||||
|
@ -827,11 +827,11 @@ FakeProcessManager _fakeProcessManager({
|
||||
return FakeProcessManager(
|
||||
canRun: canRun ?? (Object? exe, {String? workingDirectory}) => true,
|
||||
onRun:
|
||||
(List<String> cmd) => switch (cmd) {
|
||||
(FakeCommandLogEntry entry) => switch (entry.command) {
|
||||
_ => failUnknown ? io.ProcessResult(1, 1, '', '') : success,
|
||||
},
|
||||
onStart:
|
||||
(List<String> cmd) => switch (cmd) {
|
||||
(FakeCommandLogEntry entry) => switch (entry.command) {
|
||||
[final String exe, ...] when exe.endsWith('gn') => fakeProcess(gnResult),
|
||||
[final String exe, ...] when exe.endsWith('bootstrap') => fakeProcess(bootstrapResult),
|
||||
[final String exe, ...] when exe.endsWith('ninja') => fakeProcess(ninjaResult),
|
||||
|
@ -14,25 +14,25 @@ void main() {
|
||||
test('returns non-deleted files which differ from merge-base with main', () async {
|
||||
final Fixture fixture = Fixture(
|
||||
processManager: FakeProcessManager(
|
||||
onStart: (List<String> command) {
|
||||
onStart: (FakeCommandLogEntry entry) {
|
||||
// Succeed calling "git merge-base --fork-point FETCH_HEAD HEAD".
|
||||
if (command.join(' ').startsWith('git merge-base --fork-point')) {
|
||||
if (entry.command.join(' ').startsWith('git merge-base --fork-point')) {
|
||||
return FakeProcess(stdout: fakeShaHash);
|
||||
}
|
||||
|
||||
// Succeed calling "git fetch upstream main".
|
||||
if (command.join(' ') == 'git fetch upstream main') {
|
||||
if (entry.command.join(' ') == 'git fetch upstream main') {
|
||||
return FakeProcess();
|
||||
}
|
||||
|
||||
// Succeed calling "git diff --name-only --diff-filter=ACMRT fake-sha-hash".
|
||||
if (command.join(' ') ==
|
||||
if (entry.command.join(' ') ==
|
||||
'git diff --name-only --diff-filter=ACMRT --relative $fakeShaHash') {
|
||||
return FakeProcess(stdout: 'file1\nfile2');
|
||||
}
|
||||
|
||||
// Otherwise, fail.
|
||||
return FakeProcessManager.unhandledStart(command);
|
||||
return FakeProcessManager.unhandledStart(entry);
|
||||
},
|
||||
),
|
||||
);
|
||||
@ -50,26 +50,26 @@ void main() {
|
||||
test('returns non-deleted files which differ from default merge-base', () async {
|
||||
final Fixture fixture = Fixture(
|
||||
processManager: FakeProcessManager(
|
||||
onStart: (List<String> command) {
|
||||
if (command.join(' ').startsWith('git merge-base --fork-point')) {
|
||||
onStart: (FakeCommandLogEntry entry) {
|
||||
if (entry.command.join(' ').startsWith('git merge-base --fork-point')) {
|
||||
return FakeProcess(exitCode: 1);
|
||||
}
|
||||
|
||||
if (command.join(' ').startsWith('git merge-base')) {
|
||||
if (entry.command.join(' ').startsWith('git merge-base')) {
|
||||
return FakeProcess(stdout: fakeShaHash);
|
||||
}
|
||||
|
||||
if (command.join(' ') == 'git fetch upstream main') {
|
||||
if (entry.command.join(' ') == 'git fetch upstream main') {
|
||||
return FakeProcess();
|
||||
}
|
||||
|
||||
if (command.join(' ') ==
|
||||
if (entry.command.join(' ') ==
|
||||
'git diff --name-only --diff-filter=ACMRT --relative $fakeShaHash') {
|
||||
return FakeProcess(stdout: 'file1\nfile2');
|
||||
}
|
||||
|
||||
// Otherwise, fail.
|
||||
return FakeProcessManager.unhandledStart(command);
|
||||
return FakeProcessManager.unhandledStart(entry);
|
||||
},
|
||||
),
|
||||
);
|
||||
@ -87,18 +87,18 @@ void main() {
|
||||
test('returns non-deleted files which differ from HEAD', () async {
|
||||
final Fixture fixture = Fixture(
|
||||
processManager: FakeProcessManager(
|
||||
onStart: (List<String> command) {
|
||||
if (command.join(' ') == 'git fetch upstream main') {
|
||||
onStart: (FakeCommandLogEntry entry) {
|
||||
if (entry.command.join(' ') == 'git fetch upstream main') {
|
||||
return FakeProcess();
|
||||
}
|
||||
|
||||
if (command.join(' ') ==
|
||||
if (entry.command.join(' ') ==
|
||||
'git diff-tree --no-commit-id --name-only --diff-filter=ACMRT --relative -r HEAD') {
|
||||
return FakeProcess(stdout: 'file1\nfile2');
|
||||
}
|
||||
|
||||
// Otherwise, fail.
|
||||
return FakeProcessManager.unhandledStart(command);
|
||||
return FakeProcessManager.unhandledStart(entry);
|
||||
},
|
||||
),
|
||||
);
|
||||
@ -116,26 +116,26 @@ void main() {
|
||||
test('returns non-deleted files which differ from HEAD when merge-base fails', () async {
|
||||
final Fixture fixture = Fixture(
|
||||
processManager: FakeProcessManager(
|
||||
onStart: (List<String> command) {
|
||||
if (command.join(' ') == 'git fetch upstream main') {
|
||||
onStart: (FakeCommandLogEntry entry) {
|
||||
if (entry.command.join(' ') == 'git fetch upstream main') {
|
||||
return FakeProcess();
|
||||
}
|
||||
|
||||
if (command.join(' ') ==
|
||||
if (entry.command.join(' ') ==
|
||||
'git diff-tree --no-commit-id --name-only --diff-filter=ACMRT --relative -r HEAD') {
|
||||
return FakeProcess(stdout: 'file1\nfile2');
|
||||
}
|
||||
|
||||
if (command.join(' ').startsWith('git merge-base --fork-point')) {
|
||||
if (entry.command.join(' ').startsWith('git merge-base --fork-point')) {
|
||||
return FakeProcess(exitCode: 1);
|
||||
}
|
||||
|
||||
if (command.join(' ').startsWith('git merge-base')) {
|
||||
if (entry.command.join(' ').startsWith('git merge-base')) {
|
||||
return FakeProcess(stdout: fakeShaHash);
|
||||
}
|
||||
|
||||
// Otherwise, fail.
|
||||
return FakeProcessManager.unhandledStart(command);
|
||||
return FakeProcessManager.unhandledStart(entry);
|
||||
},
|
||||
),
|
||||
);
|
||||
@ -153,26 +153,26 @@ void main() {
|
||||
test('verbose output is captured', () async {
|
||||
final Fixture fixture = Fixture(
|
||||
processManager: FakeProcessManager(
|
||||
onStart: (List<String> command) {
|
||||
if (command.join(' ').startsWith('git merge-base --fork-point')) {
|
||||
onStart: (FakeCommandLogEntry entry) {
|
||||
if (entry.command.join(' ').startsWith('git merge-base --fork-point')) {
|
||||
return FakeProcess(exitCode: 1);
|
||||
}
|
||||
|
||||
if (command.join(' ').startsWith('git merge-base')) {
|
||||
if (entry.command.join(' ').startsWith('git merge-base')) {
|
||||
return FakeProcess(stdout: fakeShaHash);
|
||||
}
|
||||
|
||||
if (command.join(' ') == 'git fetch upstream main') {
|
||||
if (entry.command.join(' ') == 'git fetch upstream main') {
|
||||
return FakeProcess();
|
||||
}
|
||||
|
||||
if (command.join(' ') ==
|
||||
if (entry.command.join(' ') ==
|
||||
'git diff --name-only --diff-filter=ACMRT --relative $fakeShaHash') {
|
||||
return FakeProcess(stdout: 'file1\nfile2');
|
||||
}
|
||||
|
||||
// Otherwise, fail.
|
||||
return FakeProcessManager.unhandledStart(command);
|
||||
return FakeProcessManager.unhandledStart(entry);
|
||||
},
|
||||
),
|
||||
verbose: true,
|
||||
|
@ -14,21 +14,21 @@ final class FakeProcessManager implements ProcessManager {
|
||||
///
|
||||
/// If either is not provided, it throws an [UnsupportedError] when called.
|
||||
FakeProcessManager({
|
||||
io.ProcessResult Function(List<String> command) onRun = unhandledRun,
|
||||
io.Process Function(List<String> command) onStart = unhandledStart,
|
||||
io.ProcessResult Function(FakeCommandLogEntry entry) onRun = unhandledRun,
|
||||
io.Process Function(FakeCommandLogEntry entry) onStart = unhandledStart,
|
||||
bool Function(Object?, {String? workingDirectory}) canRun = unhandledCanRun,
|
||||
}) : _onRun = onRun,
|
||||
_onStart = onStart,
|
||||
_canRun = canRun;
|
||||
|
||||
/// A default implementation of [onRun] that throws an [UnsupportedError].
|
||||
static io.ProcessResult unhandledRun(List<String> command) {
|
||||
throw UnsupportedError('Unhandled run: ${command.join(' ')}');
|
||||
static io.ProcessResult unhandledRun(FakeCommandLogEntry entry) {
|
||||
throw UnsupportedError('Unhandled run: ${entry.command.join(' ')}');
|
||||
}
|
||||
|
||||
/// A default implementation of [onStart] that throws an [UnsupportedError].
|
||||
static io.Process unhandledStart(List<String> command) {
|
||||
throw UnsupportedError('Unhandled start: ${command.join(' ')}');
|
||||
static io.Process unhandledStart(FakeCommandLogEntry entry) {
|
||||
throw UnsupportedError('Unhandled start: ${entry.command.join(' ')}');
|
||||
}
|
||||
|
||||
/// A default implementation of [canRun] that returns `true`.
|
||||
@ -36,8 +36,8 @@ final class FakeProcessManager implements ProcessManager {
|
||||
return true;
|
||||
}
|
||||
|
||||
final io.ProcessResult Function(List<String> command) _onRun;
|
||||
final io.Process Function(List<String> command) _onStart;
|
||||
final io.ProcessResult Function(FakeCommandLogEntry entry) _onRun;
|
||||
final io.Process Function(FakeCommandLogEntry entry) _onStart;
|
||||
final bool Function(Object?, {String? workingDirectory}) _canRun;
|
||||
|
||||
@override
|
||||
@ -79,7 +79,17 @@ final class FakeProcessManager implements ProcessManager {
|
||||
Encoding stdoutEncoding = io.systemEncoding,
|
||||
Encoding stderrEncoding = io.systemEncoding,
|
||||
}) {
|
||||
return _onRun(command.map((Object o) => '$o').toList());
|
||||
return _onRun(
|
||||
FakeCommandLogEntry(
|
||||
command,
|
||||
workingDirectory: workingDirectory,
|
||||
environment: environment,
|
||||
includeParentEnvironment: includeParentEnvironment,
|
||||
runInShell: runInShell,
|
||||
stdoutEncoding: stdoutEncoding,
|
||||
stderrEncoding: stderrEncoding,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -91,10 +101,57 @@ final class FakeProcessManager implements ProcessManager {
|
||||
bool runInShell = false,
|
||||
io.ProcessStartMode mode = io.ProcessStartMode.normal,
|
||||
}) async {
|
||||
return _onStart(command.map((Object o) => '$o').toList());
|
||||
return _onStart(
|
||||
FakeCommandLogEntry(
|
||||
command,
|
||||
workingDirectory: workingDirectory,
|
||||
environment: environment,
|
||||
includeParentEnvironment: includeParentEnvironment,
|
||||
runInShell: runInShell,
|
||||
stdoutEncoding: null,
|
||||
stderrEncoding: null,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Contains information about [ProcessManager.start] and [ProcessManager.run]
|
||||
/// invocations.
|
||||
final class FakeCommandLogEntry {
|
||||
/// Creates a log entry for a single process invocation.
|
||||
FakeCommandLogEntry(
|
||||
List<Object> command, {
|
||||
required this.workingDirectory,
|
||||
required this.environment,
|
||||
required this.includeParentEnvironment,
|
||||
required this.runInShell,
|
||||
required this.stdoutEncoding,
|
||||
required this.stderrEncoding,
|
||||
}) : command = command.map((o) => '$o').toList();
|
||||
|
||||
/// The command passed to the [ProcessManager].
|
||||
final List<String> command;
|
||||
|
||||
/// The working directory passed to the [ProcessManager].
|
||||
final String? workingDirectory;
|
||||
|
||||
/// The environment variables at the time [ProcessManager] was called.
|
||||
final Map<String, String>? environment;
|
||||
|
||||
/// Whether the parent environment variables were included when spawning the
|
||||
/// child process.
|
||||
final bool includeParentEnvironment;
|
||||
|
||||
/// When the child was spawned in a shell environment.
|
||||
final bool runInShell;
|
||||
|
||||
/// The encoding used by `stdout`.
|
||||
final Encoding? stdoutEncoding;
|
||||
|
||||
/// The encoding used by `stderr`.
|
||||
final Encoding? stderrEncoding;
|
||||
}
|
||||
|
||||
/// An incomplete fake of [io.Process] that allows control for testing.
|
||||
final class FakeProcess implements io.Process {
|
||||
/// Creates a fake process that returns the given [exitCode] and out/err.
|
||||
|
Loading…
x
Reference in New Issue
Block a user