Skip to content

fix(run): recover Testo paths when a remote interpreter's configuration holds host paths - #99

Merged
roxblnfk merged 1 commit into
j-plugins:mainfrom
roxblnfk:fix/compose-run-paths
Sep 19, 2026
Merged

roxblnfk merged 1 commit into
j-plugins:mainfrom
roxblnfk:fix/compose-run-paths

Conversation

@roxblnfk

@roxblnfk roxblnfk commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

🔍 What was changed

  • A remote interpreter's Testo executable and its own config file are now forward-mapped when a path mapping matches them, instead of always being passed through as already-remote — a Docker Compose interpreter in run lifecycle mode no longer launches the host vendor/bin/testo.
  • When no testo.php is known, the working directory is now the project root above the executable rather than the content root, so the run starts in a directory the interpreter actually maps.

How it works

  • Working directory order: custom cwd → parent of the configured testo.php → nearest ancestor of the (reverse-mapped) executable holding testo.php or composer.json, bounded by project.basePath → platform fallback. A globally installed binary yields nothing and falls through.
  • Framework paths never go through the path processor (that is what raised the false "Path mappings are not configured" of False "Path mappings are not configured" warning when Test Framework settings store already-remote paths #95); they are mapped with convertToRemote, which returns an already-remote path unchanged and rewrites only a host one. The alternative configuration file keeps going through addPathArgument.

Why?

When no Testo configuration is bound to the interpreter id, PhpTestFrameworkSettingsManager.getOrCreateByInterpreter fabricates one from the local configuration (the one TestoComposerConfig created, with the host vendor/bin/testo and no config file) using PathMappingSettings.convertToRemote — which returns its input unchanged when no mapping matches. So frameworkConfig.executablePath came back as a host path, and the missing config file dropped the cwd to the unmapped content root. Compose exec looked fine only because that interpreter happened to have a real per-interpreter Testo configuration.

Checklist

…on holds host paths

test(run): cover projectRootOfExecutable and the working-directory precedence

With no Testo configuration bound to the interpreter id, PhpTestFrameworkSettingsManager.getOrCreateByInterpreter fabricates one from the local configuration through PathMappingSettings.convertToRemote, which returns its input unchanged when no mapping matches — so the executable stayed the host vendor/bin/testo, and a Docker Compose interpreter in run lifecycle mode launched a path that exists only outside the container.

That fabricated configuration also carries no config file, so the working directory fell through to the platform fallback (the content root), which the compose volume need not map; the nearest ancestor of the executable holding testo.php or composer.json is the one directory the interpreter is known to see, and bounding it by project.basePath keeps a globally installed binary from answering.

Assisted-By: Claude Fable 5.1
@roxblnfk

Copy link
Copy Markdown
Collaborator Author

Same fix covers a local interpreter case, worth adding to the description.

Monorepo, vendor/bin/testo at the root, the test file inside a nested Composer package (bridge/symfony-console/tests/Acceptance/EntrypointTest.php). No testo.php bound to the run configuration.

In a fresh checkout of that repository PhpStorm registered every nested composer.json as a Composer project (ComposerConfigs in workspace.xml), so the platform fallback took bridge/symfony-console as cwd and 2026.10.262 ran

php vendor/bin/testo run -q -n --teamcity --path tests/Acceptance/EntrypointTest.php

from there. The entrypoint fails, the nested package has no vendor/ of its own:

Unable to find `vendor/autoload.php` in the following paths:
- .../bridge/symfony-console/bin/../vendor/autoload.php
- vendor/autoload.php

The original checkout of the same repository, with only the root manifest registered, ran from the root. So the cwd depended on IDE-side Composer project detection, not on the repository.

With this branch the executable-root walk stops at the root testo.php before the fallback is consulted, so both checkouts start from the repository root and --path is computed against it.

@roxblnfk
roxblnfk merged commit 05e13be into j-plugins:main Sep 19, 2026
7 checks passed
@roxblnfk
roxblnfk deleted the fix/compose-run-paths branch September 19, 2026 21:06
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