kinda wanna structure my plan out
This commit is contained in:
6 files changed
+241
-18
No files matched your search
@@ -6,11 +6,17 @@ csa show <acc> -> verbose account <acc>
|
|||||||
csa swap -- codex resume -> csa swap auth to the best account, then execvpe
|
csa swap -- codex resume -> csa swap auth to the best account, then execvpe
|
||||||
csa swap <acc> -- codex logout -> csa swap to that acount, then execvpe
|
csa swap <acc> -- codex logout -> csa swap to that acount, then execvpe
|
||||||
|
|
||||||
optional features
|
// important feature
|
||||||
|
csa refresh (--all --expired OR <acc name>)
|
||||||
|
|
||||||
csa login
|
// account:
|
||||||
csa logout
|
csa account show (--all, --expired, <name>) default current
|
||||||
csa refresh
|
csa account rename
|
||||||
|
csa accound add
|
||||||
|
csa account refresh
|
||||||
|
|
||||||
|
csa login <account>
|
||||||
|
csa logout <account> --DO NOT Support --all, DO support --expired ONLY with confirmation
|
||||||
|
|
||||||
logout and refresh have official bindings in codex-login (logout with revoke, refresh_token)
|
logout and refresh have official bindings in codex-login (logout with revoke, refresh_token)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
//! this deals with authentication. validate, refresh, and quota check.
|
||||||
+222
@@ -0,0 +1,222 @@
|
|||||||
|
#[derive(clap::Parser, Debug)]
|
||||||
|
#[clap(
|
||||||
|
name = "csa",
|
||||||
|
version,
|
||||||
|
about = "A CLI tool to manage multiple Codex accounts"
|
||||||
|
)]
|
||||||
|
pub struct Cli {
|
||||||
|
#[clap(subcommand)]
|
||||||
|
command: Commands,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(clap::Subcommand, Debug)]
|
||||||
|
pub enum Commands {
|
||||||
|
Show(ShowCommand),
|
||||||
|
Add(AddCommand),
|
||||||
|
Swap(SwapCommand),
|
||||||
|
Account(AccountCommand),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, clap::Parser)]
|
||||||
|
pub struct ShowCommand {
|
||||||
|
/// specify to show the account.
|
||||||
|
pub acc: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `csa add --use --name myacc` or `csa add myacc --use` would add an account with nickname "myacc" and switch to it right away.
|
||||||
|
#[derive(Clone, Debug, clap::Parser)]
|
||||||
|
pub struct AddCommand {
|
||||||
|
/// use the account right away after adding, instead of just adding to the store.
|
||||||
|
#[clap(long = "use", short = 'u')]
|
||||||
|
use_rn: bool,
|
||||||
|
/// use to specify a nickname for the account. If not specified, will be the email or something else identifiable.
|
||||||
|
/// highly recommend.
|
||||||
|
pub name: Option<String>,
|
||||||
|
}
|
||||||
|
/// `csa swap acc1` would swap to acc1 if it exists. Else error out. `csa swap` would swap to the most capable account, which is determined by the internal logic of csa, and is usually the best valid account with the best availability.
|
||||||
|
///
|
||||||
|
/// to use something right after add/swap, use your favourite shell feature, the semicolon `;`.
|
||||||
|
// that looks like an emoji yo (`;`) wth
|
||||||
|
#[derive(Clone, Debug, clap::Parser)]
|
||||||
|
pub struct SwapCommand {
|
||||||
|
/// specify to swap to the account, instead of best effort swap to the most capable account.
|
||||||
|
pub acc: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, clap::Parser)]
|
||||||
|
pub struct AccountCommand {
|
||||||
|
#[clap(subcommand)]
|
||||||
|
subcommand: AccountSubCommand,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, clap::Subcommand)]
|
||||||
|
pub enum AccountSubCommand {
|
||||||
|
Refresh {
|
||||||
|
/// specify to refresh the account. Else refresh all accounts.
|
||||||
|
// this and AccountCommand.account at the same time is an error.
|
||||||
|
// chat how do i enforce above rule?
|
||||||
|
acc: Option<String>,
|
||||||
|
/// specify to only refresh the account if it's expired. Else refresh anyway.
|
||||||
|
expired: bool,
|
||||||
|
},
|
||||||
|
// also logout
|
||||||
|
Remove {
|
||||||
|
/// specify to remove the account
|
||||||
|
// do NOT support remove all accounts.
|
||||||
|
acc: String,
|
||||||
|
},
|
||||||
|
Rename {
|
||||||
|
/// specify to rename the account
|
||||||
|
acc: String,
|
||||||
|
/// the new name for the account
|
||||||
|
new_name: String,
|
||||||
|
},
|
||||||
|
// same thing as Show above
|
||||||
|
Show {
|
||||||
|
/// specify to show the account. Else show all accounts.
|
||||||
|
acc: Option<String>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use clap::Parser;
|
||||||
|
#[test]
|
||||||
|
fn show() {
|
||||||
|
let cli = Cli::try_parse_from(["test", "show"]).expect("csa show");
|
||||||
|
println!("{cli:#?}");
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn show_me() {
|
||||||
|
let cli = Cli::try_parse_from(["test", "show", "me"]).expect("csa show me");
|
||||||
|
println!("{cli:#?}");
|
||||||
|
assert!(
|
||||||
|
matches!(cli.command, Commands::Show(ShowCommand { acc: Some(acc) }) if acc == "me")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn add() {
|
||||||
|
let cli = Cli::try_parse_from(["test", "add"]).expect("csa add");
|
||||||
|
println!("{cli:#?}");
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn add_use() {
|
||||||
|
let cli = Cli::try_parse_from(["test", "add", "--use"]).expect("csa add --use");
|
||||||
|
println!("{cli:#?}");
|
||||||
|
assert!(matches!(
|
||||||
|
cli.command,
|
||||||
|
Commands::Add(AddCommand {
|
||||||
|
use_rn: true,
|
||||||
|
name: None,
|
||||||
|
})
|
||||||
|
));
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn add_use_name() {
|
||||||
|
let cli = Cli::try_parse_from(["test", "add", "--use", "--name", "myacc"])
|
||||||
|
.expect("csa add --use --name myacc");
|
||||||
|
println!("{cli:#?}");
|
||||||
|
assert!(
|
||||||
|
matches!(cli.command, Commands::Add(AddCommand { use_rn: true, name: Some(name) }) if name == "myacc")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn add_name() {
|
||||||
|
let cli =
|
||||||
|
Cli::try_parse_from(["test", "add", "--name", "myacc"]).expect("csa add --name myacc");
|
||||||
|
println!("{cli:#?}");
|
||||||
|
assert!(
|
||||||
|
matches!(cli.command, Commands::Add(AddCommand { use_rn: false, name: Some(name) }) if name == "myacc")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn swap() {
|
||||||
|
let cli = Cli::try_parse_from(["test", "swap"]).expect("csa swap");
|
||||||
|
println!("{cli:#?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn swap_acc() {
|
||||||
|
let cli = Cli::try_parse_from(["test", "swap", "acc1"]).expect("csa swap acc1");
|
||||||
|
println!("{cli:#?}");
|
||||||
|
assert!(
|
||||||
|
matches!(cli.command, Commands::Swap(SwapCommand { acc: Some(acc) }) if acc == "acc1")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn refresh() {
|
||||||
|
let cli = Cli::try_parse_from(["test", "refresh"]).expect("csa refresh");
|
||||||
|
println!("{cli:#?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn refresh_acc() {
|
||||||
|
let cli = Cli::try_parse_from(["test", "refresh", "--acc", "acc1"])
|
||||||
|
.expect("csa refresh --acc acc1");
|
||||||
|
println!("{cli:#?}");
|
||||||
|
assert!(
|
||||||
|
matches!(cli.command, Commands::Account(AccountCommand { subcommand: AccountSubCommand::Refresh { acc: Some(acc), expired }, .. }) if acc == "acc1" && !expired)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn refresh_acc_expired() {
|
||||||
|
let cli = Cli::try_parse_from(["test", "refresh", "--acc", "acc1", "--expired"])
|
||||||
|
.expect("csa refresh --acc acc1 --expired");
|
||||||
|
println!("{cli:#?}");
|
||||||
|
assert!(
|
||||||
|
matches!(cli.command, Commands::Account(AccountCommand { subcommand: AccountSubCommand::Refresh { acc: Some(acc), expired }, .. }) if acc == "acc1" && expired)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn refresh_expired() {
|
||||||
|
let cli =
|
||||||
|
Cli::try_parse_from(["test", "refresh", "--expired"]).expect("csa refresh --expired");
|
||||||
|
println!("{cli:#?}");
|
||||||
|
assert!(
|
||||||
|
matches!(cli.command, Commands::Account(AccountCommand { subcommand: AccountSubCommand::Refresh { acc: None, expired }, .. }) if expired)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn remove() {
|
||||||
|
let cli = Cli::try_parse_from(["test", "remove", "--acc", "acc1"])
|
||||||
|
.expect("csa remove --acc acc1");
|
||||||
|
println!("{cli:#?}");
|
||||||
|
assert!(
|
||||||
|
matches!(cli.command, Commands::Account(AccountCommand { subcommand: AccountSubCommand::Remove { acc }, .. }) if acc == "acc1")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn remove_no_acc() {
|
||||||
|
let cli = Cli::try_parse_from(["test", "remove"]).expect("csa remove");
|
||||||
|
println!("{cli:#?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rename() {
|
||||||
|
let cli = Cli::try_parse_from(["test", "rename", "acc1", "acc_new"])
|
||||||
|
.expect("csa rename acc1 acc_new");
|
||||||
|
println!("{cli:#?}");
|
||||||
|
assert!(
|
||||||
|
matches!(cli.command, Commands::Account(AccountCommand { subcommand: AccountSubCommand::Rename { acc, new_name }, .. }) if acc == "acc1" && new_name == "acc_new")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn rename_no_args() {
|
||||||
|
let cli = Cli::try_parse_from(["test", "rename"]).expect("csa rename");
|
||||||
|
println!("{cli:#?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn rename_no_new_name() {
|
||||||
|
let cli = Cli::try_parse_from(["test", "rename", "acc1"]).expect("csa rename acc1");
|
||||||
|
println!("{cli:#?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-14
@@ -1,14 +1,4 @@
|
|||||||
pub fn add(left: u64, right: u64) -> u64 {
|
pub mod cli;
|
||||||
left + right
|
pub mod store;
|
||||||
}
|
pub mod util;
|
||||||
|
pub mod auth;
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_works() {
|
|
||||||
let result = add(2, 2);
|
|
||||||
assert_eq!(result, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
//! deals with storage of accounts.
|
||||||
|
//! updates, pull out, standard crud... all here.
|
||||||
|
//! 0 logic to do with the actual accounts, just storage and retrieval.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
//! whatever looks like an general utility goes here.
|
||||||
Reference in new issue
Block a user