Skip to content

Commit

Permalink
added feature flag for not-cli; also, config to disable dialoguer p…
Browse files Browse the repository at this point in the history
…rompt;
  • Loading branch information
calvinrp committed May 6, 2024
1 parent 9cc53a6 commit 3eb6368
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 38 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ testresult = "0.3.0"
[features]
default = []
postgres = ["warg-server/postgres"]
not-cli = ["warg-client/not-cli"]

[workspace]
members = ["crates/server"]
Expand Down
5 changes: 3 additions & 2 deletions crates/client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ homepage = { workspace = true }
repository = { workspace = true}

[features]
default = []
default = ["dialoguer"]
native-tls-vendored = ["reqwest/native-tls-vendored"]
not-cli = []

[dependencies]
warg-crypto = { workspace = true }
Expand All @@ -24,7 +25,7 @@ clap = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tokio = { workspace = true }
dialoguer = { workspace = true }
dialoguer = { workspace = true, optional = true }
tokio-util = { workspace = true }
tempfile = { workspace = true }
reqwest = { workspace = true }
Expand Down
5 changes: 5 additions & 0 deletions crates/client/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ pub struct Config {
/// Auto accept registry hint or ask the user to confirm
#[serde(default)]
pub auto_accept_federation_hints: bool,

/// Disable dialoguer prompts.
#[serde(default)]
pub disable_dialoguer: bool,
}

