Skip to content

Commit f224eea

Browse files
[tool] Add pigeon support to update-dependency (flutter#3640)
[tool] Add pigeon support to update-dependency
1 parent 306bac9 commit f224eea

26 files changed

+853
-547
lines changed

script/tool/lib/src/update_dependency_command.dart

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import 'dart:io' as io;
6+
57
import 'package:file/file.dart';
68
import 'package:http/http.dart' as http;
79
import 'package:pub_semver/pub_semver.dart';
@@ -10,6 +12,7 @@ import 'package:yaml_edit/yaml_edit.dart';
1012

1113
import 'common/core.dart';
1214
import 'common/package_looping_command.dart';
15+
import 'common/process_runner.dart';
1316
import 'common/pub_version_finder.dart';
1417
import 'common/repository_package.dart';
1518

@@ -26,10 +29,11 @@ class UpdateDependencyCommand extends PackageLoopingCommand {
2629
/// Creates an instance of the version check command.
2730
UpdateDependencyCommand(
2831
Directory packagesDir, {
32+
ProcessRunner processRunner = const ProcessRunner(),
2933
http.Client? httpClient,
3034
}) : _pubVersionFinder =
3135
PubVersionFinder(httpClient: httpClient ?? http.Client()),
32-
super(packagesDir) {
36+
super(packagesDir, processRunner: processRunner) {
3337
argParser.addOption(
3438
_pubPackageFlag,
3539
help: 'A pub package to update.',
@@ -129,6 +133,7 @@ ${response.httpResponse.body}
129133
return PackageResult.skip('$dependency in not a hosted dependency');
130134
}
131135

136+
// Determine the target version constraint.
132137
final String sectionKey = dependencyInfo.type == _PubDependencyType.dev
133138
? 'dev_dependencies'
134139
: 'dependencies';
@@ -147,6 +152,7 @@ ${response.httpResponse.body}
147152
versionString = '^$minVersion';
148153
}
149154

155+
// Update pubspec.yaml with the new version.
150156
print('${indentation}Updating to "$versionString"');
151157
if (versionString == dependencyInfo.constraintString) {
152158
return PackageResult.skip('Already depends on $versionString');
@@ -159,8 +165,14 @@ ${response.httpResponse.body}
159165
);
160166
package.pubspecFile.writeAsStringSync(editablePubspec.toString());
161167

162-
// TODO(stuartmorgan): Add additionally handling of known packages that
163-
// do file generation (mockito, pigeon, etc.).
168+
// Do any dependency-specific extra processing.
169+
if (dependency == 'pigeon') {
170+
if (!await _regeneratePigeonFiles(package)) {
171+
return PackageResult.fail(<String>['Failed to update pigeon files']);
172+
}
173+
}
174+
// TODO(stuartmorgan): Add additional handling of known packages that
175+
// do file generation (mockito, etc.).
164176

165177
return PackageResult.success();
166178
}
@@ -193,6 +205,59 @@ ${response.httpResponse.body}
193205
}
194206
return _PubDependencyInfo(type, pinned: false, hosted: false);
195207
}
208+
209+
/// Returns all of the files in [package] that are, according to repository
210+
/// convention, Pigeon input files.
211+
Iterable<File> _getPigeonInputFiles(RepositoryPackage package) {
212+
// Repo convention is that the Pigeon input files are the Dart files in a
213+
// top-level "pigeons" directory.
214+
final Directory pigeonsDir = package.directory.childDirectory('pigeons');
215+
if (!pigeonsDir.existsSync()) {
216+
return <File>[];
217+
}
218+
return pigeonsDir
219+
.listSync()
220+
.whereType<File>()
221+
.where((File file) => file.basename.endsWith('.dart'));
222+
}
223+
224+
/// Re-runs Pigeon generation for [package].
225+
///
226+
/// This assumes that all output configuration is set in the input files, so
227+
/// no additional arguments are needed. If that assumption stops holding true,
228+
/// the tooling will need a way for packages to control the generation (e.g.,
229+
/// with a script file with a known name in the pigeons/ directory.)
230+
Future<bool> _regeneratePigeonFiles(RepositoryPackage package) async {
231+
final Iterable<File> inputs = _getPigeonInputFiles(package);
232+
if (inputs.isEmpty) {
233+
logWarning('No pigeon input files found.');
234+
return true;
235+
}
236+
237+
print('${indentation}Running pub get...');
238+
final io.ProcessResult getResult = await processRunner
239+
.run('dart', <String>['pub', 'get'], workingDir: package.directory);
240+
if (getResult.exitCode != 0) {
241+
printError('dart pub get failed (${getResult.exitCode}):\n'
242+
'${getResult.stdout}\n${getResult.stderr}\n');
243+
return false;
244+
}
245+
246+
print('${indentation}Updating Pigeon files...');
247+
for (final File input in inputs) {
248+
final String relativePath =
249+
getRelativePosixPath(input, from: package.directory);
250+
final io.ProcessResult pigeonResult = await processRunner.run(
251+
'dart', <String>['run', 'pigeon', '--input', relativePath],
252+
workingDir: package.directory);
253+
if (pigeonResult.exitCode != 0) {
254+
printError('dart run pigeon failed (${pigeonResult.exitCode}):\n'
255+
'${pigeonResult.stdout}\n${pigeonResult.stderr}\n');
256+
return false;
257+
}
258+
}
259+
return true;
260+
}
196261
}
197262

