[go: nahoru, domu]

Skip to content

Commit

Permalink
[tool] Add pigeon support to update-dependency (flutter#3640)
Browse files Browse the repository at this point in the history
[tool] Add pigeon support to update-dependency
  • Loading branch information
stuartmorgan committed Apr 5, 2023
1 parent 306bac9 commit f224eea
Show file tree
Hide file tree
Showing 26 changed files with 853 additions and 547 deletions.
71 changes: 68 additions & 3 deletions script/tool/lib/src/update_dependency_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// 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:file/file.dart';
import 'package:http/http.dart' as http;
import 'package:pub_semver/pub_semver.dart';
Expand All @@ -10,6 +12,7 @@ import 'package:yaml_edit/yaml_edit.dart';

import 'common/core.dart';
import 'common/package_looping_command.dart';
import 'common/process_runner.dart';
import 'common/pub_version_finder.dart';
import 'common/repository_package.dart';

Expand All @@ -26,10 +29,11 @@ class UpdateDependencyCommand extends PackageLoopingCommand {
/// Creates an instance of the version check command.
UpdateDependencyCommand(
Directory packagesDir, {
ProcessRunner processRunner = const ProcessRunner(),
http.Client? httpClient,
}) : _pubVersionFinder =
PubVersionFinder(httpClient: httpClient ?? http.Client()),
super(packagesDir) {
super(packagesDir, processRunner: processRunner) {
argParser.addOption(
_pubPackageFlag,
help: 'A pub package to update.',
Expand Down Expand Up @@ -129,6 +133,7 @@ ${response.httpResponse.body}
return PackageResult.skip('$dependency in not a hosted dependency');
}

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

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

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

return PackageResult.success();
}
Expand Down Expand Up @@ -193,6 +205,59 @@ ${response.httpResponse.body}
}
return _PubDependencyInfo(type, pinned: false, hosted: false);
}

/// Returns all of the files in [package] that are, according to repository
/// convention, Pigeon input files.
Iterable<File> _getPigeonInputFiles(RepositoryPackage package) {
// Repo convention is that the Pigeon input files are the Dart files in a
// top-level "pigeons" directory.
final Directory pigeonsDir = package.directory.childDirectory('pigeons');
if (!pigeonsDir.existsSync()) {
return <File>[];
}
return pigeonsDir
.listSync()
.whereType<File>()
.where((File file) => file.basename.endsWith('.dart'));
}

/// Re-runs Pigeon generation for [package].
///
/// This assumes that all output configuration is set in the input files, so
/// no additional arguments are needed. If that assumption stops holding true,
/// the tooling will need a way for packages to control the generation (e.g.,
/// with a script file with a known name in the pigeons/ directory.)
Future<bool> _regeneratePigeonFiles(RepositoryPackage package) async {
final Iterable<File> inputs = _getPigeonInputFiles(package);
if (inputs.isEmpty) {
logWarning('No pigeon input files found.');
return true;
}

print('${indentation}Running pub get...');
final io.ProcessResult getResult = await processRunner
.run('dart', <String>['pub', 'get'], workingDir: package.directory);
if (getResult.exitCode != 0) {
printError('dart pub get failed (${getResult.exitCode}):\n'
'${getResult.stdout}\n${getResult.stderr}\n');
return false;
}

print('${indentation}Updating Pigeon files...');
for (final File input in inputs) {
final String relativePath =
getRelativePosixPath(input, from: package.directory);
final io.ProcessResult pigeonResult = await processRunner.run(
'dart', <String>['run', 'pigeon', '--input', relativePath],
workingDir: package.directory);
if (pigeonResult.exitCode != 0) {
printError('dart run pigeon failed (${pigeonResult.exitCode}):\n'
'${pigeonResult.stdout}\n${pigeonResult.stderr}\n');
return false;
}
}
return true;
}
}

class _PubDependencyInfo {
Expand Down
14 changes: 6 additions & 8 deletions script/tool/test/analyze_command_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// 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:args/command_runner.dart';
import 'package:file/file.dart';
import 'package:file/memory.dart';
Expand Down Expand Up @@ -320,8 +318,8 @@ void main() {
test('fails if "pub get" fails', () async {
createFakePlugin('foo', packagesDir);

processRunner.mockProcessesForExecutable['flutter'] = <io.Process>[
MockProcess(exitCode: 1) // flutter pub get
processRunner.mockProcessesForExecutable['flutter'] = <FakeProcessInfo>[
FakeProcessInfo(MockProcess(exitCode: 1), <String>['pub', 'get'])
];

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

processRunner.mockProcessesForExecutable['flutter'] = <io.Process>[
MockProcess(exitCode: 1) // flutter pub downgrade
processRunner.mockProcessesForExecutable['flutter'] = <FakeProcessInfo>[
FakeProcessInfo(MockProcess(exitCode: 1), <String>['pub', 'downgrade'])
];

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

processRunner.mockProcessesForExecutable['dart'] = <io.Process>[
MockProcess(exitCode: 1) // dart analyze
processRunner.mockProcessesForExecutable['dart'] = <FakeProcessInfo>[
FakeProcessInfo(MockProcess(exitCode: 1), <String>['analyze'])
];

Error? commandError;
Expand Down
10 changes: 4 additions & 6 deletions script/tool/test/build_examples_command_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// 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:args/command_runner.dart';
import 'package:file/file.dart';
import 'package:file/memory.dart';
Expand Down Expand Up @@ -62,8 +60,8 @@ void main() {

processRunner
.mockProcessesForExecutable[getFlutterCommand(mockPlatform)] =
<io.Process>[
MockProcess(exitCode: 1) // flutter pub get
<FakeProcessInfo>[
FakeProcessInfo(MockProcess(exitCode: 1), <String>['build'])
];

Error? commandError;
Expand Down Expand Up @@ -91,8 +89,8 @@ void main() {

processRunner
.mockProcessesForExecutable[getFlutterCommand(mockPlatform)] =
<io.Process>[
MockProcess(exitCode: 1) // flutter pub get
<FakeProcessInfo>[
FakeProcessInfo(MockProcess(exitCode: 1), <String>['pub', 'get'])
];

Error? commandError;
Expand Down
6 changes: 2 additions & 4 deletions script/tool/test/common/gradle_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// 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:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_plugin_tools/src/common/gradle.dart';
Expand Down Expand Up @@ -176,8 +174,8 @@ void main() {
);

processRunner.mockProcessesForExecutable[project.gradleWrapper.path] =
<io.Process>[
MockProcess(exitCode: 1),
<FakeProcessInfo>[
FakeProcessInfo(MockProcess(exitCode: 1)),
];

final int exitCode = await project.runCommand('foo');
Expand Down
Loading

0 comments on commit f224eea

Please sign in to comment.