[go: nahoru, domu]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removes retries from "dart pub get" and un-buffers its stdout/stderr output #115801

Merged
merged 9 commits into from
Dec 1, 2022
Prev Previous commit
Add Pub.test() constructor which lets tests mock stdio
  • Loading branch information
nehalvpatel committed Nov 30, 2022
commit 0e8a7b159845ae0974760dbfdc2ab9e13980c2fd
1 change: 0 additions & 1 deletion packages/flutter_tools/lib/src/base/io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,6 @@ class Stdio {
}
io.Stdout? _stdout;

@visibleForTesting
io.IOSink get stderr {
if (_stderr != null) {
return _stderr!;
Expand Down
79 changes: 72 additions & 7 deletions packages/flutter_tools/lib/src/dart/pub.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'dart:async';

import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart';
import 'package:process/process.dart';

Expand Down Expand Up @@ -148,6 +149,18 @@ abstract class Pub {
required Usage usage,
}) = _DefaultPub;

/// Create a [Pub] instance with a mocked [stdio].
@visibleForTesting
factory Pub.test({
required FileSystem fileSystem,
required Logger logger,
required ProcessManager processManager,
required Platform platform,
required BotDetector botDetector,
required Usage usage,
required Stdio stdio,
}) = _DefaultPub.test;

/// Runs `pub get` or `pub upgrade` for [project].
///
/// [context] provides extra information to package server requests to
Expand Down Expand Up @@ -218,7 +231,29 @@ class _DefaultPub implements Pub {
logger: logger,
processManager: processManager,
),
_processManager = processManager;
_processManager = processManager,
_stdio = null;

@visibleForTesting
_DefaultPub.test({
required FileSystem fileSystem,
required Logger logger,
required ProcessManager processManager,
required Platform platform,
required BotDetector botDetector,
required Usage usage,
required Stdio stdio,
}) : _fileSystem = fileSystem,
_logger = logger,
_platform = platform,
_botDetector = botDetector,
_usage = usage,
_processUtils = ProcessUtils(
logger: logger,
processManager: processManager,
),
_processManager = processManager,
_stdio = stdio;

final FileSystem _fileSystem;
final Logger _logger;
Expand All @@ -227,6 +262,7 @@ class _DefaultPub implements Pub {
final BotDetector _botDetector;
final Usage _usage;
final ProcessManager _processManager;
final Stdio? _stdio;

@override
Future<void> get({
Expand Down Expand Up @@ -340,6 +376,9 @@ class _DefaultPub implements Pub {

/// Runs pub with [arguments] and [ProcessStartMode.inheritStdio] mode.
///
/// Uses [ProcessStartMode.normal] and [Pub._stdio] if [Pub.test] constructor
/// was used.
///
/// Prints the stdout and stderr of the whole run.
///
/// Sends an analytics event.
Expand All @@ -359,12 +398,38 @@ class _DefaultPub implements Pub {
final List<String> pubCommand = _pubCommand(arguments);
nehalvpatel marked this conversation as resolved.
Show resolved Hide resolved
final Map<String, String> pubEnvironment = await _createPubEnvironment(context, flutterRootOverride);
try {
final io.Process process = await _processUtils.start(
pubCommand,
workingDirectory: _fileSystem.path.current,
environment: pubEnvironment,
mode: ProcessStartMode.inheritStdio,
);
final io.Process process;
final io.Stdio? stdio = _stdio;

if (stdio != null) {
// Omit mode parameter and direct pub output to [Pub._stdio] for tests.
process = await _processUtils.start(
pubCommand,
workingDirectory: _fileSystem.path.current,
environment: pubEnvironment,
);

final StreamSubscription<List<int>> stdoutSubscription =
process.stdout.listen(stdio.stdout.add);
final StreamSubscription<List<int>> stderrSubscription =
process.stderr.listen(stdio.stderr.add);

await Future.wait<void>(<Future<void>>[
stdoutSubscription.asFuture<void>(),
stderrSubscription.asFuture<void>(),
]);

unawaited(stdoutSubscription.cancel());
unawaited(stderrSubscription.cancel());
} else {
// Let pub inherit stdio for normal operation.
process = await _processUtils.start(
pubCommand,
workingDirectory: _fileSystem.path.current,
environment: pubEnvironment,
mode: ProcessStartMode.inheritStdio,
);
}

exitCode = await process.exitCode;
// The exception is rethrown, so don't catch only Exceptions.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import 'package:process/process.dart';
import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/fake_process_manager.dart';
import '../../src/fakes.dart';
import '../../src/test_flutter_command_runner.dart';

void main() {
Expand All @@ -37,6 +38,7 @@ void main() {
late ProcessManager processManager;
late AnsiTerminal terminal;
late Logger logger;
late FakeStdio mockStdio;

setUp(() {
fileSystem = globals.localFileSystem;
Expand All @@ -45,6 +47,7 @@ void main() {
terminal = AnsiTerminal(platform: platform, stdio: Stdio());
logger = BufferLogger(outputPreferences: OutputPreferences.test(), terminal: terminal);
tempDir = fileSystem.systemTempDirectory.createTempSync('flutter_analysis_test.');
mockStdio = FakeStdio();
});

tearDown(() {
Expand Down Expand Up @@ -74,13 +77,14 @@ void main() {
testUsingContext('AnalysisServer success', () async {
createSampleProject(tempDir);

final Pub pub = Pub(
final Pub pub = Pub.test(
fileSystem: fileSystem,
logger: logger,
processManager: processManager,
platform: const LocalPlatform(),
botDetector: globals.botDetector,
usage: globals.flutterUsage,
stdio: mockStdio,
);
await pub.get(
context: PubContext.flutterTests,
Expand Down Expand Up @@ -113,13 +117,14 @@ void main() {
testUsingContext('AnalysisServer errors', () async {
createSampleProject(tempDir, brokenCode: true);

final Pub pub = Pub(
final Pub pub = Pub.test(
fileSystem: fileSystem,
logger: logger,
processManager: processManager,
platform: const LocalPlatform(),
usage: globals.flutterUsage,
botDetector: globals.botDetector,
stdio: mockStdio,
);
await pub.get(
context: PubContext.flutterTests,
Expand Down
Loading