Skip to content

Commit 3cc6cdc

Browse files
Fix nested process color output (#247)
* fix: preserve nested process color output * Update wiki submodule pointer for PR #247 * fix: suppress nested xdebug warnings * Update wiki submodule pointer for PR #247 * test: stabilize ansi capability detector * fix: keep phpmetrics composer analysis bounded --------- Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 979cc87 commit 3cc6cdc

51 files changed

Lines changed: 1825 additions & 109 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/wiki

Submodule wiki updated from 6176cf7 to 6248aa1

AGENTS.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,30 @@ composer dev-tools tests -- --coverage=.dev-tools/coverage
111111
- Rector rules: `src/Rector/`
112112
- Composer plugin: `src/Composer/`
113113

114+
**Architecture Direction:**
115+
116+
- Avoid introducing new dependencies on `composer/composer` outside the
117+
existing Composer plugin integration and legacy surfaces already awaiting
118+
decoupling.
119+
- Prefer DevTools-owned interfaces for generic runtime concerns such as
120+
environment variables, process execution, filesystem access, and console
121+
presentation instead of reaching for Composer utility classes.
122+
- When an existing Composer utility is convenient, first check whether a small
123+
local abstraction would support the ongoing Composer decoupling work with
124+
minimal code.
125+
- During the Composer-to-Symfony command migration, preserve the global
126+
execution affordances already relied on by nested tools: `--ansi`/`--no-ansi`,
127+
cache and `--cache-dir` handling, and working-directory behavior.
128+
- Keep color behavior explicit in command wrappers for tools with known flags
129+
instead of probing binaries dynamically; for example, Symfony/Composer-style
130+
tools can receive `--ansi`, while PHPUnit uses `--colors=always`.
131+
- Keep child-process environment policy centralized in `ProcessQueue`
132+
configurators, including disabling Xdebug for non-coverage subprocesses while
133+
preserving coverage drivers when PCOV is unavailable.
134+
- Prefer the project-approved `Safe\*` function imports whenever replacing or
135+
adding native PHP calls that have Safe equivalents, so Rector does not have
136+
to rewrite them during commit checks.
137+
114138
**Naming Conventions:**
115139

116140
- Classes: PascalCase

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414

1515
### Fixed
1616

17+
- Preserve color-friendly nested command environments, explicit Symfony Console ANSI flags, concise process section labels, and fixture-safe PhpMetrics execution with bounded Packagist lookups without restoring PTY (#239)
18+
- Disable Xdebug for queued child processes unless coverage requires it without PCOV, reducing repeated Composer Xdebug warnings in orchestrated commands (#239)
1719
- Keep the reports workflow permission warning loop shell-safe for paths containing backslashes (#244)
1820
- Keep required PHPUnit matrix checks reporting after workflow-managed `.github/wiki` pointer commits by running the pull-request test workflow without top-level path filters and aligning the packaged consumer test wrapper (#230)
1921
- Publish pending and per-version required PHPUnit statuses for workflow-dispatched test runs so wiki pointer commits do not wait for an all-matrix aggregate status (#230)

docs/commands/metrics.rst

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Options
3333
Comma-separated directories that should be excluded from analysis.
3434

3535
Default:
36-
``vendor,test,tests,tmp,cache,spec,build,.dev-tools,backup,resources``.
36+
``vendor,tmp,cache,spec,build,.dev-tools,backup,resources,tests/Fixtures``.
3737

3838
``--target=<directory>``
3939
Output directory for the generated metrics reports.
@@ -93,4 +93,9 @@ Behavior
9393
- ``--json`` and ``--pretty-json`` keep DevTools itself structured while
9494
running PhpMetrics in a quieter mode to avoid polluting the captured payload;
9595
- it runs PhpMetrics through the active PHP binary and suppresses PhpMetrics
96-
deprecation notices emitted by the dependency itself.
96+
deprecation notices emitted by the dependency itself;
97+
- it keeps PhpMetrics' Composer analysis enabled so the reports include package
98+
metadata from the root ``composer.json`` and ``composer.lock``, while the
99+
default exclusions keep nested fixture projects out of that Composer scan;
100+
- it limits PhpMetrics' per-package Packagist socket wait so package freshness
101+
enrichment cannot leave metrics generation stuck indefinitely.

docs/internals/architecture.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ command list:
7575
- Services
7676
* - ``FastForward\DevTools\Process\ProcessBuilderInterface``
7777
- ``ProcessBuilderInterface`` and ``ProcessQueueInterface`` build and
78-
execute subprocess pipelines.
78+
execute subprocess pipelines, while process environment and output
79+
Symfony-style sections keep nested command output readable without PTY
80+
and suppress unnecessary Xdebug overhead in child processes.
7981
* - ``Filesystem and metadata``
8082
- ``FilesystemInterface``, ``ComposerJsonInterface``, and
8183
``FileLocatorInterface`` resolve local files, project metadata, and

docs/running/specialized-commands.rst

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,12 @@ Important details:
132132
structured while forwarding JSON or quieter modes to the wrapped tools where
133133
available;
134134
- it suppresses deprecation notices emitted by the PhpMetrics dependency
135-
itself so the command output stays readable.
135+
itself so the command output stays readable;
136+
- it keeps PhpMetrics' Composer analysis enabled so report generation includes
137+
root package metadata, while default exclusions keep nested fixture projects
138+
out of that Composer scan;
139+
- it limits PhpMetrics' per-package Packagist socket wait so package freshness
140+
enrichment cannot leave report generation stuck indefinitely.
136141

137142
``code-style``
138143
--------------
@@ -270,6 +275,12 @@ Important details:
270275
``--progress`` re-enables it for human-readable runs;
271276
- ``--json`` and ``--pretty-json`` are propagated to each subprocess, while
272277
their progress output is suppressed where supported;
278+
- human-readable runs keep nested command output grouped with concise local
279+
section boundaries, pass color-friendly environment variables to
280+
subprocesses, and forward explicit ANSI flags to Symfony Console tools;
281+
- queued subprocesses run with ``XDEBUG_MODE=off`` when Xdebug is loaded but
282+
the command does not need Xdebug for coverage, or when PCOV can provide
283+
coverage instead;
273284
- it is the reporting stage used by ``standards``.
274285

275286
``skills``

docs/troubleshooting.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,26 @@ Recovery:
156156
When calling lower-level tools directly, use their non-interactive flags and
157157
provide required values through environment variables or workflow inputs.
158158

159+
Repeated Composer Xdebug Warnings
160+
---------------------------------
161+
162+
Scope: local orchestration commands.
163+
164+
Symptoms:
165+
166+
- Composer repeatedly prints that it is operating slower than normal because
167+
Xdebug is enabled;
168+
- aggregate commands emit the warning once per nested Composer subprocess.
169+
170+
Behavior:
171+
172+
DevTools sets ``XDEBUG_MODE=off`` for queued child processes when Xdebug is
173+
loaded but the child command does not need Xdebug for coverage. Coverage runs
174+
keep Xdebug available when PCOV is not loaded, and use PCOV when it is
175+
available. A warning printed by the top-level ``composer dev-tools`` process
176+
can still appear before DevTools itself starts; run that command with
177+
``XDEBUG_MODE=off`` when Xdebug is not needed for the top-level process.
178+
159179
GitHub Actions Error Annotations
160180
--------------------------------
161181

src/Console/Command/CodeStyleCommand.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
132132
->build('composer normalize');
133133

134134
$processBuilder = $this->processBuilder
135+
->withArgument('--ansi')
135136
->withArgument('--config', $this->fileLocator->locate(self::CONFIG));
136137

137138
if (! $progress) {
@@ -148,9 +149,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int
148149

149150
$ecs = $processBuilder->build('vendor/bin/ecs');
150151

151-
$this->processQueue->add($composerUpdate);
152-
$this->processQueue->add($composerNormalize);
153-
$this->processQueue->add($ecs);
152+
$this->processQueue->add(process: $composerUpdate, label: 'Refreshing Composer Lock');
153+
$this->processQueue->add(
154+
process: $composerNormalize,
155+
label: 'Normalizing composer.json with Composer Normalize'
156+
);
157+
$this->processQueue->add(process: $ecs, label: 'Checking Code Style with Easy Coding Standard');
154158

155159
$result = $this->processQueue->run($processOutput);
156160

src/Console/Command/DependenciesCommand.php

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,24 @@ protected function execute(InputInterface $input, OutputInterface $output): int
129129
return $this->failure($invalidArgumentException->getMessage(), $input);
130130
}
131131

132-
$this->processQueue->add($this->getRaiseToInstalledCommand($input));
133-
$this->processQueue->add($this->getOpenVersionsCommand($input));
132+
$this->processQueue->add(
133+
process: $this->getRaiseToInstalledCommand($input),
134+
label: 'Raising Dependency Constraints with Jack',
135+
);
136+
$this->processQueue->add(
137+
process: $this->getOpenVersionsCommand($input),
138+
label: 'Opening Dependency Constraints with Jack',
139+
);
134140

135141
if ($input->getOption('upgrade')) {
136-
$this->processQueue->add($this->getComposerUpdateCommand());
137-
$this->processQueue->add($this->getComposerNormalizeCommand());
142+
$this->processQueue->add(
143+
process: $this->getComposerUpdateCommand(),
144+
label: 'Updating Dependencies with Composer'
145+
);
146+
$this->processQueue->add(
147+
process: $this->getComposerNormalizeCommand(),
148+
label: 'Normalizing composer.json with Composer Normalize',
149+
);
138150
}
139151

140152
if (! $jsonOutput) {
@@ -143,10 +155,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int
143155
]);
144156
}
145157

146-
$this->processQueue->add($this->getComposerDependencyAnalyserCommand($input));
147158
$this->processQueue->add(
148-
$this->getJackBreakpointCommand($input, $maximumOutdated),
149-
$this->shouldIgnoreOutdatedFailures($maximumOutdated),
159+
process: $this->getComposerDependencyAnalyserCommand($input),
160+
label: 'Analyzing Dependencies with Composer Dependency Analyser',
161+
);
162+
$this->processQueue->add(
163+
process: $this->getJackBreakpointCommand($input, $maximumOutdated),
164+
ignoreFailure: $this->shouldIgnoreOutdatedFailures($maximumOutdated),
165+
label: 'Checking Outdated Dependencies with Jack',
150166
);
151167

152168
$result = $this->processQueue->run($processOutput);
@@ -279,7 +295,9 @@ private function getComposerUpdateCommand(): Process
279295
*/
280296
private function getComposerNormalizeCommand(): Process
281297
{
282-
return $this->processBuilder->build('composer normalize');
298+
return $this->processBuilder
299+
->withArgument('--ansi')
300+
->build('composer normalize');
283301
}
284302

285303
/**

src/Console/Command/DocsCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
165165

166166
$phpdoc = $processBuilder->build('vendor/bin/phpdoc');
167167

168-
$this->processQueue->add($phpdoc);
168+
$this->processQueue->add(process: $phpdoc, label: 'Generating API Docs with phpDocumentor');
169169

170170
$result = $this->processQueue->run($processOutput);
171171

0 commit comments

Comments
 (0)