Top-level --colors flag (#3467)
diff --git a/bin/dependency_services.dart b/bin/dependency_services.dart
index 3dabf5d..f117afd 100644
--- a/bin/dependency_services.dart
+++ b/bin/dependency_services.dart
@@ -46,6 +46,7 @@
usageLineLength: lineLength) {
argParser.addFlag('verbose',
abbr: 'v', negatable: false, help: 'Shortcut for "--verbosity=all".');
+ PubTopLevel.addColorFlag(argParser);
argParser.addOption(
'directory',
abbr: 'C',
diff --git a/lib/src/command.dart b/lib/src/command.dart
index a1a8a2e..ae942ea 100644
--- a/lib/src/command.dart
+++ b/lib/src/command.dart
@@ -178,7 +178,8 @@
@override
@nonVirtual
FutureOr<int> run() async {
- computeCommand(_pubTopLevel.argResults);
+ _computeCommand(_pubTopLevel.argResults);
+ _decideOnColors(_pubTopLevel.argResults);
log.verbosity = _pubTopLevel.verbosity;
log.fine('Pub ${sdk.version}');
@@ -300,7 +301,17 @@
/// returned. For instance `install` becomes `get`.
static final String command = _command ?? '';
- static void computeCommand(ArgResults argResults) {
+ static void _decideOnColors(ArgResults argResults) {
+ if (!argResults.wasParsed('color')) {
+ forceColors = ForceColorOption.auto;
+ } else {
+ forceColors = argResults['color'] as bool
+ ? ForceColorOption.always
+ : ForceColorOption.never;
+ }
+ }
+
+ static void _computeCommand(ArgResults argResults) {
var list = <String?>[];
for (var command = argResults.command;
command != null;
@@ -329,6 +340,17 @@
bool get captureStackChains;
log.Verbosity get verbosity;
bool get trace;
+
+ static addColorFlag(ArgParser argParser) {
+ argParser.addFlag(
+ 'color',
+ help: 'Use colors in terminal output.\n'
+ 'Defaults to color when connected to a '
+ 'terminal, and no-color otherwise.',
+ );
+ }
+
+ /// The directory containing the pubspec.yaml of the project to work on.
String? get directory;
/// The argResults from the level of parsing of the 'pub' command.
diff --git a/lib/src/command/outdated.dart b/lib/src/command/outdated.dart
index 601bdc8..59131c4 100644
--- a/lib/src/command/outdated.dart
+++ b/lib/src/command/outdated.dart
@@ -47,13 +47,6 @@
OutdatedCommand() {
argParser.addFlag(
- 'color',
- help: 'Whether to color the output.\n'
- 'Defaults to color when connected to a '
- 'terminal, and no-color otherwise.',
- );
-
- argParser.addFlag(
'dependency-overrides',
defaultsTo: true,
help: 'Show resolutions with `dependency_overrides`.',
@@ -270,14 +263,8 @@
includeDevDependencies: includeDevDependencies,
);
} else {
- if (argResults.wasParsed('color')) {
- forceColors = argResults['color'];
- }
- final useColors =
- argResults.wasParsed('color') ? argResults['color'] : canUseAnsiCodes;
-
await _outputHuman(rows, mode,
- useColors: useColors,
+ useColors: canUseAnsiCodes,
showAll: showAll,
includeDevDependencies: includeDevDependencies,
lockFileExists: fileExists(entrypoint.lockFilePath),
diff --git a/lib/src/command_runner.dart b/lib/src/command_runner.dart
index 21f568b..92d4cf8 100644
--- a/lib/src/command_runner.dart
+++ b/lib/src/command_runner.dart
@@ -121,6 +121,7 @@
});
argParser.addFlag('verbose',
abbr: 'v', negatable: false, help: 'Shortcut for "--verbosity=all".');
+ PubTopLevel.addColorFlag(argParser);
argParser.addOption(
'directory',
abbr: 'C',
@@ -155,7 +156,8 @@
@override
Future<int> run(Iterable<String> args) async {
try {
- _argResults = parse(args);
+ final argResults = parse(args);
+ _argResults = argResults;
return await runCommand(argResults) ?? exit_codes.SUCCESS;
} on UsageException catch (error) {
log.exception(error);
diff --git a/lib/src/pub_embeddable_command.dart b/lib/src/pub_embeddable_command.dart
index 1c6cb48..c7c7f87 100644
--- a/lib/src/pub_embeddable_command.dart
+++ b/lib/src/pub_embeddable_command.dart
@@ -66,6 +66,7 @@
argParser.addFlag('trace', hide: true);
argParser.addFlag('verbose',
abbr: 'v', negatable: false, help: 'Print detailed logging.');
+ PubTopLevel.addColorFlag(argParser);
argParser.addOption(
'directory',
abbr: 'C',
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
index 3e1cf48..e4451db 100644
--- a/lib/src/utils.dart
+++ b/lib/src/utils.dart
@@ -389,8 +389,14 @@
String _urlDecode(String encoded) =>
Uri.decodeComponent(encoded.replaceAll('+', ' '));
-/// Set to `true` if ANSI colors should be output regardless of terminalD
-bool forceColors = false;
+enum ForceColorOption {
+ always,
+ never,
+ auto,
+}
+
+/// Change to decide if ANSI colors should be output regardless of terminalD.
+ForceColorOption forceColors = ForceColorOption.auto;
/// Whether ansi codes such as color escapes are safe to use.
///
@@ -398,8 +404,18 @@
///
/// Tests should make sure to run the subprocess with or without an attached
/// terminal to decide if colors will be provided.
-bool get canUseAnsiCodes =>
- forceColors || (stdout.hasTerminal && stdout.supportsAnsiEscapes);
+bool get canUseAnsiCodes {
+ switch (forceColors) {
+ case ForceColorOption.always:
+ return true;
+ case ForceColorOption.never:
+ return false;
+ case ForceColorOption.auto:
+ return (!Platform.environment.containsKey('NO_COLOR')) &&
+ stdout.hasTerminal &&
+ stdout.supportsAnsiEscapes;
+ }
+}
/// Gets an ANSI escape if those are supported by stdout (or nothing).
String getAnsi(String ansiCode) => canUseAnsiCodes ? ansiCode : '';
diff --git a/test/embedding/embedding_test.dart b/test/embedding/embedding_test.dart
index 676d8a1..73370d7 100644
--- a/test/embedding/embedding_test.dart
+++ b/test/embedding/embedding_test.dart
@@ -241,6 +241,23 @@
workingDirectory: d.path('.'),
);
});
+
+ testWithGolden('--color forces colors', (context) async {
+ final server = await servePackages();
+ server.serve('foo', '1.0.0');
+ server.serve('foo', '2.0.0');
+ await d.appDir({'foo': '^1.0.0'}).create();
+ await context.runEmbedding(
+ ['pub', '--no-color', 'get'],
+ environment: getPubTestEnvironment(),
+ workingDirectory: d.path(appPath),
+ );
+ await context.runEmbedding(
+ ['pub', '--color', 'get'],
+ workingDirectory: d.path(appPath),
+ environment: getPubTestEnvironment(),
+ );
+ });
}
String _filter(String input) {
diff --git a/test/testdata/goldens/embedding/embedding_test/--color forces colors.txt b/test/testdata/goldens/embedding/embedding_test/--color forces colors.txt
new file mode 100644
index 0000000..d468889
--- /dev/null
+++ b/test/testdata/goldens/embedding/embedding_test/--color forces colors.txt
@@ -0,0 +1,15 @@
+# GENERATED BY: test/embedding/embedding_test.dart
+
+$ tool/test-bin/pub_command_runner.dart pub --no-color get
+Resolving dependencies...
++ foo 1.0.0 (2.0.0 available)
+Downloading foo 1.0.0...
+Changed 1 dependency!
+
+-------------------------------- END OF OUTPUT ---------------------------------
+
+$ tool/test-bin/pub_command_runner.dart pub --color get
+Resolving dependencies...
+ [1mfoo[0m 1.0.0 [36m(2.0.0 available)[39m
+Got dependencies!
+
diff --git a/test/testdata/goldens/embedding/embedding_test/--help.txt b/test/testdata/goldens/embedding/embedding_test/--help.txt
index a7ebf2a..ea8fd3f 100644
--- a/test/testdata/goldens/embedding/embedding_test/--help.txt
+++ b/test/testdata/goldens/embedding/embedding_test/--help.txt
@@ -6,6 +6,9 @@
Usage: pub_command_runner pub [arguments...]
-h, --help Print this usage information.
-v, --verbose Print detailed logging.
+ --[no-]color Use colors in terminal output.
+ Defaults to color when connected to a terminal, and
+ no-color otherwise.
-C, --directory=<dir> Run the subcommand in the directory<dir>.
(defaults to ".")
diff --git a/test/testdata/goldens/help_test/pub outdated --help.txt b/test/testdata/goldens/help_test/pub outdated --help.txt
index 9a7b1bc..d0f6bbe 100644
--- a/test/testdata/goldens/help_test/pub outdated --help.txt
+++ b/test/testdata/goldens/help_test/pub outdated --help.txt
@@ -6,9 +6,6 @@
Usage: pub outdated [options]
-h, --help Print this usage information.
- --[no-]color Whether to color the output.
- Defaults to color when connected to a
- terminal, and no-color otherwise.
--[no-]dependency-overrides Show resolutions with `dependency_overrides`.
(defaults to on)
--[no-]dev-dependencies Take dev dependencies into account.
diff --git a/test/testdata/goldens/outdated/outdated_test/does not allow arguments - handles bad flags.txt b/test/testdata/goldens/outdated/outdated_test/does not allow arguments - handles bad flags.txt
index 6ab6163..e9ae621 100644
--- a/test/testdata/goldens/outdated/outdated_test/does not allow arguments - handles bad flags.txt
+++ b/test/testdata/goldens/outdated/outdated_test/does not allow arguments - handles bad flags.txt
@@ -6,9 +6,6 @@
[STDERR]
[STDERR] Usage: pub outdated [options]
[STDERR] -h, --help Print this usage information.
-[STDERR] --[no-]color Whether to color the output.
-[STDERR] Defaults to color when connected to a
-[STDERR] terminal, and no-color otherwise.
[STDERR] --[no-]dependency-overrides Show resolutions with `dependency_overrides`.
[STDERR] (defaults to on)
[STDERR] --[no-]dev-dependencies Take dev dependencies into account.
@@ -38,9 +35,6 @@
[STDERR]
[STDERR] Usage: pub outdated [options]
[STDERR] -h, --help Print this usage information.
-[STDERR] --[no-]color Whether to color the output.
-[STDERR] Defaults to color when connected to a
-[STDERR] terminal, and no-color otherwise.
[STDERR] --[no-]dependency-overrides Show resolutions with `dependency_overrides`.
[STDERR] (defaults to on)
[STDERR] --[no-]dev-dependencies Take dev dependencies into account.