Skip to content

Commit a87e0e4

Browse files
authored
improved login and config subcommands (#288)
- `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
1 parent de8152b commit a87e0e4

File tree

5 files changed

+190
-115
lines changed

5 files changed

+190
-115
lines changed

src/commands/config.rs

Lines changed: 81 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ pub struct ConfigCommand {
2121

2222
/// Ignore federation hints.
2323
#[clap(long)]
24-
pub ignore_federation_hints: bool,
24+
pub ignore_federation_hints: Option<bool>,
2525

2626
/// Auto accept federation hints.
2727
#[clap(long)]
28-
pub auto_accept_federation_hints: bool,
28+
pub auto_accept_federation_hints: Option<bool>,
2929

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

57-
if !self.overwrite && path.is_file() {
58-
bail!(
59-
"configuration file `{path}` already exists; use `--overwrite` to overwrite it",
58+
if self.overwrite && path.is_file() {
59+
println!(
60+
"Overwriting configuration file: `{path}`",
6061
path = path.display()
6162
);
6263
}
6364

64-
let home_url = &self
65-
.common
66-
.registry
67-
.clone()
68-
.map(RegistryUrl::new)
69-
.transpose()?
70-
.map(|u| u.to_string());
65+
let mut changing_home_registry = false;
66+
67+
let config = if self.overwrite {
68+
let home_url = self
69+
.common
70+
.registry
71+
.as_ref()
72+
.map(RegistryUrl::new)
73+
.transpose()?
74+
.map(|u| u.to_string())
75+
.ok_or(anyhow::anyhow!(
76+
"Please configure your home registry: warg config --registry <registry-url>"
77+
))?;
78+
79+
changing_home_registry = true;
80+
81+
Config {
82+
home_url: Some(home_url),
83+
registries_dir: self.registries_dir.map(|p| cwd.join(p)),
84+
content_dir: self.content_dir.map(|p| cwd.join(p)),
85+
namespace_map_path: self.namespace_path.map(|p| cwd.join(p)),
86+
keys: self.common.read_config()?.keys,
87+
keyring_auth: false,
88+
ignore_federation_hints: self.ignore_federation_hints.unwrap_or_default(),
89+
auto_accept_federation_hints: self.auto_accept_federation_hints.unwrap_or_default(),
90+
disable_interactive: false,
91+
keyring_backend: self.keyring_backend,
92+
}
93+
} else {
94+
let mut config = self.common.read_config()?;
95+
if self.common.registry.is_some() {
96+
let home_url = self
97+
.common
98+
.registry
99+
.as_ref()
100+
.map(RegistryUrl::new)
101+
.transpose()?
102+
.map(|u| u.to_string());
103+
if home_url != config.home_url {
104+
changing_home_registry = true;
105+
config.home_url = home_url;
106+
}
107+
}
108+
if config.home_url.is_none() {
109+
bail!("Please configure your home registry: warg config --registry <registry-url>");
110+
}
111+
if self.registries_dir.is_some() {
112+
config.registries_dir = self.registries_dir.map(|p| cwd.join(p));
113+
}
114+
if self.content_dir.is_some() {
115+
config.content_dir = self.content_dir.map(|p| cwd.join(p));
116+
}
117+
if self.namespace_path.is_some() {
118+
config.namespace_map_path = self.namespace_path.map(|p| cwd.join(p));
119+
}
120+
if let Some(ignore_federation_hints) = self.ignore_federation_hints {
121+
config.ignore_federation_hints = ignore_federation_hints;
122+
}
123+
if let Some(auto_accept_federation_hints) = self.auto_accept_federation_hints {
124+
config.auto_accept_federation_hints = auto_accept_federation_hints;
125+
}
126+
if self.keyring_backend.is_some() {
127+
config.keyring_backend = self.keyring_backend;
128+
}
129+
130+
config
131+
};
71132

72133
// The paths specified on the command line are relative to the current
73134
// directory.
74135
//
75136
// `write_to_file` will handle normalizing the paths to be relative to
76137
// the configuration file's directory.
77-
let cwd = std::env::current_dir().context("failed to determine current directory")?;
78-
let config = Config {
79-
home_url: home_url.clone(),
80-
registries_dir: self.registries_dir.map(|p| cwd.join(p)),
81-
content_dir: self.content_dir.map(|p| cwd.join(p)),
82-
namespace_map_path: self.namespace_path.map(|p| cwd.join(p)),
83-
keys: self.common.read_config()?.keys,
84-
keyring_auth: false,
85-
ignore_federation_hints: self.ignore_federation_hints,
86-
auto_accept_federation_hints: self.auto_accept_federation_hints,
87-
disable_interactive: false,
88-
keyring_backend: self.keyring_backend.clone(),
89-
};
90-
91138
config.write_to_file(&path)?;
92139

93140
// reset when changing home registry
94-
let client = self.common.create_client(&config)?;
95-
client.reset_namespaces().await?;
96-
client.reset_registry().await?;
141+
if changing_home_registry {
142+
let client = self.common.create_client(&config)?;
143+
client.reset_namespaces().await?;
144+
client.reset_registry().await?;
145+
}
97146

98-
println!(
99-
"created warg configuration file `{path}`",
100-
path = path.display(),
101-
);
147+
println!("Set configuration file `{path}`", path = path.display(),);
102148

103149
Ok(())
104150
}
105151
}
106152

107-
fn keyring_backend_parser(s: &str) -> Result<String, String> {
153+
pub(crate) fn keyring_backend_parser(s: &str) -> Result<String, String> {
108154
if Keyring::SUPPORTED_BACKENDS.contains(&s) {
109155
Ok(s.to_string())
110156
} else {
111157
Err(format!("`{s}` is not a supported keyring backend."))
112158
}
113159
}
114160

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

118164
let mut help = String::new();

src/commands/download.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ impl DownloadCommand {
3030
let config = self.common.read_config()?;
3131
let client = self.common.create_client(&config)?;
3232

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

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

4949
println!(
50-
"Downloaded version {version} of package `{name}` ({digest}) to local cache",
51-
name = self.name,
50+
"Downloaded version: {version}\nDigest: {digest}\n",
5251
version = download.version,
5352
digest = download.digest
5453
);

src/commands/info.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use super::CommonOptions;
22
use anyhow::Result;
33
use clap::{ArgAction, Args};
44
use warg_client::{
5+
keyring::Keyring,
56
storage::{ContentStorage, NamespaceMapStorage, PackageInfo, RegistryStorage},
67
Client,
78
};
@@ -30,13 +31,29 @@ impl InfoCommand {
3031
let config = self.common.read_config()?;
3132
let client = self.common.create_client(&config)?;
3233

33-
println!("registry: {url}", url = client.url());
34-
println!("\npackages in client storage:");
34+
println!("\nRegistry: {url}", url = client.url());
35+
if config.keyring_auth
36+
&& Keyring::from_config(&config)?
37+
.get_auth_token(client.url())?
38+
.is_some()
39+
{
40+
println!(
41+
"(Using credentials{keyring_backend})",
42+
keyring_backend = if let Some(keyring_backend) = &config.keyring_backend {
43+
format!(" stored in `{keyring_backend}` keyring backend")
44+
} else {
45+
"".to_string()
46+
}
47+
);
48+
} else {
49+
println!("(Not logged in)");
50+
}
51+
println!("\nPackages in client storage:");
3552
match self.package {
3653
Some(package) => {
3754
let info = client.package(&package).await?;
3855
if let Some(registry) = client.get_warg_registry(package.namespace()).await? {
39-
println!("registry: {registry}");
56+
println!("Registry: {registry}");
4057
}
4158
Self::print_package_info(&info);
4259
}
@@ -47,24 +64,26 @@ impl InfoCommand {
4764
.await?
4865
.iter()
4966
.for_each(|(registry, packages)| {
50-
println!("registry: {registry}");
67+
println!("\nRegistry: {registry}");
5168
packages.iter().for_each(Self::print_package_info);
5269
});
5370
}
5471
}
5572

5673
if self.namespaces {
57-
println!("\nnamespace mappings in client storage");
74+
println!("\nNamespace mappings in client storage");
5875
Self::print_namespace_map(&client).await?;
5976
return Ok(());
6077
}
6178

79+
println!();
80+
6281
Ok(())
6382
}
6483

6584
fn print_package_info(info: &PackageInfo) {
66-
println!(" name: {name}", name = info.name);
67-
println!(" versions:");
85+
println!(" Name: {name}", name = info.name);
86+
println!(" Versions:");
6887
info.state.releases().for_each(|r| {
6988
if let Some(content) = r.content() {
7089
Self::print_release(&r.version, content);

0 commit comments

Comments
 (0)