Skip to content

feat: add non-interactive session checking to modern commands#10134

Open
paulbalandan wants to merge 3 commits intocodeigniter4:4.8from
paulbalandan:non-interactive-mode
Open

feat: add non-interactive session checking to modern commands#10134
paulbalandan wants to merge 3 commits intocodeigniter4:4.8from
paulbalandan:non-interactive-mode

Conversation

@paulbalandan
Copy link
Copy Markdown
Member

@paulbalandan paulbalandan commented Apr 23, 2026

Description
Adds a non-interactive session capability to the modern AbstractCommand framework introduced in #10120. Previously interact() always fired, so modern commands could hang on CLI::prompt() when run in CI, cron, or piped contexts.

This PR adds:

  • A reserved default option on every modern command: --no-interaction / -N.
  • Public API on AbstractCommand: isInteractive(): bool and setInteractive(bool): static.
  • Precedence: explicit setter > CLI flag > STDIN TTY detection.
  • Automatic cascade of the non-interactive state to sub-commands invoked via $this->call(...); a caller-supplied flag wins over propagation.
  • A new ?bool $noInteractionOverride parameter on call(): null (default) propagates, true forces non-interactive, false strips any inherited --no-interaction so the child resolves its own state.
  • logs:clear now shows its --force hint only in non-interactive mode, resolving an existing @todo.

Note
The shortcut is -N (capital) rather than -n because several legacy migration commands: migrate, migrate:refresh, migrate:rollback already use -n as the shortcut for --namespace. Capital -N leaves that shortcut free if any of those commands are later migrated to AbstractCommand.

Checklist:

  • Securely signed commits
  • Component(s) with PHPDoc blocks, only if necessary or adds value (without duplication)
  • Unit testing, with >80% coverage
  • User guide updated
  • Conforms to style guide

@github-actions github-actions Bot added the 4.8 PRs that target the `4.8` branch. label Apr 23, 2026
@paulbalandan paulbalandan force-pushed the non-interactive-mode branch from 23fd7fd to 409db29 Compare April 23, 2026 19:01
@paulbalandan paulbalandan force-pushed the non-interactive-mode branch from 409db29 to 6cfa8ce Compare April 23, 2026 19:25
Copy link
Copy Markdown
Member

@michalsn michalsn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks solid - nice work

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a first-class non-interactive mode to CodeIgniter’s modern AbstractCommand CLI framework so commands don’t hang on prompts in CI/cron/piped executions, and propagates that state through sub-command calls.

Changes:

  • Injects a default --no-interaction / -N option into all modern commands and skips interact() when non-interactive.
  • Adds AbstractCommand::isInteractive() / setInteractive() plus interactive-state propagation semantics for $this->call(..., ?bool $noInteractionOverride).
  • Updates docs/changelog and expands system tests (including logs:clear behavior) to cover the new mode.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
user_guide_src/source/cli/cli_modern_commands.rst Documents --no-interaction, interactive state precedence, and call() propagation/override semantics.
user_guide_src/source/changelogs/v4.8.0.rst Adds changelog entry describing the new flag and APIs.
system/CLI/AbstractCommand.php Implements interactive-state tracking, default option injection, call() override param, and propagation logic.
system/Commands/Housekeeping/ClearLogs.php Adjusts abort messaging to show the --force hint only in non-interactive mode.
tests/system/CLI/AbstractCommandTest.php Adds coverage for skipping interact(), isInteractive() behavior, and call() propagation/override cases.
tests/system/Commands/Housekeeping/ClearLogsTest.php Adds data-driven test verifying non-interactive abort output includes the --force hint.
tests/system/Commands/HelpCommandTest.php Updates expected help output to include -N, --no-interaction.
tests/_support/Commands/Modern/InteractiveStateProbeCommand.php New fixture command to record whether interact() ran and what interactive state was observed.
tests/_support/Commands/Modern/ParentCallsInteractFixtureCommand.php New fixture command to exercise call() interactive propagation and override behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread system/CLI/AbstractCommand.php Outdated
Comment thread user_guide_src/source/cli/cli_modern_commands.rst Outdated
Comment thread system/CLI/AbstractCommand.php
@paulbalandan paulbalandan requested a review from michalsn April 25, 2026 10:13
Copy link
Copy Markdown
Member

@michalsn michalsn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can "leak" the interactive state across repeated run() calls on the same command instance. This is not a problem for normal command usage, so I'm not sure if we should bother... although it can affect tests or other code that manually reuses a command object, like:

$cmd = new MyCommand();
$cmd->run([], ['no-interaction' => null]);
$cmd->run([], []);

@paulbalandan
Copy link
Copy Markdown
Member Author

Fixed. The flag becomes a per-run switch. Only setInteractive() call is persistent across runs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

4.8 PRs that target the `4.8` branch.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants