aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/command/base_config_command.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe/src/command/base_config_command.rs')
-rw-r--r--crates/shirabe/src/command/base_config_command.rs119
1 files changed, 119 insertions, 0 deletions
diff --git a/crates/shirabe/src/command/base_config_command.rs b/crates/shirabe/src/command/base_config_command.rs
index d000704..3d6e0da 100644
--- a/crates/shirabe/src/command/base_config_command.rs
+++ b/crates/shirabe/src/command/base_config_command.rs
@@ -1 +1,120 @@
//! ref: composer/src/Composer/Command/BaseConfigCommand.php
+
+use indexmap::IndexMap;
+use shirabe_php_shim::{touch, chmod, PhpMixed};
+use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
+use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
+use crate::command::base_command::BaseCommand;
+use crate::config::Config;
+use crate::config::json_config_source::JsonConfigSource;
+use crate::factory::Factory;
+use crate::json::json_file::JsonFile;
+use crate::util::platform::Platform;
+use crate::util::silencer::Silencer;
+
+#[derive(Debug)]
+pub struct BaseConfigCommand {
+ inner: BaseCommand,
+ pub(crate) config: Option<Config>,
+ pub(crate) config_file: Option<JsonFile>,
+ pub(crate) config_source: Option<JsonConfigSource>,
+}
+
+impl BaseConfigCommand {
+ pub fn initialize(
+ &mut self,
+ input: &dyn InputInterface,
+ output: &dyn OutputInterface,
+ ) -> anyhow::Result<()> {
+ self.inner.initialize(input, output)?;
+
+ if input.get_option("global").as_bool() && input.get_option("file").is_not_null() {
+ return Err(anyhow::anyhow!("--file and --global can not be combined"));
+ }
+
+ let io = self.inner.get_io();
+ self.config = Some(Factory::create_config(io)?);
+ let config = self.config.as_mut().unwrap();
+
+ // When using --global flag, set baseDir to home directory for correct absolute path resolution
+ if input.get_option("global").as_bool() {
+ let home = config.get("home").to_string();
+ config.set_base_dir(home);
+ }
+
+ let config_file = self.get_composer_config_file(input, config);
+
+ // Create global composer.json if invoked using `composer global [config-cmd]`
+ if (config_file == "composer.json" || config_file == "./composer.json")
+ && !std::path::Path::new(&config_file).exists()
+ && std::fs::canonicalize(Platform::get_cwd()).ok()
+ == std::fs::canonicalize(config.get("home").to_string()).ok()
+ {
+ std::fs::write(&config_file, "{\n}\n")?;
+ }
+
+ let config = self.config.as_ref().unwrap();
+ self.config_file = Some(JsonFile::new(config_file.clone(), None, Some(io)));
+ self.config_source = Some(JsonConfigSource::new(self.config_file.as_ref().unwrap()));
+
+ // Initialize the global file if it's not there, ignoring any warnings or notices
+ if input.get_option("global").as_bool() && !self.config_file.as_ref().unwrap().exists() {
+ let path = self.config_file.as_ref().unwrap().get_path().to_string();
+ touch(&path);
+ self.config_file.as_mut().unwrap().write(PhpMixed::Array({
+ let mut m = IndexMap::new();
+ m.insert("config".to_string(), Box::new(PhpMixed::Array(IndexMap::new())));
+ m
+ }))?;
+ let _ = Silencer::call(|| {
+ chmod(&path, 0o600);
+ Ok(())
+ });
+ }
+
+ if !self.config_file.as_ref().unwrap().exists() {
+ return Err(anyhow::anyhow!(
+ "File \"{}\" cannot be found in the current directory",
+ config_file
+ ));
+ }
+
+ Ok(())
+ }
+
+ /// Get the local composer.json, global config.json, or the file passed by the user
+ pub(crate) fn get_composer_config_file(
+ &self,
+ input: &dyn InputInterface,
+ config: &Config,
+ ) -> String {
+ if input.get_option("global").as_bool() {
+ format!("{}/config.json", config.get("home"))
+ } else {
+ input
+ .get_option("file")
+ .as_string_opt()
+ .map(|s| s.to_string())
+ .unwrap_or_else(|| Factory::get_composer_file())
+ }
+ }
+
+ /// Get the local auth.json or global auth.json, or if the user passed in a file to use,
+ /// the corresponding auth.json
+ pub(crate) fn get_auth_config_file(
+ &self,
+ input: &dyn InputInterface,
+ config: &Config,
+ ) -> String {
+ if input.get_option("global").as_bool() {
+ format!("{}/auth.json", config.get("home"))
+ } else {
+ let composer_config = self.get_composer_config_file(input, config);
+ let parent = std::path::Path::new(&composer_config)
+ .parent()
+ .map(|p| p.to_string_lossy().to_string())
+ .unwrap_or_default();
+ format!("{}/auth.json", parent)
+ }
+ }
+}