Unverified Commit dca6320f authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] inject output preferences at the top level (#58875)

The tool was setting the output preferences in a sub-context. Originally these were not injected before the arg parsers were created, though that was fixed by the lazy command creation. Once local engine is removed, the inner flutter_command Zone can be removed.
parent e7b4d2b8
......@@ -11,6 +11,7 @@ import 'src/base/template.dart';
// The build_runner code generation is provided here to make it easier to
// avoid introducing the dependency into google3. Not all build* packages
// are synced internally.
import 'src/base/terminal.dart';
import 'src/build_runner/build_runner.dart';
import 'src/build_runner/mustache_template.dart';
import 'src/build_runner/resident_web_runner.dart';
......@@ -135,6 +136,11 @@ Future<void> main(List<String> args) async {
stdio: globals.stdio,
terminal: globals.terminal,
outputPreferences: globals.outputPreferences,
))
)),
OutputPreferences: () => OutputPreferences.fromArguments(
args,
stdio: globals.stdio,
userMessages: globals.userMessages,
),
});
}
......@@ -8,9 +8,12 @@ import 'package:meta/meta.dart';
import '../convert.dart';
import '../globals.dart' as globals;
import 'common.dart';
import 'io.dart' as io;
import 'io.dart';
import 'logger.dart';
import 'platform.dart';
import 'user_messages.dart';
enum TerminalColor {
red,
......@@ -47,6 +50,43 @@ class OutputPreferences {
OutputPreferences.test({this.wrapText = false, int wrapColumn = kDefaultTerminalColumns, this.showColor = false})
: _overrideWrapColumn = wrapColumn;
/// Create an [OutputPreferences] from a list of command line arguments.
static OutputPreferences fromArguments(List<String> topLevelResults, {
@required UserMessages userMessages,
@required Stdio stdio,
}) {
// Don't set wrapColumns unless the user said to: if it's set, then all
// wrapping will occur at this width explicitly, and won't adapt if the
// terminal size changes during a run.
int wrapColumn;
final String rawWrapColumn = topLevelResults
.firstWhere((String line) => line.startsWith('--wrap-column='), orElse: () => null);
if (rawWrapColumn != null) {
final List<String> parts = rawWrapColumn.split('=');
if (parts.length > 1) {
wrapColumn = int.tryParse(parts[1]);
}
if (wrapColumn == null) {
throwToolExit(userMessages.runnerWrapColumnInvalid(rawWrapColumn));
}
}
// If we're not writing to a terminal with a defined width, then don't wrap
// anything, unless the user explicitly said to.
final bool useWrapping = !topLevelResults.contains('--no-wrap');
// If no default width was provided, first default to the terminal width. If
// that is null, use `kDefaultTerminalColumns`.
if (useWrapping && wrapColumn == null) {
wrapColumn = stdio.terminalColumns ?? kDefaultTerminalColumns;
}
return OutputPreferences(
wrapText: useWrapping,
showColor: !topLevelResults.contains('--no-color'),
wrapColumn: wrapColumn,
);
}
/// If [wrapText] is true, then any text sent to the context's [Logger]
/// instance (e.g. from the [printError] or [printStatus] functions) will be
/// wrapped (newlines added between words) to be no longer than the
......
......@@ -15,7 +15,6 @@ import '../artifacts.dart';
import '../base/common.dart';
import '../base/context.dart';
import '../base/file_system.dart';
import '../base/terminal.dart';
import '../base/user_messages.dart';
import '../base/utils.dart';
import '../cache.dart';
......@@ -235,32 +234,6 @@ class FlutterCommandRunner extends CommandRunner<void> {
Future<void> runCommand(ArgResults topLevelResults) async {
final Map<Type, dynamic> contextOverrides = <Type, dynamic>{};
// Don't set wrapColumns unless the user said to: if it's set, then all
// wrapping will occur at this width explicitly, and won't adapt if the
// terminal size changes during a run.
int wrapColumn;
if (topLevelResults.wasParsed('wrap-column')) {
try {
wrapColumn = int.parse(topLevelResults['wrap-column'] as String);
if (wrapColumn < 0) {
throwToolExit(userMessages.runnerWrapColumnInvalid(topLevelResults['wrap-column']));
}
} on FormatException {
throwToolExit(userMessages.runnerWrapColumnParseError(topLevelResults['wrap-column']));
}
}
// If we're not writing to a terminal with a defined width, then don't wrap
// anything, unless the user explicitly said to.
final bool useWrapping = topLevelResults.wasParsed('wrap')
? topLevelResults['wrap'] as bool
: globals.stdio.terminalColumns != null && topLevelResults['wrap'] as bool;
contextOverrides[OutputPreferences] = OutputPreferences(
wrapText: useWrapping,
showColor: topLevelResults['color'] as bool,
wrapColumn: wrapColumn,
);
if (topLevelResults['show-test-device'] as bool ||
topLevelResults['device-id'] == FlutterTesterDevices.kTesterDeviceId) {
FlutterTesterDevices.showFlutterTesterDevice = true;
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/base/user_messages.dart';
import 'package:mockito/mockito.dart';
import '../src/common.dart';
void main() {
testWithoutContext('Defaults to a wrapped terminal columns with color if no '
'args are provided', () {
final MockUserMessage userMessages = MockUserMessage();
final MockStdio stdio = MockStdio();
when(stdio.terminalColumns).thenReturn(80);
final OutputPreferences preferences = OutputPreferences.fromArguments(
<String>[],
userMessages: userMessages,
stdio: stdio,
);
expect(preferences.showColor, true);
expect(preferences.wrapText, true);
expect(preferences.wrapColumn, 80);
});
testWithoutContext('Can be configured with --no-color', () {
final MockUserMessage userMessages = MockUserMessage();
final MockStdio stdio = MockStdio();
when(stdio.terminalColumns).thenReturn(80);
final OutputPreferences preferences = OutputPreferences.fromArguments(
<String>['--no-color'],
userMessages: userMessages,
stdio: stdio,
);
expect(preferences.showColor, false);
expect(preferences.wrapText, true);
expect(preferences.wrapColumn, 80);
});
testWithoutContext('Can be configured with a specific wrap length', () {
final MockUserMessage userMessages = MockUserMessage();
final MockStdio stdio = MockStdio();
when(stdio.terminalColumns).thenReturn(80);
final OutputPreferences preferences = OutputPreferences.fromArguments(
<String>['--wrap-column=123'],
userMessages: userMessages,
stdio: stdio,
);
expect(preferences.showColor, true);
expect(preferences.wrapText, true);
expect(preferences.wrapColumn, 123);
});
testWithoutContext('Will wrap to 100 when there is no terminal columns available', () {
final MockUserMessage userMessages = MockUserMessage();
final MockStdio stdio = MockStdio();
when(stdio.terminalColumns).thenReturn(null);
final OutputPreferences preferences = OutputPreferences.fromArguments(
<String>['--wrap'],
userMessages: userMessages,
stdio: stdio,
);
expect(preferences.showColor, true);
expect(preferences.wrapText, true);
expect(preferences.wrapColumn, 100);
});
testWithoutContext('Can be configured to disable wrapping', () {
final MockUserMessage userMessages = MockUserMessage();
final MockStdio stdio = MockStdio();
when(stdio.terminalColumns).thenReturn(80);
final OutputPreferences preferences = OutputPreferences.fromArguments(
<String>['--no-wrap'],
userMessages: userMessages,
stdio: stdio,
);
expect(preferences.showColor, true);
expect(preferences.wrapText, false);
});
testWithoutContext('Throws a tool exit when an invalid wrap number is given', () {
final MockUserMessage userMessages = MockUserMessage();
final MockStdio stdio = MockStdio();
when(stdio.terminalColumns).thenReturn(80);
expect(() => OutputPreferences.fromArguments(
<String>['--wrap-column=a'],
userMessages: userMessages,
stdio: stdio,
), throwsA(isA<ToolExit>()));
});
testWithoutContext('Throws a tool exit when wrap is given without a number', () {
final MockUserMessage userMessages = MockUserMessage();
final MockStdio stdio = MockStdio();
when(stdio.terminalColumns).thenReturn(80);
expect(() => OutputPreferences.fromArguments(
<String>['--wrap-column='],
userMessages: userMessages,
stdio: stdio,
), throwsA(isA<ToolExit>()));
});
}
class MockUserMessage extends Mock implements UserMessages {}
class MockStdio extends Mock implements Stdio {}
......@@ -239,52 +239,6 @@ void main() {
Platform: () => platform,
}, initializeFlutterRoot: false);
});
group('wrapping', () {
testUsingContext('checks that output wrapping is turned on when writing to a terminal', () async {
final FakeFlutterCommand fakeCommand = FakeFlutterCommand();
runner.addCommand(fakeCommand);
await runner.run(<String>['fake']);
expect(fakeCommand.preferences.wrapText, isTrue);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
Stdio: () => FakeStdio(hasFakeTerminal: true),
}, initializeFlutterRoot: false);
testUsingContext('checks that output wrapping is turned off when not writing to a terminal', () async {
final FakeFlutterCommand fakeCommand = FakeFlutterCommand();
runner.addCommand(fakeCommand);
await runner.run(<String>['fake']);
expect(fakeCommand.preferences.wrapText, isFalse);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
Stdio: () => FakeStdio(hasFakeTerminal: false),
}, initializeFlutterRoot: false);
testUsingContext('checks that output wrapping is turned off when set on the command line and writing to a terminal', () async {
final FakeFlutterCommand fakeCommand = FakeFlutterCommand();
runner.addCommand(fakeCommand);
await runner.run(<String>['--no-wrap', 'fake']);
expect(fakeCommand.preferences.wrapText, isFalse);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
Stdio: () => FakeStdio(hasFakeTerminal: true),
}, initializeFlutterRoot: false);
testUsingContext('checks that output wrapping is turned on when set on the command line, but not writing to a terminal', () async {
final FakeFlutterCommand fakeCommand = FakeFlutterCommand();
runner.addCommand(fakeCommand);
await runner.run(<String>['--wrap', 'fake']);
expect(fakeCommand.preferences.wrapText, isTrue);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
Stdio: () => FakeStdio(hasFakeTerminal: false),
}, initializeFlutterRoot: false);
});
});
}
class MockProcessManager extends Mock implements ProcessManager {}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment