diff --git a/crates/wasm-pkg-common/src/config.rs b/crates/wasm-pkg-common/src/config.rs index 05e55c9..9bc8bd3 100644 --- a/crates/wasm-pkg-common/src/config.rs +++ b/crates/wasm-pkg-common/src/config.rs @@ -1,7 +1,7 @@ use std::{ collections::{hash_map::Entry, HashMap}, io::ErrorKind, - path::Path, + path::{Path, PathBuf}, }; use serde::{Deserialize, Serialize}; @@ -102,13 +102,18 @@ impl Config { Ok(config) } + /// Returns the default global config file location + pub fn global_config_path() -> Option { + dirs::config_dir().map(|path| path.join("wasm-pkg").join("config.toml")) + } + /// Reads config from the default global config file location pub async fn read_global_config() -> Result, Error> { - let Some(config_dir) = dirs::config_dir() else { - return Ok(None); + let path = match Config::global_config_path() { + Some(path) => path, + None => return Ok(None), }; - let path = config_dir.join("wasm-pkg").join("config.toml"); - let contents = match tokio::fs::read_to_string(path).await { + let contents = match tokio::fs::read_to_string(&path).await { Ok(contents) => contents, Err(err) if err.kind() == ErrorKind::NotFound => return Ok(None), Err(err) => return Err(Error::ConfigFileIoError(err)), diff --git a/crates/wkg/src/main.rs b/crates/wkg/src/main.rs index d86ed84..028ae7f 100644 --- a/crates/wkg/src/main.rs +++ b/crates/wkg/src/main.rs @@ -10,6 +10,7 @@ use wasm_pkg_client::{ Client, PublishOpts, }; use wasm_pkg_common::{ + self, config::{Config, RegistryMapping}, package::PackageSpec, registry::Registry, @@ -83,6 +84,8 @@ impl Common { #[derive(Subcommand, Debug)] #[allow(clippy::large_enum_variant)] enum Commands { + /// Set registry configuration + Config(ConfigArgs), /// Download a package from a registry Get(GetArgs), /// Publish a package to a registry @@ -95,6 +98,53 @@ enum Commands { Wit(WitCommands), } +#[derive(Args, Debug)] +struct ConfigArgs { + /// The default registry domain to use. Overrides configuration file(s). + #[arg(long = "default", value_name = "DEFAULT")] + default: Option, + + #[command(flatten)] + common: Common, +} + +impl ConfigArgs { + pub async fn run(self) -> anyhow::Result<()> { + // use config path provided, otherwise global config path + let path = if let Some(path) = self.common.config { + path + } else { + Config::global_config_path() + .ok_or(anyhow::anyhow!("global config path not available"))? + }; + + // read file or use default config (not empty config) + let mut config = match tokio::fs::read_to_string(&path).await { + Ok(contents) => Config::from_toml(&contents)?, + Err(err) if err.kind() == std::io::ErrorKind::NotFound => Config::default(), + Err(err) => return Err(anyhow::anyhow!("error reading config file: {0}", err)), + }; + + if let Some(default) = self.default { + // set default registry + config.set_default_registry(Some(default)); + + // write config file + config.to_file(&path).await?; + println!("Updated config file: {path}", path = path.display()); + } + + // print config + if let Some(registry) = config.default_registry() { + println!("Default registry: {}", registry); + } else { + println!("Default registry is not set"); + } + + Ok(()) + } +} + #[derive(Args, Debug)] struct GetArgs { /// Output path. If this ends with a '/', a filename based on the package @@ -312,6 +362,7 @@ async fn main() -> anyhow::Result<()> { let cli = Cli::parse(); match cli.command { + Commands::Config(args) => args.run().await, Commands::Get(args) => args.run().await, Commands::Publish(args) => args.run().await, Commands::Oci(args) => args.run().await,