/
impl.dart
105 lines (84 loc) · 2.65 KB
/
impl.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import 'dart:convert';
import 'dart:io';
import 'package:io/ansi.dart' as ansi;
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'utils.dart';
const dartPlaceHolder = 'DART';
Future<void> expectBuildCleanImpl(
String workingDir,
List<String> command, {
String? packageRelativeDirectory,
}) async {
if (command.isEmpty) {
throw ArgumentError.value(command, 'customCommand', 'Cannot be empty');
}
final repoRoot =
await _runProc('git', ['rev-parse', '--show-toplevel'], workingDir);
final pkgDir = p.join(repoRoot, packageRelativeDirectory);
if (!p.equals(pkgDir, workingDir)) {
throw StateError(
'Expected the git root ($repoRoot) '
'to match the current directory ($workingDir).',
);
}
// 1 - get a list of modified files files - should be empty
expect(
await _changedGeneratedFiles(workingDir),
isEmpty,
reason: 'The working directory should be clean before running build.',
);
var executable = command.first;
if (executable == 'DART') {
executable = dartPath;
}
final arguments = command.skip(1).toList();
// 2 - run build - should be no output, since nothing should change
final result = await _runProc(executable, arguments, workingDir);
expectResultOutputSucceeds(result);
// 3 - get a list of modified files after the build - should still be empty
expect(await _changedGeneratedFiles(workingDir), isEmpty);
}
void expectResultOutputSucceeds(String result) {
expect(
result,
contains(RegExp(r'\[INFO\] Succeeded after .+ with \d+ outputs')),
);
}
Future<String> _changedGeneratedFiles(String workingDir) =>
_runProc('git', ['diff'], workingDir);
Future<String> _runProc(
String proc,
List<String> args,
String workingDir,
) async {
print(
'Running: `${ansi.cyan.wrap(
[proc, ...args].join(' '),
)}` in `${ansi.cyan.wrap(workingDir)}`',
);
final process = await Process.start(proc, args, workingDirectory: workingDir);
Future<void> transform(
Stream<List<int>> standardChannel,
List<String> lines,
) =>
standardChannel
.transform(const SystemEncoding().decoder)
.transform(const LineSplitter())
.forEach((element) {
print(element);
lines.add(element);
});
final stdoutContent = <String>[];
final stderrContent = <String>[];
final result = await Future.wait([
process.exitCode,
transform(process.stderr, stderrContent),
transform(process.stdout, stdoutContent),
]);
final exitCode = result.first as int;
if (exitCode != 0) {
throw ProcessException(proc, args, 'Process failed', exitCode);
}
return stdoutContent.join('\n').trim();
}