use super::*;
pub(super) async fn preflight(
target: &account::TargetSpec,
config: Option<&Config>,
flags: &FlagOverrides,
env: &HashMap<String, String>,
verbosity: i8,
) -> Result<std::result::Result<Preflight, ExitCode>> {
let settings = {
let resolved = if target.implicit {
account::synthetic_config().resolve("default", None, env, flags)
} else {
config
.expect("non-implicit target has config")
.resolve(&target.label, None, env, flags)
};
match resolved {
Ok(settings) => settings,
Err(err) => {
eprint_t!("error: {err}");
return Ok(Err(ExitCode::Config));
}
}
};
let token = match token::resolve_token(&target.label, &settings).await {
Ok(Some(token)) => token,
Ok(None) => {
eprint_t!(
"error: no token for account '{}'; pass --token, set SUNO_TOKEN or SUNO_TOKEN_COMMAND, or set token/token_command in config",
target.label
);
return Ok(Err(ExitCode::Config));
}
Err(err) => {
eprint_t!("error: {err}");
return Ok(Err(ExitCode::Config));
}
};
if settings.requires_ffmpeg() && version::ffmpeg_version().is_none() {
eprint_t!(
"error: ffmpeg is required for {} output{} but was not found on PATH; \
install ffmpeg or switch to mp3 format",
settings.format,
if settings.animated_covers && !settings.raw_animated_cover {
" and animated WebP covers"
} else if settings.animated_covers {
" and animated covers"
} else {
""
}
);
return Ok(Err(ExitCode::Config));
}
let http = ReqwestHttp::new().context("failed to build the HTTP client")?;
let dest = &target.dest;
let auth = ClerkAuth::new(&token);
if let Err(err) = auth.authenticate(&http).await {
return Ok(Err(failure::report_auth_failure(&target.label, &err)));
}
let account = auth.display_name().to_owned();
crate::cli::expiry::warn_token_expiry(&target.label, &auth, verbosity);
let Some(user_id) = auth.user_id() else {
eprint_t!(
"error: could not determine the authenticated account for '{}'. Refusing to run to protect the library.",
target.label
);
return Ok(Err(ExitCode::Auth));
};
let mut store = logs::load_graph(dest)?;
store.refresh_eligible_roots();
store.set_album_overrides(settings.album_overrides.clone());
let client = SunoClient::new(auth, TokioClock);
Ok(Ok(Preflight {
settings,
http,
client,
store,
user_id,
account,
}))
}