//! ref: composer/src/Composer/Platform/HhvmDetector.php use crate::util::platform::Platform; use crate::util::process_executor::ProcessExecutor; use shirabe_external_packages::symfony::process::executable_finder::ExecutableFinder; use shirabe_php_shim::{HHVM_VERSION, defined}; use std::sync::Mutex; // None = null (uninitialized), Some(None) = false (not found), Some(Some(v)) = version static HHVM_VERSION_CACHE: Mutex>> = Mutex::new(None); pub struct HhvmDetector { executable_finder: Option, process_executor: Option, } impl HhvmDetector { pub fn new( executable_finder: Option, process_executor: Option, ) -> Self { Self { executable_finder, process_executor, } } pub fn reset(&self) { *HHVM_VERSION_CACHE.lock().unwrap() = None; } pub fn get_version(&mut self) -> Option { let cached = HHVM_VERSION_CACHE.lock().unwrap().clone(); if cached.is_some() { return cached.flatten(); } let mut cache = HHVM_VERSION_CACHE.lock().unwrap(); *cache = Some(if defined("HHVM_VERSION") { HHVM_VERSION.map(|s| s.to_string()) } else { None }); if cache.as_ref().unwrap().is_none() && !Platform::is_windows() { *cache = Some(None); let finder = self .executable_finder .get_or_insert_with(ExecutableFinder::new); let hhvm_path = finder.find("hhvm"); if let Some(hhvm_path) = hhvm_path { let executor = self .process_executor .get_or_insert_with(ProcessExecutor::new); let mut version_output = String::new(); let exit_code = executor.execute( &[ &hhvm_path, "--php", "-d", "hhvm.jit=0", "-r", "echo HHVM_VERSION;", ], &mut version_output, ); if exit_code == 0 { *cache = Some(Some(version_output)); } } } cache.clone().flatten() } }