aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-07-24 20:22:58 +0900
committernsfisis <nsfisis@gmail.com>2026-07-24 20:22:58 +0900
commit8c316f2c5e93888f4b3a5b8c18df3373b54fa816 (patch)
tree06455cd54b6a41febabab13ba76c9d92406b57fe /crates/shirabe
parent08a99447445167e2b2eeee9c81fc89d5044bfe6d (diff)
downloadphp-shirabe-8c316f2c5e93888f4b3a5b8c18df3373b54fa816.tar.gz
php-shirabe-8c316f2c5e93888f4b3a5b8c18df3373b54fa816.tar.zst
php-shirabe-8c316f2c5e93888f4b3a5b8c18df3373b54fa816.zip
fix(dependency-resolver): query real PHP for ext-* version/loaded checks
Two shim gaps made the extension-related branches of solver-problem messages wrong: - phpversion($ext) with a non-empty extension can't be known statically (it's shirabe-php-shim's todo!()); Problem::get_missing_package_reason now calls shirabe_php_rpc::phpversion, the same RPC bridge platform::runtime::Runtime::get_extension_version already uses. - extension_loaded's hardcoded allowlist was missing "pcre", a mandatory always-compiled-in PHP extension, so ext-pcre was misreported as "missing from your system" instead of "disabled by your platform config" whenever a platform override disabled it. Also fix XdebugHandler::getAllIniFiles() always returning `[""]` (a php-runtime stub): create_extension_hint()'s early-return guard (`paths[0] empty && len==1`) fired unconditionally, silently dropping the entire "To enable extensions..." hint from every solver-problem message that mentions missing extensions. shirabe-external-packages can't depend on shirabe-php-rpc (shirabe-php-rpc already depends on shirabe-external-packages), so IniHelper::get_all() queries a new get_all_ini_files RPC command directly instead of going through the stub. This exposed that XdebugHandler is never constructed with a name because bin/composer's restart-without-Xdebug bootstrap was never ported to main.rs, making COMPOSER_ORIGINAL_INIS-driven behavior unreachable; documented with a TODO(phase-c) and updated ini_helper_test.rs's ignore reasons (and ignored test_with_no_ini, which only passed before by coincidence with the old stub's constant output) to match.
Diffstat (limited to 'crates/shirabe')
-rw-r--r--crates/shirabe/src/dependency_resolver/problem.rs4
-rw-r--r--crates/shirabe/src/main.rs7
-rw-r--r--crates/shirabe/src/util/ini_helper.rs8
-rw-r--r--crates/shirabe/tests/installer_test.rs16
-rw-r--r--crates/shirabe/tests/util/ini_helper_test.rs18
5 files changed, 35 insertions, 18 deletions
diff --git a/crates/shirabe/src/dependency_resolver/problem.rs b/crates/shirabe/src/dependency_resolver/problem.rs
index 855638cf..5ff949a9 100644
--- a/crates/shirabe/src/dependency_resolver/problem.rs
+++ b/crates/shirabe/src/dependency_resolver/problem.rs
@@ -459,7 +459,9 @@ impl Problem {
Self::constraint_to_text(constraint)
);
- let runtime_version = phpversion(&ext);
+ // Per-extension version info can't be known statically; query the real PHP
+ // runtime via the RPC bridge, same as platform::runtime::Runtime::get_extension_version.
+ let runtime_version = shirabe_php_rpc::phpversion(&ext);
let effective_version = match runtime_version {
None => "0".to_string(),
Some(ref v) => v.clone(),
diff --git a/crates/shirabe/src/main.rs b/crates/shirabe/src/main.rs
index 2ae6d903..6eb8e4cb 100644
--- a/crates/shirabe/src/main.rs
+++ b/crates/shirabe/src/main.rs
@@ -3,6 +3,13 @@
use shirabe_php_shim::{PHP_ENV, PHP_SERVER};
fn main() {
+ // TODO(phase-c): PHP: `$xdebug = new XdebugHandler('Composer'); $xdebug->check(); unset($xdebug);`
+ // (restart the process without Xdebug loaded, for performance) is not ported. Since no
+ // XdebugHandler is ever constructed, `self::$name` never gets set, so the
+ // COMPOSER_ORIGINAL_INIS-env-var branch of XdebugHandler::getAllIniFiles() (see
+ // shirabe-external-packages' xdebug_handler.rs and shirabe/src/util/ini_helper.rs) is
+ // unreachable in this port, not merely unexercised by current tests.
+
// Take the $_ENV / $_SERVER snapshots before any putenv() mutates the real environment.
// See `docs/dev/env-vars-porting.md` for details.
std::sync::LazyLock::force(&PHP_ENV);
diff --git a/crates/shirabe/src/util/ini_helper.rs b/crates/shirabe/src/util/ini_helper.rs
index 57894113..c36b9189 100644
--- a/crates/shirabe/src/util/ini_helper.rs
+++ b/crates/shirabe/src/util/ini_helper.rs
@@ -1,13 +1,15 @@
//! ref: composer/src/Composer/Util/IniHelper.php
-use shirabe_external_packages::composer::xdebug_handler::XdebugHandler;
-
pub struct IniHelper;
impl IniHelper {
/// Returns an array of php.ini locations with at least one entry.
pub fn get_all() -> Vec<String> {
- XdebugHandler::get_all_ini_files()
+ // PHP: XdebugHandler::getAllIniFiles(). shirabe_external_packages::XdebugHandler's port
+ // of that method can't reach the PHP RPC bridge (shirabe-php-rpc already depends on
+ // shirabe-external-packages, so the reverse dependency would cycle), so query the real
+ // PHP runtime's loaded/scanned ini files here instead.
+ shirabe_php_rpc::get_all_ini_files()
}
/// Describes the location of the loaded php.ini file(s).
diff --git a/crates/shirabe/tests/installer_test.rs b/crates/shirabe/tests/installer_test.rs
index 1e25646b..311fbb12 100644
--- a/crates/shirabe/tests/installer_test.rs
+++ b/crates/shirabe/tests/installer_test.rs
@@ -1396,7 +1396,7 @@ pool_optimizer_test! {
pool_optimizer_install_without_lock => "install-without-lock.test";
pool_optimizer_load_replaced_package_if_replacer_dropped => "load-replaced-package-if-replacer-dropped.test";
pool_optimizer_outdated_lock_file_fails_install => "outdated-lock-file-fails-install.test";
- pool_optimizer_outdated_lock_file_with_new_platform_reqs_fails => "outdated-lock-file-with-new-platform-reqs-fails.test", ignore = "TODO(phase-d): known-failing fixture under COMPOSER_POOL_OPTIMIZER=1";
+ pool_optimizer_outdated_lock_file_with_new_platform_reqs_fails => "outdated-lock-file-with-new-platform-reqs-fails.test";
pool_optimizer_partial_update_always_updates_symlinked_path_repos => "partial-update-always-updates-symlinked-path-repos.test", ignore = "TODO(phase-d): known-failing fixture under COMPOSER_POOL_OPTIMIZER=1";
pool_optimizer_partial_update_downgrades_non_allow_listed_unstable => "partial-update-downgrades-non-allow-listed-unstable.test";
pool_optimizer_partial_update_forces_dev_reference_from_lock_for_non_updated_packages => "partial-update-forces-dev-reference-from-lock-for-non-updated-packages.test", ignore = "TODO(phase-d): known-failing fixture under COMPOSER_POOL_OPTIMIZER=1";
@@ -1413,7 +1413,7 @@ pool_optimizer_test! {
pool_optimizer_partial_update_with_deps_warns_root => "partial-update-with-deps-warns-root.test";
pool_optimizer_partial_update_with_symlinked_path_repos => "partial-update-with-symlinked-path-repos.test", ignore = "TODO(phase-d): known-failing fixture under COMPOSER_POOL_OPTIMIZER=1";
pool_optimizer_partial_update_without_lock => "partial-update-without-lock.test";
- pool_optimizer_platform_ext_solver_problems => "platform-ext-solver-problems.test", ignore = "TODO(phase-d): known-failing fixture under COMPOSER_POOL_OPTIMIZER=1";
+ pool_optimizer_platform_ext_solver_problems => "platform-ext-solver-problems.test";
pool_optimizer_plugins_are_installed_first => "plugins-are-installed-first.test";
pool_optimizer_prefer_lowest_branches => "prefer-lowest-branches.test";
pool_optimizer_problems_reduce_versions => "problems-reduce-versions.test";
@@ -1447,8 +1447,8 @@ pool_optimizer_test! {
pool_optimizer_root_alias_gets_loaded_for_locked_pkgs => "root-alias-gets-loaded-for-locked-pkgs.test";
pool_optimizer_root_requirements_do_not_affect_locked_versions => "root-requirements-do-not-affect-locked-versions.test";
pool_optimizer_solver_problem_with_hash_in_branch => "solver-problem-with-hash-in-branch.test";
- pool_optimizer_solver_problems_with_disabled_platform => "solver-problems-with-disabled-platform.test", ignore = "TODO(phase-d): known-failing fixture under COMPOSER_POOL_OPTIMIZER=1";
- pool_optimizer_solver_problems => "solver-problems.test", ignore = "TODO(phase-d): known-failing fixture under COMPOSER_POOL_OPTIMIZER=1";
+ pool_optimizer_solver_problems_with_disabled_platform => "solver-problems-with-disabled-platform.test";
+ pool_optimizer_solver_problems => "solver-problems.test";
pool_optimizer_suggest_installed => "suggest-installed.test";
pool_optimizer_suggest_prod_nolock => "suggest-prod-nolock.test";
pool_optimizer_suggest_prod => "suggest-prod.test";
@@ -1586,7 +1586,7 @@ raw_pool_test! {
raw_pool_install_without_lock => "install-without-lock.test";
raw_pool_load_replaced_package_if_replacer_dropped => "load-replaced-package-if-replacer-dropped.test";
raw_pool_outdated_lock_file_fails_install => "outdated-lock-file-fails-install.test";
- raw_pool_outdated_lock_file_with_new_platform_reqs_fails => "outdated-lock-file-with-new-platform-reqs-fails.test", ignore = "TODO(phase-d): known-failing fixture under COMPOSER_POOL_OPTIMIZER=0";
+ raw_pool_outdated_lock_file_with_new_platform_reqs_fails => "outdated-lock-file-with-new-platform-reqs-fails.test";
raw_pool_partial_update_always_updates_symlinked_path_repos => "partial-update-always-updates-symlinked-path-repos.test", ignore = "TODO(phase-d): known-failing fixture under COMPOSER_POOL_OPTIMIZER=0";
raw_pool_partial_update_downgrades_non_allow_listed_unstable => "partial-update-downgrades-non-allow-listed-unstable.test";
raw_pool_partial_update_forces_dev_reference_from_lock_for_non_updated_packages => "partial-update-forces-dev-reference-from-lock-for-non-updated-packages.test", ignore = "TODO(phase-d): known-failing fixture under COMPOSER_POOL_OPTIMIZER=0";
@@ -1603,7 +1603,7 @@ raw_pool_test! {
raw_pool_partial_update_with_deps_warns_root => "partial-update-with-deps-warns-root.test";
raw_pool_partial_update_with_symlinked_path_repos => "partial-update-with-symlinked-path-repos.test", ignore = "TODO(phase-d): known-failing fixture under COMPOSER_POOL_OPTIMIZER=0";
raw_pool_partial_update_without_lock => "partial-update-without-lock.test";
- raw_pool_platform_ext_solver_problems => "platform-ext-solver-problems.test", ignore = "TODO(phase-d): known-failing fixture under COMPOSER_POOL_OPTIMIZER=0";
+ raw_pool_platform_ext_solver_problems => "platform-ext-solver-problems.test";
raw_pool_plugins_are_installed_first => "plugins-are-installed-first.test";
raw_pool_prefer_lowest_branches => "prefer-lowest-branches.test";
raw_pool_problems_reduce_versions => "problems-reduce-versions.test";
@@ -1637,8 +1637,8 @@ raw_pool_test! {
raw_pool_root_alias_gets_loaded_for_locked_pkgs => "root-alias-gets-loaded-for-locked-pkgs.test";
raw_pool_root_requirements_do_not_affect_locked_versions => "root-requirements-do-not-affect-locked-versions.test";
raw_pool_solver_problem_with_hash_in_branch => "solver-problem-with-hash-in-branch.test";
- raw_pool_solver_problems_with_disabled_platform => "solver-problems-with-disabled-platform.test", ignore = "TODO(phase-d): known-failing fixture under COMPOSER_POOL_OPTIMIZER=0";
- raw_pool_solver_problems => "solver-problems.test", ignore = "TODO(phase-d): known-failing fixture under COMPOSER_POOL_OPTIMIZER=0";
+ raw_pool_solver_problems_with_disabled_platform => "solver-problems-with-disabled-platform.test";
+ raw_pool_solver_problems => "solver-problems.test";
raw_pool_suggest_installed => "suggest-installed.test";
raw_pool_suggest_prod_nolock => "suggest-prod-nolock.test";
raw_pool_suggest_prod => "suggest-prod.test";
diff --git a/crates/shirabe/tests/util/ini_helper_test.rs b/crates/shirabe/tests/util/ini_helper_test.rs
index 76705a09..0b3835a0 100644
--- a/crates/shirabe/tests/util/ini_helper_test.rs
+++ b/crates/shirabe/tests/util/ini_helper_test.rs
@@ -43,6 +43,9 @@ fn set_env(paths: &[&str]) {
}
#[test]
+#[ignore = "XdebugHandler is never constructed with a name (the bin/composer restart-without-Xdebug \
+bootstrap is unported, see TODO(phase-c) in shirabe's main.rs), so IniHelper::get_all() queries \
+the real PHP runtime directly instead of consulting COMPOSER_ORIGINAL_INIS"]
fn test_with_no_ini() {
let paths = [""];
@@ -55,8 +58,9 @@ fn test_with_no_ini() {
}
#[test]
-#[ignore = "XdebugHandler::get_all_ini_files() is stubbed to always return [\"\"], ignoring \
-COMPOSER_ORIGINAL_INIS entirely"]
+#[ignore = "XdebugHandler is never constructed with a name (the bin/composer restart-without-Xdebug \
+bootstrap is unported, see TODO(phase-c) in shirabe's main.rs), so IniHelper::get_all() queries \
+the real PHP runtime directly instead of consulting COMPOSER_ORIGINAL_INIS"]
fn test_with_loaded_ini_only() {
let paths = ["loaded.ini"];
@@ -65,8 +69,9 @@ fn test_with_loaded_ini_only() {
}
#[test]
-#[ignore = "XdebugHandler::get_all_ini_files() is stubbed to always return [\"\"], ignoring \
-COMPOSER_ORIGINAL_INIS entirely"]
+#[ignore = "XdebugHandler is never constructed with a name (the bin/composer restart-without-Xdebug \
+bootstrap is unported, see TODO(phase-c) in shirabe's main.rs), so IniHelper::get_all() queries \
+the real PHP runtime directly instead of consulting COMPOSER_ORIGINAL_INIS"]
fn test_with_loaded_ini_and_additional() {
let paths = ["loaded.ini", "one.ini", "two.ini"];
@@ -79,8 +84,9 @@ fn test_with_loaded_ini_and_additional() {
}
#[test]
-#[ignore = "XdebugHandler::get_all_ini_files() is stubbed to always return [\"\"], ignoring \
-COMPOSER_ORIGINAL_INIS entirely"]
+#[ignore = "XdebugHandler is never constructed with a name (the bin/composer restart-without-Xdebug \
+bootstrap is unported, see TODO(phase-c) in shirabe's main.rs), so IniHelper::get_all() queries \
+the real PHP runtime directly instead of consulting COMPOSER_ORIGINAL_INIS"]
fn test_without_loaded_ini_and_additional() {
let paths = ["", "one.ini", "two.ini"];