impl Config {
Expand Down Expand Up @@ -202,6 +206,7 @@ impl Config {
keyring_auth: self.keyring_auth,
ignore_federation_hints: self.ignore_federation_hints,
auto_accept_federation_hints: self.auto_accept_federation_hints,
disable_dialoguer: self.disable_dialoguer,
};

serde_json::to_writer_pretty(
Expand Down
161 changes: 125 additions & 36 deletions crates/client/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
//! A client library for Warg component registries.
#![deny(missing_docs)]
use crate::storage::{PackageInfo, PublishEntry};
use crate::storage::PackageInfo;

#[cfg(not(feature = "not-cli"))]
use crate::storage::PublishEntry;

use anyhow::{anyhow, Context, Result};
use dialoguer::theme::ColorfulTheme;
use dialoguer::Confirm;

#[cfg(not(feature = "not-cli"))]
use dialoguer::{theme::ColorfulTheme, Confirm};

use indexmap::IndexMap;
use reqwest::{Body, IntoUrl};
use secrecy::Secret;
Expand Down Expand Up @@ -63,30 +69,40 @@ where
content: C,
namespace_map: N,
api: api::Client,
#[cfg(not(feature = "not-cli"))]
ignore_federation_hints: bool,
#[cfg(not(feature = "not-cli"))]
auto_accept_federation_hints: bool,
#[cfg(not(feature = "not-cli"))]
disable_dialoguer: bool,
}

impl<R: RegistryStorage, C: ContentStorage, N: NamespaceMapStorage> Client<R, C, N> {
/// Creates a new client for the given URL, registry storage, and
/// content storage.
#[allow(clippy::too_many_arguments)]
pub fn new(
url: impl IntoUrl,
registry: R,
content: C,
namespace_map: N,
auth_token: Option<Secret<String>>,
ignore_federation_hints: bool,
auto_accept_federation_hints: bool,
#[cfg(not(feature = "not-cli"))] ignore_federation_hints: bool,
#[cfg(not(feature = "not-cli"))] auto_accept_federation_hints: bool,
#[cfg(not(feature = "not-cli"))] disable_dialoguer: bool,
) -> ClientResult<Self> {
let api = api::Client::new(url, auth_token)?;
Ok(Self {
registry,
content,
namespace_map,
api,
#[cfg(not(feature = "not-cli"))]
ignore_federation_hints,
#[cfg(not(feature = "not-cli"))]
auto_accept_federation_hints,
#[cfg(not(feature = "not-cli"))]
disable_dialoguer,
})
}

Expand Down Expand Up @@ -331,13 +347,20 @@ impl<R: RegistryStorage, C: ContentStorage, N: NamespaceMapStorage> Client<R, C,
);
tracing::debug!("entries: {:?}", publish_info.entries);

#[cfg(not(feature = "not-cli"))]
let mut accepted_prompt_to_initialize = false;

let mut init_record_id: Option<RecordId> = None;

let (package, record) = loop {
let mut info = publish_info.clone();

#[cfg(not(feature = "not-cli"))]
let mut initializing = info.initializing();

#[cfg(feature = "not-cli")]
let initializing = info.initializing();

let package = match self.fetch_package(&info.name).await {
Ok(package) => {
if initializing {
Expand All @@ -356,37 +379,42 @@ impl<R: RegistryStorage, C: ContentStorage, N: NamespaceMapStorage> Client<R, C,
name,
has_auth_token,
}) => {
if !initializing {
let prompt = if has_auth_token {
format!(
"Package `{package_name}` was not found.
if !initializing && cfg!(feature = "not-cli") {
return Err(ClientError::MustInitializePackage {
name,
has_auth_token,
});
} else if !initializing {
#[cfg(not(feature = "not-cli"))]
{
if self.disable_dialoguer {
return Err(ClientError::MustInitializePackage {
name,
has_auth_token,
});
}

if accepted_prompt_to_initialize
|| Confirm::with_theme(&ColorfulTheme::default())
.with_prompt(format!(
"Package `{package_name}` was not found.
If it exists, you may not have access.
Attempt to create `{package_name}` and publish the release y/N\n",
package_name = &info.name,
)
} else {
format!(
"Package `{package_name}` was not found.
If it exists, you may not have access without logging in. Try: `warg login`
Attempt to create `{package_name}` and publish the release y/N\n",
package_name = &info.name,
)
};
if accepted_prompt_to_initialize
|| Confirm::with_theme(&ColorfulTheme::default())
.with_prompt(prompt)
.default(false)
.interact()
.unwrap()
{
info.entries.insert(0, PublishEntry::Init);
initializing = true;
accepted_prompt_to_initialize = true;
} else {
return Err(ClientError::MustInitializePackage {
name,
has_auth_token,
});
package_name = &info.name,
))
.default(false)
.interact()
.unwrap()
{
info.entries.insert(0, PublishEntry::Init);
initializing = true;
accepted_prompt_to_initialize = true;
} else {
return Err(ClientError::MustInitializePackage {
name,
has_auth_token,
});
}
}
}
PackageInfo::new(info.name.clone())
Expand Down Expand Up @@ -700,7 +728,13 @@ Attempt to create `{package_name}` and publish the release y/N\n",
}

// federated packages in other registries
let mut federated_packages: IndexMap<Option<RegistryDomain>, Vec<&mut PackageInfo>> =
#[cfg(not(feature = "not-cli"))]
let mut federated_packages: IndexMap<
Option<RegistryDomain>,
Vec<&mut PackageInfo>,
> = IndexMap::with_capacity(packages.len());
#[cfg(feature = "not-cli")]
let federated_packages: IndexMap<Option<RegistryDomain>, Vec<&mut PackageInfo>> =
IndexMap::with_capacity(packages.len());

// loop and fetch logs
Expand Down Expand Up @@ -745,10 +779,44 @@ Attempt to create `{package_name}` and publish the release y/N\n",
Err(ClientError::Api(err))
}
}

#[cfg(feature = "not-cli")]
api::ClientError::LogNotFoundWithHint(log_id, hint) => {
let name = packages.get(log_id).unwrap().name.clone();

match hint.to_str().ok().map(|s| s.split_once('=')) {
Some(Some((namespace, registry))) if packages.contains_key(log_id) => {
Err(ClientError::PackageDoesNotExistWithHintHeader {
name,
has_auth_token,
hint_namespace: namespace.to_string(),
hint_registry: registry.to_string(),
})
}
_ => Err(ClientError::PackageDoesNotExist {
name,
has_auth_token,
}),
}
}

#[cfg(not(feature = "not-cli"))]
api::ClientError::LogNotFoundWithHint(log_id, hint) => {
match hint.to_str().ok().map(|s| s.split_once('=')) {
Some(Some((namespace, registry)))
if !self.ignore_federation_hints
if self.disable_dialoguer && packages.contains_key(log_id) =>
{
let name = packages.get(log_id).unwrap().name.clone();
Err(ClientError::PackageDoesNotExistWithHintHeader {
name,
has_auth_token,
hint_namespace: namespace.to_string(),
hint_registry: registry.to_string(),
})
}
Some(Some((namespace, registry)))
if !self.disable_dialoguer
&& !self.ignore_federation_hints
&& packages.contains_key(log_id) =>
{
let package_name = &packages.get(log_id).unwrap().name;
Expand Down Expand Up @@ -1191,8 +1259,12 @@ impl FileSystemClient {
content,
namespace_map,
auth_token,
#[cfg(not(feature = "not-cli"))]
config.ignore_federation_hints,
#[cfg(not(feature = "not-cli"))]
config.auto_accept_federation_hints,
#[cfg(not(feature = "not-cli"))]
config.disable_dialoguer,
)?))
}

Expand All @@ -1219,8 +1291,12 @@ impl FileSystemClient {
FileSystemContentStorage::lock(content_dir)?,
FileSystemNamespaceMapStorage::new(namespace_map_path),
auth_token,
#[cfg(not(feature = "not-cli"))]
config.ignore_federation_hints,
#[cfg(not(feature = "not-cli"))]
config.auto_accept_federation_hints,
#[cfg(not(feature = "not-cli"))]
config.disable_dialoguer,
)
}
}
Expand Down Expand Up @@ -1315,6 +1391,19 @@ pub enum ClientError {
has_auth_token: bool,
},

/// The package does not exist with hint header.
#[error("package `{name}` does not exist but the registry suggests checking registry `{hint_registry}` for packages in namespace `{hint_namespace}`")]
PackageDoesNotExistWithHintHeader {
/// The missing package.
name: PackageName,
/// Client has authentication credentials.
has_auth_token: bool,
/// The hint namespace.
hint_namespace: String,
/// The hint registry.
hint_registry: String,
},

/// The package version does not exist.
#[error("version `{version}` of package `{name}` does not exist")]
PackageVersionDoesNotExist {
Expand Down
13 changes: 13 additions & 0 deletions src/bin/warg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,19 @@ pub async fn describe_client_error(e: &ClientError) -> Result<()> {
eprintln!("You may be required to login. Try: `warg login`");
}
}
ClientError::PackageDoesNotExistWithHintHeader {
name,
has_auth_token,
hint_namespace,
hint_registry,
} => {
eprintln!(
"Package `{name}` was not found or you do not have access.
The registry suggests using registry `{hint_registry}` for packages in namespace `{hint_namespace}`.");
if !has_auth_token {
eprintln!("You may be required to login. Try: `warg login`");
}
}
ClientError::PackageVersionDoesNotExist { name, version } => {
eprintln!("Package `{name}` version `{version}` was not found.")
}
Expand Down
1 change: 1 addition & 0 deletions src/commands/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ impl ConfigCommand {
keyring_auth: false,
ignore_federation_hints: self.ignore_federation_hints,
auto_accept_federation_hints: self.auto_accept_federation_hints,
disable_dialoguer: false,
};

config.write_to_file(&path)?;
Expand Down
1 change: 1 addition & 0 deletions tests/support/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ pub async fn spawn_server(
keyring_auth: false,
ignore_federation_hints: false,
auto_accept_federation_hints: false,
disable_dialoguer: true,
};

Ok((instance, config))
Expand Down

0 comments on commit 3eb6368

Please sign in to comment.