cli: prompt for missing CurseForge credentials on add
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Id0bbdc9ed62bc8b9582ccb89158e53786a6a6964
This commit is contained in:
parent
d2d6b7c421
commit
e7c6da593d
2 changed files with 101 additions and 3 deletions
|
|
@ -1,16 +1,99 @@
|
|||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, time::Duration};
|
||||
|
||||
use crate::{
|
||||
error::{MultiError, PakkerError, Result},
|
||||
model::{Config, LockFile, Project, credentials::ResolvedCredentials},
|
||||
http,
|
||||
model::{
|
||||
Config,
|
||||
LockFile,
|
||||
PakkerCredentialsFile,
|
||||
Project,
|
||||
Target,
|
||||
credentials::ResolvedCredentials,
|
||||
set_keyring_secret,
|
||||
},
|
||||
platform::create_platform,
|
||||
resolver::DependencyResolver,
|
||||
ui_utils::prompt_curseforge_api_key,
|
||||
};
|
||||
|
||||
fn get_loaders(lockfile: &LockFile) -> Vec<String> {
|
||||
lockfile.loaders.keys().cloned().collect()
|
||||
}
|
||||
|
||||
fn needs_curseforge(target: Option<&Target>) -> bool {
|
||||
matches!(
|
||||
target,
|
||||
Some(Target::CurseForge) | Some(Target::Multiplatform)
|
||||
)
|
||||
}
|
||||
|
||||
async fn ensure_curseforge_credentials() -> Result<bool> {
|
||||
let creds = ResolvedCredentials::load();
|
||||
if creds.curseforge_api_key().is_some() {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
if let Some(key) = prompt_curseforge_api_key(false)? {
|
||||
// Verify the key before saving
|
||||
let client = http::create_http_client();
|
||||
let response = client
|
||||
.get("https://api.curseforge.com/v1/mods/238222")
|
||||
.header("x-api-key", &key)
|
||||
.timeout(Duration::from_secs(10))
|
||||
.send()
|
||||
.await;
|
||||
|
||||
match response {
|
||||
Ok(resp) if resp.status().is_success() => {
|
||||
let mut creds_file = PakkerCredentialsFile::load()?;
|
||||
set_keyring_secret("curseforge_api_key", &key)?;
|
||||
creds_file.curseforge_api_key = Some(key.clone());
|
||||
creds_file.save()?;
|
||||
println!("CurseForge API key verified and saved.");
|
||||
Ok(true)
|
||||
},
|
||||
Ok(resp) => {
|
||||
println!(
|
||||
"Warning: CurseForge API key verification failed (HTTP {}).",
|
||||
resp.status()
|
||||
);
|
||||
if crate::ui_utils::prompt_yes_no(
|
||||
"Save this key anyway?",
|
||||
false,
|
||||
false,
|
||||
)? {
|
||||
let mut creds_file = PakkerCredentialsFile::load()?;
|
||||
set_keyring_secret("curseforge_api_key", &key)?;
|
||||
creds_file.curseforge_api_key = Some(key);
|
||||
creds_file.save()?;
|
||||
Ok(true)
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
println!("Warning: Could not verify CurseForge API key: {e}");
|
||||
if crate::ui_utils::prompt_yes_no(
|
||||
"Save this key anyway?",
|
||||
false,
|
||||
false,
|
||||
)? {
|
||||
let mut creds_file = PakkerCredentialsFile::load()?;
|
||||
set_keyring_secret("curseforge_api_key", &key)?;
|
||||
creds_file.curseforge_api_key = Some(key);
|
||||
creds_file.save()?;
|
||||
Ok(true)
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
},
|
||||
}
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_all_platforms()
|
||||
-> HashMap<String, Box<dyn crate::platform::PlatformClient>> {
|
||||
let mut platforms = HashMap::new();
|
||||
|
|
@ -166,6 +249,11 @@ pub async fn execute(
|
|||
|
||||
let mut lockfile = LockFile::load_with_validation(lockfile_dir, false)?;
|
||||
|
||||
// Prompt for missing CurseForge credentials when needed
|
||||
if needs_curseforge(lockfile.target.as_ref()) && !skip_prompts {
|
||||
let _ = ensure_curseforge_credentials().await;
|
||||
}
|
||||
|
||||
// Load config if available
|
||||
let _config = Config::load(config_dir).ok();
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use crate::{
|
|||
},
|
||||
platform::create_platform,
|
||||
resolver::DependencyResolver,
|
||||
ui_utils::prompt_curseforge_api_key,
|
||||
};
|
||||
|
||||
/// Parse a common project argument (slug or ID with optional file ID)
|
||||
|
|
@ -100,7 +101,16 @@ pub async fn execute(
|
|||
log::info!("Fetching from CurseForge: {cf_input}");
|
||||
let (input, file_id) = parse_common_arg(&cf_input);
|
||||
|
||||
let cf_api_key = std::env::var("CURSEFORGE_API_KEY").ok();
|
||||
let credentials = ResolvedCredentials::load();
|
||||
let mut cf_api_key = credentials.curseforge_api_key().map(String::from);
|
||||
|
||||
// Prompt for missing CurseForge credentials
|
||||
if cf_api_key.is_none() && !yes {
|
||||
if let Some(key) = prompt_curseforge_api_key(false)? {
|
||||
cf_api_key = Some(key);
|
||||
}
|
||||
}
|
||||
|
||||
let platform = create_platform("curseforge", cf_api_key)?;
|
||||
|
||||
let mut project = platform
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue