aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/shirabe-php-shim/src/fs.rs4
-rw-r--r--crates/shirabe/build.rs37
-rw-r--r--crates/shirabe/src/json/json_file.rs31
-rw-r--r--crates/shirabe/src/repository/filesystem_repository.rs32
4 files changed, 73 insertions, 31 deletions
diff --git a/crates/shirabe-php-shim/src/fs.rs b/crates/shirabe-php-shim/src/fs.rs
index a97433a..e55b689 100644
--- a/crates/shirabe-php-shim/src/fs.rs
+++ b/crates/shirabe-php-shim/src/fs.rs
@@ -512,8 +512,8 @@ pub fn file_put_contents3(_filename: &str, _data: &str, _flags: i64) -> Option<i
Some(_data.len() as i64)
}
-pub fn file_get_contents(_path: &str) -> Option<String> {
- std::fs::read(_path)
+pub fn file_get_contents(path: impl AsRef<std::path::Path>) -> Option<String> {
+ std::fs::read(path)
.ok()
.map(|bytes| String::from_utf8_lossy(&bytes).into_owned())
}
diff --git a/crates/shirabe/build.rs b/crates/shirabe/build.rs
new file mode 100644
index 0000000..d98b07e
--- /dev/null
+++ b/crates/shirabe/build.rs
@@ -0,0 +1,37 @@
+use std::path::PathBuf;
+
+// Composer ships its JSON schemas in res/ and JsonFile resolves them via __DIR__.
+// We copy those schema files next to the built executable so they can be located
+// at runtime through std::env::current_exe().
+fn main() {
+ let manifest_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
+ let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
+
+ // OUT_DIR is target/<profile>/build/<pkg>-<hash>/out; its 3rd ancestor is target/<profile>.
+ let target_profile_dir = out_dir
+ .ancestors()
+ .nth(3)
+ .expect("OUT_DIR has an unexpected layout");
+
+ let composer_res = manifest_dir.join("../../composer/res");
+ let files = ["composer-schema.json", "composer-lock-schema.json"];
+
+ // Binaries live in target/<profile>, test/example binaries in target/<profile>/deps;
+ // populate a res/ directory next to both so current_exe()/../res resolves either way.
+ for dest_dir in [
+ target_profile_dir.join("res"),
+ target_profile_dir.join("deps").join("res"),
+ ] {
+ std::fs::create_dir_all(&dest_dir).unwrap();
+ for file in files {
+ std::fs::copy(composer_res.join(file), dest_dir.join(file)).unwrap();
+ }
+ }
+
+ for file in files {
+ println!(
+ "cargo:rerun-if-changed={}",
+ composer_res.join(file).display()
+ );
+ }
+}
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(())