Skip to content

Commit

Permalink
improved login and config subcommands (#288)
Browse files Browse the repository at this point in the history
- `warg config` now lets you modify your current settings instead of
forcing an overwrite
- `warg login --registry` asks you if you want to set that registry as
your home / default registry
- Clearer messaging on the CLI on what registry is being used
  • Loading branch information
calvinrp committed May 15, 2024
1 parent de8152b commit a87e0e4
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 115 deletions.
116 changes: 81 additions & 35 deletions src/commands/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ pub struct ConfigCommand {

/// Ignore federation hints.
#[clap(long)]
pub ignore_federation_hints: bool,
pub ignore_federation_hints: Option<bool>,

/// Auto accept federation hints.
#[clap(long)]
pub auto_accept_federation_hints: bool,
pub auto_accept_federation_hints: Option<bool>,

/// Overwrite the existing configuration file.
#[clap(long)]
Expand Down Expand Up @@ -53,66 +53,112 @@ impl ConfigCommand {
.path
.map(Ok)
.unwrap_or_else(Config::default_config_path)?;
let cwd = std::env::current_dir().context("failed to determine current directory")?;

if !self.overwrite && path.is_file() {
bail!(
"configuration file `{path}` already exists; use `--overwrite` to overwrite it",
if self.overwrite && path.is_file() {
println!(
"Overwriting configuration file: `{path}`",
path = path.display()
);
}

let home_url = &self
.common
.registry
.clone()
.map(RegistryUrl::new)
.transpose()?
.map(|u| u.to_string());
let mut changing_home_registry = false;

let config = if self.overwrite {
let home_url = self
.common
.registry
.as_ref()
.map(RegistryUrl::new)
.transpose()?
.map(|u| u.to_string())
.ok_or(anyhow::anyhow!(
"Please configure your home registry: warg config --registry <registry-url>"
))?;

changing_home_registry = true;

Config {
home_url: Some(home_url),
registries_dir: self.registries_dir.map(|p| cwd.join(p)),
content_dir: self.content_dir.map(|p| cwd.join(p)),
namespace_map_path: self.namespace_path.map(|p| cwd.join(p)),
keys: self.common.read_config()?.keys,
keyring_auth: false,
ignore_federation_hints: self.ignore_federation_hints.unwrap_or_default(),
auto_accept_federation_hints: self.auto_accept_federation_hints.unwrap_or_default(),
disable_interactive: false,
keyring_backend: self.keyring_backend,
}
} else {
let mut config = self.common.read_config()?;
if self.common.registry.is_some() {
let home_url = self
.common
.registry
.as_ref()
.map(RegistryUrl::new)
.transpose()?
.map(|u| u.to_string());
if home_url != config.home_url {
changing_home_registry = true;
config.home_url = home_url;
}
}
if config.home_url.is_none() {
bail!("Please configure your home registry: warg config --registry <registry-url>");
}
if self.registries_dir.is_some() {
config.registries_dir = self.registries_dir.map(|p| cwd.join(p));
}
if self.content_dir.is_some() {
config.content_dir = self.content_dir.map(|p| cwd.join(p));
}
if self.namespace_path.is_some() {
config.namespace_map_path = self.namespace_path.map(|p| cwd.join(p));
}
if let Some(ignore_federation_hints) = self.ignore_federation_hints {
config.ignore_federation_hints = ignore_federation_hints;
}
if let Some(auto_accept_federation_hints) = self.auto_accept_federation_hints {
config.auto_accept_federation_hints = auto_accept_federation_hints;
}
if self.keyring_backend.is_some() {
config.keyring_backend = self.keyring_backend;
}

config
};

// The paths specified on the command line are relative to the current
// directory.
//
// `write_to_file` will handle normalizing the paths to be relative to
// the configuration file's directory.
let cwd = std::env::current_dir().context("failed to determine current directory")?;
let config = Config {
home_url: home_url.clone(),
registries_dir: self.registries_dir.map(|p| cwd.join(p)),
content_dir: self.content_dir.map(|p| cwd.join(p)),
namespace_map_path: self.namespace_path.map(|p| cwd.join(p)),
keys: self.common.read_config()?.keys,
keyring_auth: false,
ignore_federation_hints: self.ignore_federation_hints,
auto_accept_federation_hints: self.auto_accept_federation_hints,
disable_interactive: false,
keyring_backend: self.keyring_backend.clone(),
};

config.write_to_file(&path)?;

// reset when changing home registry
let client = self.common.create_client(&config)?;
client.reset_namespaces().await?;
client.reset_registry().await?;
if changing_home_registry {
let client = self.common.create_client(&config)?;
client.reset_namespaces().await?;
client.reset_registry().await?;
}

println!(
"created warg configuration file `{path}`",
path = path.display(),
);
println!("Set configuration file `{path}`", path = path.display(),);

Ok(())
}
}

fn keyring_backend_parser(s: &str) -> Result<String, String> {
pub(crate) fn keyring_backend_parser(s: &str) -> Result<String, String> {
if Keyring::SUPPORTED_BACKENDS.contains(&s) {
Ok(s.to_string())
} else {
Err(format!("`{s}` is not a supported keyring backend."))
}
}

fn keyring_backend_help() -> clap::builder::StyledStr {
pub(crate) fn keyring_backend_help() -> clap::builder::StyledStr {
use std::fmt::Write as _;

let mut help = String::new();
Expand Down
5 changes: 2 additions & 3 deletions src/commands/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl DownloadCommand {
let config = self.common.read_config()?;
let client = self.common.create_client(&config)?;

println!("downloading package `{name}`...", name = self.name);
println!("Downloading `{name}`...", name = self.name);

// if user specifies exact verion, then set the `VersionReq` to exact match
let version = match &self.version {
Expand All @@ -47,8 +47,7 @@ impl DownloadCommand {
})?;

println!(
"Downloaded version {version} of package `{name}` ({digest}) to local cache",
name = self.name,
"Downloaded version: {version}\nDigest: {digest}\n",
version = download.version,
digest = download.digest
);
Expand Down
33 changes: 26 additions & 7 deletions src/commands/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::CommonOptions;
use anyhow::Result;
use clap::{ArgAction, Args};
use warg_client::{
keyring::Keyring,
storage::{ContentStorage, NamespaceMapStorage, PackageInfo, RegistryStorage},
Client,
};
Expand Down Expand Up @@ -30,13 +31,29 @@ impl InfoCommand {
let config = self.common.read_config()?;
let client = self.common.create_client(&config)?;

println!("registry: {url}", url = client.url());
println!("\npackages in client storage:");
println!("\nRegistry: {url}", url = client.url());
if config.keyring_auth
&& Keyring::from_config(&config)?
.get_auth_token(client.url())?
.is_some()
{
println!(
"(Using credentials{keyring_backend})",
keyring_backend = if let Some(keyring_backend) = &config.keyring_backend {
format!(" stored in `{keyring_backend}` keyring backend")
} else {
"".to_string()
}
);
} else {
println!("(Not logged in)");
}
println!("\nPackages in client storage:");
match self.package {
Some(package) => {
let info = client.package(&package).await?;
if let Some(registry) = client.get_warg_registry(package.namespace()).await? {
println!("registry: {registry}");
println!("Registry: {registry}");
}
Self::print_package_info(&info);
}
Expand All @@ -47,24 +64,26 @@ impl InfoCommand {
.await?
.iter()
.for_each(|(registry, packages)| {
println!("registry: {registry}");
println!("\nRegistry: {registry}");
packages.iter().for_each(Self::print_package_info);
});
}
}

if self.namespaces {
println!("\nnamespace mappings in client storage");
println!("\nNamespace mappings in client storage");
Self::print_namespace_map(&client).await?;
return Ok(());
}

println!();

Ok(())
}

fn print_package_info(info: &PackageInfo) {
println!(" name: {name}", name = info.name);
println!(" versions:");
println!(" Name: {name}", name = info.name);
println!(" Versions:");
info.state.releases().for_each(|r| {
if let Some(content) = r.content() {
Self::print_release(&r.version, content);
Expand Down

0 comments on commit a87e0e4

Please sign in to comment.