198263
class _PubDependencyInfo {

script/tool/test/analyze_command_test.dart

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import 'dart:io' as io;
6-
75
import 'package:args/command_runner.dart';
86
import 'package:file/file.dart';
97
import 'package:file/memory.dart';
@@ -320,8 +318,8 @@ void main() {
320318
test('fails if "pub get" fails', () async {
321319
createFakePlugin('foo', packagesDir);
322320

323-
processRunner.mockProcessesForExecutable['flutter'] = <io.Process>[
324-
MockProcess(exitCode: 1) // flutter pub get
321+
processRunner.mockProcessesForExecutable['flutter'] = <FakeProcessInfo>[
322+
FakeProcessInfo(MockProcess(exitCode: 1), <String>['pub', 'get'])
325323
];
326324

327325
Error? commandError;
@@ -342,8 +340,8 @@ void main() {
342340
test('fails if "pub downgrade" fails', () async {
343341
createFakePlugin('foo', packagesDir);
344342

345-
processRunner.mockProcessesForExecutable['flutter'] = <io.Process>[
346-
MockProcess(exitCode: 1) // flutter pub downgrade
343+
processRunner.mockProcessesForExecutable['flutter'] = <FakeProcessInfo>[
344+
FakeProcessInfo(MockProcess(exitCode: 1), <String>['pub', 'downgrade'])
347345
];
348346

349347
Error? commandError;
@@ -364,8 +362,8 @@ void main() {
364362
test('fails if "analyze" fails', () async {
365363
createFakePlugin('foo', packagesDir);
366364

367-
processRunner.mockProcessesForExecutable['dart'] = <io.Process>[
368-
MockProcess(exitCode: 1) // dart analyze
365+
processRunner.mockProcessesForExecutable['dart'] = <FakeProcessInfo>[
366+
FakeProcessInfo(MockProcess(exitCode: 1), <String>['analyze'])
369367
];
370368

371369
Error? commandError;

script/tool/test/build_examples_command_test.dart

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import 'dart:io' as io;
6-
75
import 'package:args/command_runner.dart';
86
import 'package:file/file.dart';
97
import 'package:file/memory.dart';
@@ -62,8 +60,8 @@ void main() {
6260

6361
processRunner
6462
.mockProcessesForExecutable[getFlutterCommand(mockPlatform)] =
65-
<io.Process>[
66-
MockProcess(exitCode: 1) // flutter pub get
63+
<FakeProcessInfo>[
64+
FakeProcessInfo(MockProcess(exitCode: 1), <String>['build'])
6765
];
6866

6967
Error? commandError;
@@ -91,8 +89,8 @@ void main() {
9189

9290
processRunner
9391
.mockProcessesForExecutable[getFlutterCommand(mockPlatform)] =
94-
<io.Process>[
95-
MockProcess(exitCode: 1) // flutter pub get
92+
<FakeProcessInfo>[
93+
FakeProcessInfo(MockProcess(exitCode: 1), <String>['pub', 'get'])
9694
];
9795

9896
Error? commandError;

script/tool/test/common/gradle_test.dart

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import 'dart:io' as io;
6-
75
import 'package:file/file.dart';
86
import 'package:file/memory.dart';
97
import 'package:flutter_plugin_tools/src/common/gradle.dart';
@@ -176,8 +174,8 @@ void main() {
176174
);
177175

178176
processRunner.mockProcessesForExecutable[project.gradleWrapper.path] =
179-
<io.Process>[
180-
MockProcess(exitCode: 1),
177+
<FakeProcessInfo>[
178+
FakeProcessInfo(MockProcess(exitCode: 1)),
181179
];
182180

183181
final int exitCode = await project.runCommand('foo');

0 commit comments

Comments
 (0)