Conversation
Tia refused to run whenever the Pest project was not the git repository root, because git prints and addresses paths relative to the repository root while the dependency graph is keyed on project-relative paths. Translate at every git boundary instead of guarding against the mismatch. `Git::pathPrefix()` resolves the directory of the project inside the repository, and `ChangedFiles` strips that prefix off the paths git prints, drops the paths of sibling packages, and prepends it to `git show`. Both diffs read `-z` records, because `core.quotePath` C-quotes a path outside ASCII, and `--no-relative` holds the frame when a user sets `diff.relative`. Three places read `<projectRoot>/.git` directly, which is absent in a nested project and in a worktree, and now ask git: `BaseRemote`, `Storage` and `Fingerprint::isTrackedByGit()`. `Storage` folds the prefix into the state key so two projects in one repository do not share a graph, and the fingerprint carries the prefix so a baseline published by a sibling project is rejected. A project at the repository root keeps the key and the fingerprint it had. `git check-ignore` runs without `--no-index`, so a tracked file that an ignore rule matches counts as part of the project on both sides of the boundary. Changes outside the project are dropped and reported by count in the run summary, so a nested project does not look idle when the repository around it moved. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… its root changes A nested project can load PHP from outside its own root: a Composer path repository, a psr-4 mapping onto `../packages/shared/src`, a PHPUnit bootstrap, source directory or test suite, an include path, or a symlink that leaves the project. The dependency graph reaches no further than the project root, so a change to those files selected no test at all and the suite replayed from cache. `ExternalSources` reads the composer manifest of the project and the PHPUnit configuration that the run selects, the way PHPUnit selects it: `-c` in its split, joined and attached forms, a directory as its value, `--no-configuration`, `--bootstrap` and `--include-path`, and the implicit file of the working directory. Each declaration resolves against the file that declares it, follows its symlinks when the target exists, keeps the segments before a wildcard, and keeps a target that a commit deleted. A root answers to the directory itself, so a moved submodule matches. A committed change under one of those roots stops the replay and records a fresh graph when a coverage driver is available. An uncommitted change there runs the full suite and writes nothing, on every path that writes: git stops reporting such an edit the moment it is undone, and no snapshot of the run covers it. A declaration that leaves the repository, or sits under a path the repository ignores, is reported and runs the full suite, because no run can observe it. The structural fingerprint carries the external roots and the identity of the selected configuration, so a graph recorded under one configuration does not replay under another. A project that declares nothing outside its root and runs the file PHPUnit selects by default keeps the fingerprint it had. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 of 2 tasks
Replace the phpunit_xml and phpunit_xml_dist entries with one configuration entry, and drop the exception that left the file of the project root to the tracked hash. A phpunit.xml that git ignores now invalidates the graph when its content changes. SCHEMA_VERSION moves to 19, so existing graphs rebuild once. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
# Conflicts: # src/Plugins/Tia/Baselines/BaseRemote.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Builds on #1914. The first commit here is that pull request; review the second commit,
fix(tia): run the full suite when code the project loads from outside its root changes.What happens
A nested project can load PHP from outside its own root: a Composer
pathrepository, a psr-4 mapping onto../packages/shared/src, a PHPUnitbootstrap,<source>directory or<testsuite>, an--include-path, or a symlink that leaves the project. The dependency graph reaches no further than the project root, so a change to any of those files selects no test at all, and the suite replays from cache with results that the changed code no longer supports.The fix
src/Plugins/Tia/ExternalSources.phpreads the composer manifest of the project and the PHPUnit configuration that the run selects, and resolves the roots the project loads from outside itself.-cin its split, joined and attached forms, a directory as its value,--no-configuration, and the implicit file of the working directory in the orderphpunit.xml,phpunit.dist.xml,phpunit.xml.dist.--bootstrapand--include-pathon the command line count as declarations too, and so does thebootstrapattribute of each test suite.--fresh, a rebuild after drift, and the result-only write of a--filterrun. Git stops reporting such an edit the moment it is undone, so no snapshot of the run could stand behind a cached result.phpunit.xmlandphpunit.xml.disttells-c phpunit.xml.distapart from the default. A project that declares nothing outside its root and runs the file PHPUnit selects by default keeps the fingerprint it had.This is the narrow form on purpose. Every change outside the project would make Tia worthless in a monorepo whose frontend moves daily; a project that declares nothing outside its root keeps the selection it had.
Tests
tests/Unit/Plugins/Tia/ExternalSources.phpcovers each declaration source, the configuration selection and the fingerprint.tests/Features/Tia/Monorepo.phpruns a nested project against a changed sibling package, an autoload file, a bootstrap, a deleted package, an external test suite, a wildcard path repository, a symlink, a submodule, a configuration argument, a relative-cfrom the repository root, an uncommitted external edit on each write path, and a project that loads from outside its repository.pest --group=tia: 248 passed.🤖 Generated with Claude Code