@@ -41,7 +41,38 @@ php -r "
4141 \$ missingConstraints = [];
4242 \$ missingNames = [];
4343 foreach (\$ deps as \$ package => \$ constraint) {
44- if (!is_dir('vendor/' . \$ package)) {
44+ \$ vendorDir = 'vendor/' . \$ package;
45+ // Check vendor dir exists AND the installed version satisfies the required constraint.
46+ // A plain directory check would miss constraint changes and leave incompatible versions.
47+ \$ installedVersion = null;
48+ \$ installedJson = 'vendor/' . \$ package . '/composer.json';
49+ if (is_dir(\$ vendorDir) && is_file(\$ installedJson)) {
50+ \$ installed = json_decode(file_get_contents(\$ installedJson), true);
51+ \$ installedVersion = \$ installed['version'] ?? null;
52+ }
53+ \$ needsInstall = !is_dir(\$ vendorDir);
54+ if (!\$ needsInstall && \$ installedVersion !== null) {
55+ // Use Composer's own semver check via the lock file if available.
56+ \$ lockFile = 'composer.lock';
57+ if (is_file(\$ lockFile)) {
58+ \$ lock = json_decode(file_get_contents(\$ lockFile), true);
59+ \$ lockedPackages = array_merge(\$ lock['packages'] ?? [], \$ lock['packages-dev'] ?? []);
60+ \$ found = false;
61+ foreach (\$ lockedPackages as \$ lp) {
62+ if (\$ lp['name'] === \$ package) {
63+ \$ found = true;
64+ break;
65+ }
66+ }
67+ // If not in lock file, the package was added externally – reinstall.
68+ if (!\$ found) {
69+ \$ needsInstall = true;
70+ }
71+ }
72+ } elseif (!is_dir(\$ vendorDir)) {
73+ \$ needsInstall = true;
74+ }
75+ if (\$ needsInstall) {
4576 \$ missingConstraints[] = escapeshellarg(\"\$ package:\$ constraint\" );
4677 \$ missingNames[] = escapeshellarg(\$ package);
4778 }
0 commit comments