aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-06-22 23:40:47 +0900
committernsfisis <nsfisis@gmail.com>2026-06-22 23:40:47 +0900
commit99ef82a9807578c1e5749156a027949efaba75c4 (patch)
treee5f6bfb4c74c1ced20a9bc1c884f811f582e38eb /crates/shirabe/src
parentffd3e239a56172d2a336fb4d6253c01f6b1a0100 (diff)
downloadphp-shirabe-99ef82a9807578c1e5749156a027949efaba75c4.tar.gz
php-shirabe-99ef82a9807578c1e5749156a027949efaba75c4.tar.zst
php-shirabe-99ef82a9807578c1e5749156a027949efaba75c4.zip
feat(json): resolve bundled Composer schema files via build.rs
JsonFile's schema paths previously relied on php_dir() (__DIR__), which has no runtime equivalent. Add a build.rs that copies composer-schema.json and composer-lock-schema.json next to the built executable, and resolve them with std::env::current_exe(). FilesystemRepository now embeds InstalledVersions.php directly via include_str! instead of reading it through php_dir(). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src')
-rw-r--r--crates/shirabe/src/json/json_file.rs31
-rw-r--r--crates/shirabe/src/repository/filesystem_repository.rs32
2 files changed, 34 insertions, 29 deletions
diff --git a/crates/shirabe/src/json/json_file.rs b/crates/shirabe/src/json/json_file.rs
index 4145385..0aada36 100644
--- a/crates/shirabe/src/json/json_file.rs
+++ b/crates/shirabe/src/json/json_file.rs
@@ -11,8 +11,8 @@ use shirabe_external_packages::seld::json_lint::ParsingException;
use shirabe_php_shim::{
InvalidArgumentException, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE,
PhpMixed, RuntimeException, UnexpectedValueException, dirname, file_exists, file_get_contents,
- file_put_contents, is_dir, is_file, json_decode, json_encode_ex, mkdir, php_dir, realpath,
- str_contains, str_ends_with, str_repeat, strlen, strpos, usleep,
+ file_put_contents, is_dir, is_file, json_decode, json_encode_ex, mkdir, realpath, str_contains,
+ str_ends_with, str_repeat, strlen, strpos, usleep,
};
use crate::downloader::TransportException;
@@ -87,14 +87,24 @@ impl JsonFile {
pub const INDENT_DEFAULT: &'static str = " ";
- /// PHP: __DIR__ . '/../../../res/composer-schema.json'
- pub fn composer_schema_path() -> String {
- format!("{}/../../../res/composer-schema.json", php_dir())
+ /// build.rs copies the Composer schema files into a res/ directory next to the
+ /// executable; this resolves that path via the running executable's location.
+ ///
+ /// TODO(phase-f): this on-disk layout is hard to distribute. Embed the schema with
+ /// include_str! and extract it to a temporary file at runtime instead.
+ pub fn composer_schema_path() -> std::path::PathBuf {
+ Self::schema_res_path("composer-schema.json")
+ }
+
+ /// See composer_schema_path.
+ pub fn lock_schema_path() -> std::path::PathBuf {
+ Self::schema_res_path("composer-lock-schema.json")
}
- /// PHP: __DIR__ . '/../../../res/composer-lock-schema.json'
- pub fn lock_schema_path() -> String {
- format!("{}/../../../res/composer-lock-schema.json", php_dir())
+ fn schema_res_path(filename: &str) -> std::path::PathBuf {
+ let exe = std::env::current_exe().expect("failed to resolve current executable path");
+ let dir = exe.parent().expect("executable has no parent directory");
+ dir.join("res").join(filename)
}
/// Initializes json file reader/parser.
@@ -329,8 +339,8 @@ impl JsonFile {
schema_file: Option<&str>,
) -> Result<bool> {
let mut is_composer_schema_file = false;
- let mut schema_file: String = match schema_file {
- Some(f) => f.to_string(),
+ let mut schema_file = match schema_file {
+ Some(f) => f.into(),
None => {
if schema == Self::LOCK_SCHEMA {
Self::lock_schema_path()
@@ -340,6 +350,7 @@ impl JsonFile {
}
}
};
+ let mut schema_file = schema_file.to_string_lossy().into_owned();
// Prepend with file:// only when not using a special schema already (e.g. in the phar)
if strpos(&schema_file, "://").is_none() {
diff --git a/crates/shirabe/src/repository/filesystem_repository.rs b/crates/shirabe/src/repository/filesystem_repository.rs
index 86887d1..2f74eaf 100644
--- a/crates/shirabe/src/repository/filesystem_repository.rs
+++ b/crates/shirabe/src/repository/filesystem_repository.rs
@@ -9,8 +9,8 @@ use shirabe_external_packages::composer::pcre::Preg;
use shirabe_php_shim::{
Exception, InvalidArgumentException, LogicException, PhpMixed, SORT_NATURAL,
UnexpectedValueException, array_flip, dirname, r#eval, file_get_contents, get_class,
- get_class_err, get_debug_type, in_array, is_array, is_null, is_string, ksort, php_dir,
- realpath, sort, sort_with_flags, str_repeat, strtr, trim, usort, var_export,
+ get_class_err, get_debug_type, in_array, is_array, is_null, is_string, ksort, realpath, sort,
+ sort_with_flags, str_repeat, strtr, trim, usort, var_export,
};
use crate::config::is_php_integer_key;
@@ -329,25 +329,19 @@ impl FilesystemRepository {
&format!("{}/installed.php", repo_dir),
&format!("<?php return {};\n", self.dump_to_php_code(&versions, 0),),
);
- let installed_versions_class =
- file_get_contents(&format!("{}/../InstalledVersions.php", php_dir(),));
-
- // this normally should not happen but during upgrades of Composer when it is installed in the project it is a possibility
- if let Some(class_content) = installed_versions_class {
- self.filesystem.borrow_mut().file_put_contents_if_modified(
- &format!("{}/InstalledVersions.php", repo_dir),
- &class_content,
- );
+ self.filesystem.borrow_mut().file_put_contents_if_modified(
+ &format!("{}/InstalledVersions.php", repo_dir),
+ include_str!("../../../../composer/src/Composer/InstalledVersions.php"),
+ );
- // make sure the in memory state is up to date with on disk
- InstalledVersions::reload(versions);
+ // make sure the in memory state is up to date with on disk
+ InstalledVersions::reload(versions);
- // make sure the selfDir matches the expected data at runtime if the class was loaded from the vendor dir, as it may have been
- // loaded from the Composer sources, causing packages to appear twice in that case if the installed.php is loaded in addition to the
- // in memory loaded data from above
- InstalledVersions::set_self_dir(repo_dir.replace('\\', "/"));
- InstalledVersions::set_installed_is_local_dir(true);
- }
+ // make sure the selfDir matches the expected data at runtime if the class was loaded from the vendor dir, as it may have been
+ // loaded from the Composer sources, causing packages to appear twice in that case if the installed.php is loaded in addition to the
+ // in memory loaded data from above
+ InstalledVersions::set_self_dir(repo_dir.replace('\\', "/"));
+ InstalledVersions::set_installed_is_local_dir(true);
}
Ok(())