Skip to content

feat: simplify output handling - #20

Merged
loadinglucian merged 4 commits into
mainfrom
feat/simplify-output-handling
Oct 1, 2025
Merged

feat: simplify output handling#20
loadinglucian merged 4 commits into
mainfrom
feat/simplify-output-handling

Conversation

@loadinglucian

@loadinglucian loadinglucian commented Oct 1, 2025

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Introduced modern interactive prompts and spinners for input and progress.
    • Consistent banner now always displays; version flag shows banner and exits immediately.
    • Enhanced output helpers for simple/multi-line text and horizontal rules.
  • Refactor

    • Unified output pathway; quiet mode removed—commands always print output.
    • Streamlined CLI options to help, version, and ansi; removed quiet/verbose/no-interaction.
  • Documentation

    • Updated command output and interaction guidelines to reflect new patterns.
  • Tests

    • Added coverage for banner/version behavior and custom CLI options; removed quiet-mode tests.

Add laravel/prompts package to enable beautiful, interactive CLI prompts
with validation, auto-complete, and loading spinners for enhanced UX.
Remove quiet mode suppression from BaseCommand output methods and
introduce custom input definition that exposes only essential options.

Changes:
- Remove $isQuiet property and checks from BaseCommand
- Remove quiet mode logic from writeln(), text(), and hr() methods
- Add custom getDefaultInputDefinition() in SymfonyApp
- Expose only --help, --version, and --ansi options
- Add early exit when --version flag is used
- Banner now always displays (no quiet mode suppression)

BREAKING CHANGE: --quiet, --verbose, and --no-interaction flags are
no longer available. Commands always produce output. This aligns with
the new philosophy of modern TUI styling over verbosity management.
Replace quiet/verbosity management documentation with modern TUI
philosophy emphasizing BaseCommand custom methods and Laravel Prompts.

Changes:
- Remove quiet mode and verbosity level documentation
- Add output method philosophy section
- Document mandatory use of BaseCommand custom methods
- Add Laravel Prompts integration examples
- Remove performance and verbosity pattern guidelines
- Simplify to focus on consistent, beautiful output
Remove obsolete quiet mode tests and add new tests for custom input
definition and version flag handling.

Changes:
- Remove quiet mode suppression tests from BaseCommandTest
- Remove quiet mode test from HelloCommandTest
- Add test for custom input definition (only essential options)
- Add test for early exit on --version flag
- Add test for banner always displaying
- All tests passing with new architecture (14 integration tests)
@coderabbitai

coderabbitai Bot commented Oct 1, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Removes quiet-mode handling from BaseCommand helpers, adds a custom InputDefinition and version short-circuit in SymfonyApp, updates tests to reflect new behavior, and introduces laravel/prompts as a dependency. Documentation is rewritten to mandate BaseCommand-driven output and to demonstrate Laravel Prompts usage.

Changes

Cohort / File(s) Summary of changes
Command IO behavior
app/Contracts/BaseCommand.php
Removed isQuiet flag and related initialization; output helpers (writeln, text, hr) no longer suppress output in quiet mode.
Application input and version handling
app/SymfonyApp.php
Added custom getDefaultInputDefinition with only command, --help, --version, --ansi; doRun now always shows banner and exits early with success when --version is present.
Dependencies
composer.json
Added runtime dependency: laravel/prompts ^0.3.7.
Tests
tests/Integration/SymfonyAppTest.php, tests/Integration/Console/HelloCommandTest.php, tests/Unit/Contracts/BaseCommandTest.php
Added tests for custom input options, banner behavior, and --version early exit; removed quiet-mode output suppression tests in integration and unit suites.
Documentation and guidelines
.cursor/rules/03-commands.mdc
Replaced IO philosophy: require BaseCommand for output; discourage direct Symfony IO; added patterns for text, hr, and Laravel Prompts (inputs, spinners); removed verbosity/progress guidance.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant CLI as SymfonyApp (CLI)
  participant Cmd as Command
  Note over CLI: getDefaultInputDefinition()<br/>options: --help, --version, --ansi
  User->>CLI: Run app with --version
  CLI->>CLI: Display banner
  CLI->>CLI: hasParameterOption(--version) == true
  CLI-->>User: Exit Command::SUCCESS (no further execution)
  Note over CLI: Early exit on --version
Loading
sequenceDiagram
  autonumber
  actor User
  participant CLI as SymfonyApp (CLI)
  participant Cmd as Command
  User->>CLI: Run app (e.g., list)
  CLI->>CLI: Display banner (always)
  CLI->>Cmd: Execute command flow
  Cmd->>Cmd: BaseCommand::writeln/text/hr (no quiet suppression)
  Cmd-->>CLI: Return status
  CLI-->>User: Output result
  Note over Cmd: Output not gated by quiet mode
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • bigpixelrocket/deployer-php#17 — Also modifies BaseCommand and SymfonyApp around command initialization/output behavior.
  • bigpixelrocket/deployer-php#19 — Touches BaseCommand with configure/execute and option handling, overlapping the class modified here.

Poem

A banner unfurls at command-line dawn,
My whiskers twitch—quiet mode is gone!
Prompts hop in with a cheerful spin,
Version waves, exits with a grin.
From text to hr, I tap-tap-tap—
Consistent prints in every lap.
Carrot approved: ship this patch! 🥕🐇

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “feat: simplify output handling” succinctly captures the primary intent of the changeset, which centralizes and streamlines all output through the BaseCommand abstraction and deprecates direct Symfony IO usage in favor of uniform methods and Laravel Prompts integration. It is brief, focused on the main feature, and avoids extraneous details or generic phrasing. Teammates reviewing the history will immediately recognize that the pull request’s core purpose is to overhaul and simplify how command output is handled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/simplify-output-handling

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dfbd9b6 and b42e33d.

⛔ Files ignored due to path filters (1)
  • composer.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • .cursor/rules/03-commands.mdc (2 hunks)
  • app/Contracts/BaseCommand.php (0 hunks)
  • app/SymfonyApp.php (3 hunks)
  • composer.json (1 hunks)
  • tests/Integration/Console/HelloCommandTest.php (0 hunks)
  • tests/Integration/SymfonyAppTest.php (1 hunks)
  • tests/Unit/Contracts/BaseCommandTest.php (0 hunks)
💤 Files with no reviewable changes (3)
  • app/Contracts/BaseCommand.php
  • tests/Unit/Contracts/BaseCommandTest.php
  • tests/Integration/Console/HelloCommandTest.php
🧰 Additional context used
📓 Path-based instructions (6)
**/*.php

📄 CodeRabbit inference engine (.cursor/rules/00-main.mdc)

**/*.php: Organize code into comment-separated sections grouping related functions
Prefer alphabetical ordering when it doesn’t conflict with logical grouping
Maintain obsessive implementation consistency and logical coherence across similar areas (naming, parameters, flow, comments)
Refactor relentlessly for clarity and necessity

**/*.php: Follow PSR-12 coding standard in all PHP files
Declare strict types in all PHP files (declare(strict_types=1);)
Use PHP 8.x features where appropriate (unions, match, attributes, readonly)
Use import statements (use ...) instead of fully qualified class names in code
All methods must declare explicit return types with proper generics (e.g., Collection<int, User>)
Prefer Dependency Injection over manual class resolution/instantiation
Use Symfony component classes (e.g., Filesystem, Process) instead of native PHP functions for easier mocking
All object creation must use $container->build(ClassName::class) except for value objects, DTOs, and pure data structures
Access the container via constructor injection in production code; tests may instantiate Container directly
Services must receive dependencies via constructor injection
Use SymfonyStyle consistently for all user-facing console output
Add DocBlock comments with minimalist descriptions, parameters, and return types for classes and functions
Use comments to separate sections and explain complex logic; avoid obvious or stale comments
Use the exact section header comment format with a single newline between headers/subheaders/paragraphs

Files:

  • tests/Integration/SymfonyAppTest.php
  • app/SymfonyApp.php
tests/**

📄 CodeRabbit inference engine (.cursor/rules/00-main.mdc)

Do not run or edit tests unless explicitly instructed

Files:

  • tests/Integration/SymfonyAppTest.php
tests/**/*.php

📄 CodeRabbit inference engine (.cursor/rules/02-tests.mdc)

tests/**/*.php: Use Pest exclusively with it() syntax for all tests.
Keep each test file under 1.8x the size of the source code it tests.
Test core business logic; do not test the framework itself.
Use dataset-driven testing with ->with([]) for multiple scenarios.
Eliminate overlap: avoid multiple tests covering the same functionality.
Consolidate assertions using chained expectations (e.g., expect(...)->toBe(...)->and(...)).
Mock only external dependencies; do not mock internal implementation details.
Do not add performance tests unless performance is the primary concern.
Do not sacrifice readability to meet size/ratio targets.
Do not consolidate tests when they target different public methods.
Do not consolidate exception-flow tests with normal-flow tests.
Do not consolidate tests with different setup requirements.
Do not consolidate tests covering distinct business logic.
Follow the AAA pattern (Arrange, Act, Assert) in all tests; include cleanup when needed.
For exception tests, use a combined // ACT & ASSERT step when the act triggers the assertion.
Organize tests with describe() blocks, beforeEach() setup, and extract helpers/traits for DRY tests.
Do not assert only on type using toBeInstanceOf(Class::class).
Do not use generic assertions like toBeArray() that don’t validate behavior.
Avoid meaningless assertions such as not->toBeNull() without behavioral relevance.
Do not write literally meaningless assertions like expect(true)->toBeTrue().
Do not use sleep(...); use time mocking instead.
Write assertions against concrete outcomes, e.g., expect($config->getValue('host'))->toBe('example.com').
Assert validator outcomes directly, e.g., expect($this->validator->isValid($input))->toBe($expected).
Define mock expectations explicitly, e.g., $mock->shouldReceive('method')->with('param')->andReturn('result').
In unit tests, mock all external dependencies (filesystem, HTTP, processes).
Unit tests should target a single unit in isolation.
Unit tests should complete i...

Files:

  • tests/Integration/SymfonyAppTest.php
composer.json

📄 CodeRabbit inference engine (.cursor/rules/00-main.mdc)

Before starting any task, check composer.json for installed packages

Files:

  • composer.json
{composer.json,package.json}

📄 CodeRabbit inference engine (.cursor/rules/00-main.mdc)

Plan using features supported by the major versions of installed dependencies

Files:

  • composer.json
app/SymfonyApp.php

📄 CodeRabbit inference engine (.cursor/rules/01-architecture.mdc)

Register commands via $this->container->build(CommandClass::class) in SymfonyApp.php

Files:

  • app/SymfonyApp.php
🧠 Learnings (9)
📚 Learning: 2025-10-01T13:57:29.909Z
Learnt from: CR
PR: bigpixelrocket/deployer-php#0
File: .cursor/rules/03-commands.mdc:0-0
Timestamp: 2025-10-01T13:57:29.909Z
Learning: Applies to src/Command/**/*.php : Prefer SymfonyStyle high-level methods (success, info, warning, error, note, caution, table, progress*) for all output; they auto-honor quiet/verbosity

Applied to files:

  • .cursor/rules/03-commands.mdc
📚 Learning: 2025-10-01T13:57:29.909Z
Learnt from: CR
PR: bigpixelrocket/deployer-php#0
File: .cursor/rules/03-commands.mdc:0-0
Timestamp: 2025-10-01T13:57:29.909Z
Learning: Applies to src/Command/**/*.php : Only use raw $this->io->writeln() for complex custom formatting, and only after checking quiet mode (e.g., if (!$this->isQuiet))

Applied to files:

  • .cursor/rules/03-commands.mdc
📚 Learning: 2025-10-01T13:57:29.909Z
Learnt from: CR
PR: bigpixelrocket/deployer-php#0
File: .cursor/rules/03-commands.mdc:0-0
Timestamp: 2025-10-01T13:57:29.909Z
Learning: Applies to src/Command/**/*.php : For simple text output, use project wrapper methods writeln(), text(), hr() (from BaseCommand) instead of raw SymfonyStyle output

Applied to files:

  • .cursor/rules/03-commands.mdc
📚 Learning: 2025-10-01T13:57:29.909Z
Learnt from: CR
PR: bigpixelrocket/deployer-php#0
File: .cursor/rules/03-commands.mdc:0-0
Timestamp: 2025-10-01T13:57:29.909Z
Learning: Applies to src/Command/**/*.php : Use SymfonyStyle auto-verbosity features (section, note, progress bars) for appropriate visibility at each verbosity level

Applied to files:

  • .cursor/rules/03-commands.mdc
📚 Learning: 2025-10-01T13:57:29.909Z
Learnt from: CR
PR: bigpixelrocket/deployer-php#0
File: .cursor/rules/03-commands.mdc:0-0
Timestamp: 2025-10-01T13:57:29.909Z
Learning: Applies to src/Command/**/*.php : Do not call raw SymfonyStyle output methods like $this->io->writeln() or $this->io->text() directly (forbidden)

Applied to files:

  • .cursor/rules/03-commands.mdc
📚 Learning: 2025-10-01T13:56:16.653Z
Learnt from: CR
PR: bigpixelrocket/deployer-php#0
File: .cursor/rules/01-architecture.mdc:0-0
Timestamp: 2025-10-01T13:56:16.653Z
Learning: Applies to **/*.php : Use SymfonyStyle consistently for all user-facing console output

Applied to files:

  • .cursor/rules/03-commands.mdc
📚 Learning: 2025-10-01T13:57:29.909Z
Learnt from: CR
PR: bigpixelrocket/deployer-php#0
File: .cursor/rules/03-commands.mdc:0-0
Timestamp: 2025-10-01T13:57:29.909Z
Learning: Applies to src/Command/**/*.php : Honor Symfony verbosity levels; provide more detail with -v/-vv/-vvv and keep essential output at normal verbosity

Applied to files:

  • .cursor/rules/03-commands.mdc
📚 Learning: 2025-10-01T13:57:29.909Z
Learnt from: CR
PR: bigpixelrocket/deployer-php#0
File: .cursor/rules/03-commands.mdc:0-0
Timestamp: 2025-10-01T13:57:29.909Z
Learning: Applies to src/Command/**/*.php : Use custom verbosity checks (isVerbose, isVeryVerbose, isDebug) to gate additional content

Applied to files:

  • .cursor/rules/03-commands.mdc
📚 Learning: 2025-10-01T13:57:29.909Z
Learnt from: CR
PR: bigpixelrocket/deployer-php#0
File: .cursor/rules/03-commands.mdc:0-0
Timestamp: 2025-10-01T13:57:29.909Z
Learning: Applies to src/Command/**/*.php : Structure output progressively: always show critical start/end messages; add summaries at -v; detailed steps at -vv; traces at -vvv

Applied to files:

  • .cursor/rules/03-commands.mdc
🧬 Code graph analysis (1)
tests/Integration/SymfonyAppTest.php (2)
app/Container.php (2)
  • Container (23-227)
  • build (42-62)
app/SymfonyApp.php (2)
  • SymfonyApp (21-125)
  • doRun (66-78)
🔇 Additional comments (10)
tests/Integration/SymfonyAppTest.php (3)

153-169: LGTM! Test correctly validates custom input definition.

The test appropriately verifies that only the intended options (help, version, ansi) are exposed and that the removed options (quiet, verbose, no-interaction) are excluded from the custom input definition.


171-189: LGTM! Version flag short-circuit behavior is well-tested.

The test correctly validates that --version exits early with success and displays the banner without rendering the command list.


191-208: LGTM! Banner display behavior is validated.

The test confirms that the banner is always displayed regardless of output decoration settings, which aligns with the new output philosophy.

app/SymfonyApp.php (3)

11-12: LGTM! Imports correctly added for custom input definition.

The new imports for InputArgument, InputDefinition, and InputOption are necessary for the custom input definition override.

Also applies to: 14-14


42-53: LGTM! Custom input definition correctly excludes unwanted options.

The override provides a minimal, intentional set of options (help, version, ansi) and correctly excludes Symfony's default quiet, verbose, and no-interaction options, aligning with the PR's goal to simplify output handling.


70-75: LGTM! Version flag handling is clean and correct.

The banner is displayed unconditionally, and the --version flag correctly short-circuits execution, returning success without proceeding to command dispatch. This provides a clean user experience and aligns with the test expectations.

.cursor/rules/03-commands.mdc (3)

9-57: LGTM! Output philosophy clearly mandates BaseCommand-centric approach.

The rewritten section effectively communicates the mandatory use of BaseCommand methods and forbids direct Symfony IO usage. The examples are clear and actionable, with guidance on extending BaseCommand when new methods are needed.


58-92: LGTM! Laravel Prompts integration is well-documented.

The section provides comprehensive examples of Laravel Prompts usage with appropriate patterns for interactive and non-interactive modes. The integration with $this->io->isInteractive() checks and spinner usage guidance aligns with the new dependency added in composer.json.


93-130: LGTM! Command layer patterns reflect the new architecture.

The updated patterns correctly demonstrate BaseCommand method usage and Laravel Prompts integration, maintaining clean separation between commands and services. The flow examples are consistent with the new output philosophy.

composer.json (1)

21-21: No changes required: laravel/prompts ^0.3.7 is the latest stable release and has no known security advisories.


Comment @coderabbitai help to get the list of available commands and usage tips.

@loadinglucian
loadinglucian merged commit a5d6885 into main Oct 1, 2025
5 checks passed
@loadinglucian
loadinglucian deleted the feat/simplify-output-handling branch October 1, 2025 15:30
@coderabbitai coderabbitai Bot mentioned this pull request Oct 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant