utopia-php / utopia-php/detector
Framework detection can never return null for a repo with a package.json
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 3
- Forks
- 0
- Avg merge
- 11h 18m
- Merged PRs (30d)
- 1
Description
Summary
Framework::detect() never returns null for any repository containing a package.json, even when no framework is present. It returns angular.
Cause
package.json is listed in getFiles() for every framework detection — Angular, React, NextJs, SvelteKit, Astro, Analog and the rest. So for a repo with a package.json and no framework dependencies, every detector scores exactly one path match.
detect() then filters to the joint-highest scorers, and since all fourteen tie at 1, falls through to the fewest-parents tie-break in src/Detector/Framework.php:
$bestFrameworks = \array_keys($frameworkMatches);
usort($bestFrameworks, fn ($a, $b) => $fameworkParents[$a] <=> $fameworkParents[$b]);
$bestFramework = $bestFrameworks[0];
Angular extends JS directly, so it has the fewest parents and wins. The count($frameworkMatches) <= 0 early return never fires, because the tie is at 1 rather than 0.
Reproduction
Against utopia-php/detector 0.2.6, with all fourteen detections registered as in Appwrite's detection endpoint:
$detector = new Framework('npm');
$detector->addInput('{"dependencies":{"lodash":"^4"}}', Framework::INPUT_PACKAGES);
$detector->addInput('package.json', Framework::INPUT_FILE);
// ... addOption() for all 14 detections
$detector->detect()->getName(); // => "angular"
| Input | Expected | Actual |
|---|---|---|
{"dependencies":{"lodash":"^4"}} |
null |
angular |
{"devDependencies":{"turbo":"^2"}} |
null |
angular |
{} |
null |
angular |
Real repositories affected
Both are turborepo monorepos whose root package.json holds only tooling, with the apps under apps/*:
sunshineLixun/ShipFullStack→angularmohebifar/tooscut→angular
Consumers that map a detection to a build configuration will pick Angular's install/build commands and an output directory of ./dist/angular for these, which no build produces.
Note on the fix
This is a design call rather than an obvious patch, which is why this is an issue and not a PR. package.json cannot discriminate between frameworks, so the options I can see each have a blast radius across all fourteen detections:
- Drop
package.jsonfromgetFiles()and rely ongetPackages()for JS frameworks. Cleanest, but changes scores everywhere. - Require at least one package match before a detection is eligible, keeping
package.jsonas a tiebreak-only signal. - Weight path matches so a universal file scores below a discriminating one.
Happy to send a PR for whichever direction you prefer.
Found while testing Appwrite's framework detection against open-source repositories.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/Detector/Framework.php, especially Framework::detect(), getFiles(), and getPackages(). Reproduce the fourteen-detector case with package.json and package inputs, then compare the proposed eligibility and scoring directions. Done means repositories with no framework dependencies return null while framework repositories still select the appropriate detection.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 45/100