Skip to content

Commit 058e118

Browse files
committed
feat: simplify color system - remove automatic detection
Remove complex color detection heuristics in favor of simple boolean control. This gives users complete control over when colors are used. Changes: - Remove NO_COLOR environment variable detection - Remove TTY detection and automatic color logic - Colors now only work when color: true is explicitly set - Update documentation to reflect simplified behavior - Update tests to match new behavior - Update examples to show simple boolean control Benefits: - Predictable behavior - no environment surprises - Simpler API - just a boolean flag - User control - users can implement their own detection wrapper - Lighter weight - less environment dependencies Breaking change: - Previously colors might auto-enable based on TTY/environment - Now colors only work when explicitly enabled with color: true - Users who want automatic detection should wrap their CLI logic
1 parent c7a4b12 commit 058e118

5 files changed

Lines changed: 42 additions & 88 deletions

File tree

README.md

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,7 @@ properties.
334334
- `name?: string` - The name of the application (shown in help)
335335
- `description?: string` - A brief description of the application (shown in
336336
help)
337-
- `color?: boolean` - Enable colored help output (respects NO_COLOR
338-
environment variable)
337+
- `color?: boolean` - Enable colored help output (no automatic detection)
339338
- `showDefaults?: boolean` - Show default values in help text (default: true)
340339
- `defaultCommand?: string | "help"` - Default command to run when no
341340
arguments are provided
@@ -1069,7 +1068,7 @@ Options:
10691068

10701069
### Colored Help Output
10711070

1072-
Enable colored help text that respects the NO_COLOR environment variable standard:
1071+
Enable colored help text with simple boolean control:
10731072

10741073
```typescript
10751074
@parse(Deno.args, {
@@ -1087,20 +1086,17 @@ class Config {
10871086
```
10881087

10891088
**Color behavior:**
1090-
- Colors are automatically disabled if `NO_COLOR` environment variable is set
1091-
- Colors are disabled if stdout is not a TTY (e.g., piped output)
1092-
- Use `color: true` to request colors (still respects NO_COLOR and TTY)
1093-
- Use `color: false` to explicitly disable colors
1089+
- Use `color: true` to enable colored output
1090+
- Use `color: false` or omit the option to disable colors
1091+
- No automatic detection based on environment variables or TTY
1092+
- Users can implement their own color detection wrapper if needed
10941093

10951094
```bash
1096-
# Colored help (if terminal supports it)
1095+
# Colored help (when color: true is set)
10971096
deno run app.ts --help
10981097
1099-
# Disable colors via environment variable
1100-
NO_COLOR=1 deno run app.ts --help
1101-
1102-
# Disable colors via pipe
1103-
deno run app.ts --help | cat
1098+
# Plain help (default behavior)
1099+
deno run app.ts --help
11041100
```
11051101

11061102
### Show Default Values

examples/new_features.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* Demonstration of new CLI parsing features:
3-
* - Colored help output with NO_COLOR support
3+
* - Colored help output with simple boolean control
44
* - Default values shown in help text
55
* - Default command functionality
66
*/
@@ -69,7 +69,7 @@ class TestCommand {
6969
@parse(Deno.args, {
7070
name: "devtool",
7171
description: "A modern development tool with colored help and smart defaults",
72-
color: true, // Enable colored output (respects NO_COLOR)
72+
color: true, // Enable colored output
7373
showDefaults: true, // Show default values in help
7474
defaultCommand: "help", // Show help when no command is provided
7575
})
@@ -147,14 +147,11 @@ deno run new_features.ts build src/main.ts --minify --output build
147147
# Verbose mode
148148
deno run new_features.ts --verbose serve
149149
150-
# Disable colors
151-
NO_COLOR=1 deno run new_features.ts
152-
153150
# Help for specific command
154151
deno run new_features.ts serve --help
155152
156153
Features demonstrated:
157-
- ✅ Colored help output (respects NO_COLOR env var)
154+
- ✅ Colored help output (simple boolean control)
158155
- ✅ Default values shown in help text
159156
- ✅ Default command (shows help when no args provided)
160157
- ✅ Nested subcommands with proper help

src/colors.ts

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
/**
22
* Color utilities for CLI help output with NO_COLOR environment variable support.
33
*
4-
* This module provides ANSI color codes for terminal output while respecting
5-
* the NO_COLOR environment variable standard (https://no-color.org/).
4+
* This module provides ANSI color codes for terminal output.
65
*
76
* Features:
8-
* - Automatic color detection based on environment
9-
* - NO_COLOR environment variable support
10-
* - Graceful fallback to plain text
7+
* - Simple boolean-based color control
8+
* - No automatic detection or environment checks
9+
* - Users can implement their own color detection logic
1110
* - Common color functions for CLI output
1211
*/
1312

@@ -50,37 +49,14 @@ const COLORS = {
5049
/**
5150
* Determines if color output should be enabled.
5251
*
53-
* Colors are disabled if:
54-
* - NO_COLOR environment variable is set (any value)
55-
* - Terminal doesn't support colors
56-
* - Color is explicitly disabled
52+
* Simply returns the enableColor value - no heuristics or environment checks.
53+
* Users can wrap their CLI with their own color detection logic if needed.
5754
*
5855
* @param enableColor - Explicit color preference
5956
* @returns true if colors should be used
6057
*/
6158
function shouldUseColors(enableColor?: boolean): boolean {
62-
// Explicit disable takes precedence
63-
if (enableColor === false) {
64-
return false;
65-
}
66-
67-
// Check NO_COLOR environment variable
68-
if (process.env.NO_COLOR !== undefined) {
69-
return false;
70-
}
71-
72-
// Check if stdout is a TTY
73-
if (!process.stdout.isTTY) {
74-
return false;
75-
}
76-
77-
// If explicitly enabled, use colors
78-
if (enableColor === true) {
79-
return true;
80-
}
81-
82-
// Default: auto-detect based on environment
83-
return process.stdout.isTTY && !process.env.NO_COLOR;
59+
return enableColor === true;
8460
}
8561

8662
/**
@@ -155,6 +131,6 @@ export function createColors(enableColor?: boolean): {
155131
}
156132

157133
/**
158-
* Default color instance for convenience.
134+
* Default color instance for convenience (colors disabled by default).
159135
*/
160136
export const colors = createColors();

src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ export interface ParseOptions {
151151
name?: string;
152152
/** Application description shown in help text */
153153
description?: string;
154-
/** Enable colored help output (respects NO_COLOR environment variable) */
154+
/** Enable colored help output (no automatic detection) */
155155
color?: boolean;
156156
/** Show default values in help text */
157157
showDefaults?: boolean;

tests/lib.test.ts

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,46 +1795,31 @@ Deno.test("Color support - help output with colors enabled", () => {
17951795
}
17961796
});
17971797

1798-
Deno.test("Color support - respects NO_COLOR environment variable", () => {
1799-
// Save original environment
1800-
const originalNoColor = Deno.env.get("NO_COLOR");
1798+
Deno.test("Color support - disabled when color option is false", () => {
1799+
mockProcessExit();
18011800

18021801
try {
1803-
// Set NO_COLOR environment variable
1804-
Deno.env.set("NO_COLOR", "1");
1805-
1806-
mockProcessExit();
1807-
1808-
try {
1809-
const output = captureConsoleOutput(() => {
1810-
try {
1811-
@parse(["--help"], {
1812-
name: "nocolor",
1813-
description: "Test NO_COLOR",
1814-
color: true, // Even with color=true, NO_COLOR should disable it
1815-
})
1816-
class _Config {
1817-
static port: number = 8080;
1818-
}
1819-
} catch (_e) {
1820-
// Expected process.exit call
1802+
const output = captureConsoleOutput(() => {
1803+
try {
1804+
@parse(["--help"], {
1805+
name: "nocolor",
1806+
description: "Test color disabled",
1807+
color: false,
1808+
})
1809+
class _NoColorTest {
1810+
static port: number = 8080;
18211811
}
1822-
});
1823-
1824-
assertEquals(exitCode, 0);
1825-
// Colors should NOT be present in output when NO_COLOR is set
1826-
assertEquals(output.includes("\x1b["), false);
1827-
assertEquals(output.includes("nocolor"), true);
1828-
} finally {
1829-
restoreProcessExit();
1830-
}
1812+
} catch (_e) {
1813+
// Expected process.exit call
1814+
}
1815+
});
1816+
1817+
assertEquals(exitCode, 0);
1818+
// Colors should NOT be present in output when color=false
1819+
assertEquals(output.includes("\x1b["), false);
1820+
assertEquals(output.includes("nocolor"), true);
18311821
} finally {
1832-
// Restore original environment
1833-
if (originalNoColor !== undefined) {
1834-
Deno.env.set("NO_COLOR", originalNoColor);
1835-
} else {
1836-
Deno.env.delete("NO_COLOR");
1837-
}
1822+
restoreProcessExit();
18381823
}
18391824
});
18401825

0 commit comments

Comments
 (0)