Skip to content

Conversation

@binaryfire
Copy link
Contributor

Summary

Implements Laravel-compatible app()->runningInConsole() detection for Hypervel, using coroutine-local Context to correctly distinguish between CLI commands and HTTP/queue contexts

Problem

In traditional Laravel, app()->runningInConsole() checks PHP_SAPI === 'cli'. This doesn't work in Swoole/Hypervel because both HTTP servers and console commands run via CLI.

Common use cases that need this detection:

  • Model global scopes that should behave differently in the CLI
  • Observers that skip certain behavior during CLI commands

Solution

Uses Hyperf\Context\Context to store a coroutine-local flag that tracks whether code is executing within a console command context.

How it works

  1. Kernel::handle() (the CLI entry point, e.g., php artisan foo) calls markAsRunningInConsole() before executing any command

  2. Kernel::call() (programmatic command execution) does NOT set the flag - it inherits whatever context already exists

  3. Command::execute() propagates the flag across coroutine boundaries when commands spawn new coroutines

Behavior matrix

Context runningInConsole()
php artisan migrate true
Code inside CLI command true
Nested command via Artisan::call() from CLI true
Scheduled command (via schedule:run) true
HTTP request false
Artisan::call() from HTTP controller false
Queue job false

Changes

  • Application.php - Added runningInConsole() and markAsRunningInConsole() methods using Context
  • Application.php (Contract) - Added method signatures to interface
  • Kernel.php - Calls markAsRunningInConsole() in handle() (CLI entry point only)
  • Command.php - Propagates console context across coroutine boundaries
  • App.php (Facade) - Regenerated docblocks to include new methods

Tests

10 tests covering:

  • Default state returns false
  • markAsRunningInConsole() sets state to true
  • Idempotent marking
  • Kernel::handle() sets the flag
  • Artisan::call() alone doesn't set the flag
  • Code inside CLI commands sees true
  • Code inside Kernel::call() without prior handle() sees false
  • Nested commands inherit console context
  • app() helper reflects state
  • Scheduled commands inherit context from schedule:run

Implements Laravel-compatible runningInConsole() for Swoole's coroutine
architecture where PHP_SAPI detection doesn't work (both HTTP server and
CLI commands run via CLI).

- Add runningInConsole() and markAsRunningInConsole() to Application
- Kernel::handle() sets the console context flag for CLI entry points
- Command::execute() preserves context across coroutine boundaries
- Uses __foundation.running_in_console Context key (framework convention)

Semantics:
- CLI commands via Kernel::handle(): true
- Artisan::call() from HTTP: false (inherits caller context)
- Nested commands: inherit parent context
- Scheduled commands: true (inherited from schedule:run)
- Queue jobs: false
- Remove queue job test that didn't actually test the PR's functionality
- Remove CaptureRunningInConsoleJob fixture (100+ lines of boilerplate)
- Rename test method to accurately reflect what it tests
- Regenerate App facade docblocks to include new methods
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