This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Nette Command Line is a lightweight PHP library providing two focused utilities:
Parser: Command-line argument and option parsing with help text extractionConsole: Terminal color output with intelligent capability detection
Key characteristics:
- Zero runtime dependencies (PHP 8.2-8.5 only)
- Minimal codebase (~518 LOC total)
- Part of the Nette Framework ecosystem
- Triple-licensed: BSD-3-Clause, GPL-2.0-only, GPL-3.0-only
composer install # Install dev dependenciescomposer run tester # Run all tests with simple output
vendor/bin/tester tests -s # Same as above
vendor/bin/tester tests -s # Run with code coverage
vendor/bin/tester tests/Parser.phpt -s # Run specific test filecomposer run phpstan # Run PHPStan static analysis (level 5)- Tests run on PHP 8.2, 8.3, 8.4, 8.5 via GitHub Actions
- Coding style checked via Nette Code Checker and Coding Standard
- PHPStan runs on master branch (informative only)
Parser (src/CommandLine/Parser.php - 368 lines)
- Parses command-line arguments using help text or fluent API
- Two approaches:
addFromHelp()for help-text-driven definitions, or fluentaddSwitch()/addOption()/addArgument()methods - Supports: flags, arguments, aliases, default values, enums, file paths, custom normalizers
- Modern PascalCase constants (e.g.,
Parser::Argument,Parser::Optional) - Deprecated UPPERCASE constants maintained for backward compatibility
Console (src/CommandLine/Console.php - 89 lines)
- ANSI color output with automatic terminal capability detection
- Respects
NO_COLORenvironment variable (https://no-color.org) - Detects Windows VT100 support and TTY environments
- 16 named colors with foreground/background combinations
Option (src/CommandLine/Option.php - 39 lines)
final readonly classrepresenting a single option or positional argument configuration- Properties:
name,type,alias,fallback,repeatable,enum,normalizer - Auto-computed
positionalproperty based on-prefix
ValueType (src/CommandLine/ValueType.php - 22 lines)
- Enum describing value requirement for options/arguments:
None- switch without value (e.g.,--verbose)Required- value must be provided (e.g.,--output <file>)Optional- value can be omitted (e.g.,--format [type])
Help Text as Schema:
The addFromHelp() method extracts option definitions from formatted help text:
$parser = new Parser;
$parser->addFromHelp('
-p, --param=<value> Parameter description (default: 123)
--verbose Enable verbose mode
');The help text format drives the parser configuration - options, arguments, defaults, and enums are all extracted from the help string structure.
Fluent API:
For more control, use addSwitch(), addOption(), and addArgument() methods:
$parser = new Parser;
$parser
->addSwitch('--verbose', '-v')
->addOption('--output', '-o')
->addOption('--format', '-f', optionalValue: true, fallback: 'json', enum: ['json', 'xml', 'csv'])
->addArgument('input', optional: false);Early-Exit Options with parseOnly():
For options like --help or --version that should work without providing required arguments:
$parser = new Parser;
$parser
->addSwitch('--help', '-h')
->addArgument('input'); // required
// Check --help before full validation
if ($parser->parseOnly(['--help'])['--help']) {
$parser->help();
exit;
}
$args = $parser->parse(); // full parsing with validationThe parseOnly() method parses only specified options, ignoring everything else. No validation, no exceptions.
Option Configuration Array:
When using addFromHelp(), additional options can be passed via second parameter:
Parser::Argument- requires a valueParser::Optional- value is optionalParser::Repeatable- can be specified multiple timesParser::Enum- restricted to specific valuesParser::RealPath- validates file path existenceParser::Normalizer- custom transformation functionParser::Default- default value when not specified
- Every file:
declare(strict_types=1)at the top - Tab indentation (not spaces)
- Comprehensive type hints on all parameters and return values
- PSR-12 inspired with Nette-specific modifications
- Minimal but clear documentation
- PascalCase for class constants (modern style, e.g.,
Parser::Optional) - camelCase for methods and properties
- Deprecated UPPERCASE constants aliased to PascalCase equivalents
- Classes: Brief description without unnecessary verbosity (e.g., "Stupid command line arguments parser")
- Methods: Document when adding value beyond type signatures
- Properties: Inline
@varannotations for complex types
Files use .phpt extension and follow this pattern:
<?php
declare(strict_types=1);
use Nette\CommandLine\Parser;
use Tester\Assert;
require __DIR__ . '/bootstrap.php';
test('description of what is tested', function () {
$cmd = new Parser('...');
Assert::same(['expected'], $cmd->parse(['input']));
});
test('another test case', function () {
// Test implementation
});- Use
test()function for each test case with clear descriptions - No comments before
test()calls - the description parameter serves this purpose - Group related tests in the same file
- Use
Assert::same()for exact equality checks - Use
Assert::exception()for exception testing
All tests require require __DIR__ . '/bootstrap.php'; which:
- Loads Composer autoloader
- Configures Tester environment
- Sets up test functions
Current branch: master (1.9-dev) PHP Support: 8.2 minimum, tested through 8.5 Branch alias: dev-master → 1.9-dev
- Deprecated constants maintained with
@deprecatedannotations - Old UPPERCASE constants aliased to new PascalCase versions
- Breaking changes noted in commit messages with "(BC break)"
When extending the Parser class:
- Add new constants in PascalCase format
- Create UPPERCASE deprecated aliases if replacing old names
- Update help text regex in constructor if needed
- Add comprehensive tests in
tests/Parser.phpt - Consider enum validation and normalizer patterns
When modifying Console output:
- Respect
$this->useColorsflag - Return plain strings when colors disabled
- Test with
NO_COLORenvironment variable - Consider cross-platform compatibility (Windows VT100)
- Create or extend
.phptfiles intests/directory - Use descriptive test names in
test()function - Cover both success and error cases
- Test edge cases (empty input, missing values, invalid formats)
Runtime: None (PHP 8.2+ only)
Development:
nette/tester^2.5 - Testing frameworktracy/tracy^2.9 - Debugging and error handlingphpstan/phpstan-nette^2.0 - Static analysis with Nette-specific rules
Autoloading:
- PSR-4:
Nette\→src/ - Classmap fallback for
src/directory