From cccb60f81f3b2c76a529adfa559fd1c273886601 Mon Sep 17 00:00:00 2001 From: Nathan Flurry Date: Mon, 22 Jul 2024 17:21:42 -0700 Subject: [PATCH] chore: add back cli --- Cargo.lock | 188 +++++++++++++++--- Cargo.toml | 2 +- rivet-cli/Cargo.toml | 12 ++ rivet-cli/src/commands/login.rs | 50 +++++ rivet-cli/src/commands/logout.rs | 20 ++ rivet-cli/src/commands/mod.rs | 26 +++ rivet-cli/src/commands/task.rs | 35 ++++ rivet-cli/src/main.rs | 19 ++ .../src/tasks/check_login_state.rs | 2 +- rivet-toolchain/src/tasks/unlink.rs | 2 - rivet-toolchain/src/util/task/mod.rs | 18 +- 11 files changed, 337 insertions(+), 37 deletions(-) create mode 100644 rivet-cli/Cargo.toml create mode 100644 rivet-cli/src/commands/login.rs create mode 100644 rivet-cli/src/commands/logout.rs create mode 100644 rivet-cli/src/commands/mod.rs create mode 100644 rivet-cli/src/commands/task.rs create mode 100644 rivet-cli/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 00949a4b..9455c7ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,12 +52,55 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + [[package]] name = "anstyle" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + [[package]] name = "anyhow" version = "1.0.75" @@ -111,7 +154,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.72", ] [[package]] @@ -122,7 +165,7 @@ checksum = "531b97fb4cd3dfdce92c35dedbfdc1f0b9d8091c8ca943d6dae340ef5012d514" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.72", ] [[package]] @@ -263,6 +306,52 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "clap" +version = "4.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim 0.11.1", +] + +[[package]] +name = "clap_derive" +version = "4.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.72", +] + +[[package]] +name = "clap_lex" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + [[package]] name = "combine" version = "4.6.6" @@ -388,8 +477,8 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", - "syn 2.0.39", + "strsim 0.10.0", + "syn 2.0.72", ] [[package]] @@ -400,7 +489,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.39", + "syn 2.0.72", ] [[package]] @@ -503,7 +592,7 @@ checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.72", ] [[package]] @@ -640,7 +729,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.72", ] [[package]] @@ -791,6 +880,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.3" @@ -1043,6 +1138,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itertools" version = "0.11.0" @@ -1402,7 +1503,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.72", ] [[package]] @@ -1606,18 +1707,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -1800,6 +1901,17 @@ dependencies = [ "uuid", ] +[[package]] +name = "rivet-cli" +version = "0.1.0" +dependencies = [ + "clap", + "global-error", + "rivet-toolchain", + "serde_json", + "tokio", +] + [[package]] name = "rivet-toolchain" version = "0.1.0" @@ -2097,29 +2209,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.193" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.72", ] [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", @@ -2163,7 +2275,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.72", ] [[package]] @@ -2222,6 +2334,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "strum" version = "0.24.1" @@ -2237,7 +2355,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "rustversion", @@ -2257,9 +2375,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -2319,7 +2437,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9ee618502f497abf593e1c5c9577f34775b111480009ffccd7ad70d23fcaba8" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro-error", "proc-macro2", "quote", @@ -2383,7 +2501,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.72", ] [[package]] @@ -2443,9 +2561,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.0" +version = "1.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df" dependencies = [ "backtrace", "bytes", @@ -2462,13 +2580,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.72", ] [[package]] @@ -2655,6 +2773,12 @@ dependencies = [ "serde", ] +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.6.1" @@ -2761,7 +2885,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.72", "wasm-bindgen-shared", ] @@ -2795,7 +2919,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/Cargo.toml b/Cargo.toml index 6c1fb10f..b6f1e2c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = [ +members = [ "rivet-cli", "rivet-toolchain", ] diff --git a/rivet-cli/Cargo.toml b/rivet-cli/Cargo.toml new file mode 100644 index 00000000..e2434b6a --- /dev/null +++ b/rivet-cli/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "rivet-cli" +version = "0.1.0" +edition = "2021" + +[dependencies] +clap = { version = "4.5.9", features = ["derive"] } +global-error = { git = "https://github.com/rivet-gg/rivet.git", rev = "22baf31efa3ffcdad65ecc72ce25425ab61b9c6f" } +toolchain = { version = "0.1.0", path = "../rivet-toolchain", package = "rivet-toolchain" } +tokio = { version = "1.38.1", features = ["full"] } +serde_json = "1.0.120" + diff --git a/rivet-cli/src/commands/login.rs b/rivet-cli/src/commands/login.rs new file mode 100644 index 00000000..650a6d73 --- /dev/null +++ b/rivet-cli/src/commands/login.rs @@ -0,0 +1,50 @@ +use clap::Parser; +use global_error::prelude::*; +use toolchain::{ + tasks::{check_login_state, start_device_link, wait_for_login, RunConfig}, + util::task::run_task, +}; + +#[derive(Parser)] +pub struct Opts { + #[clap(long, default_value = "https://api.rivet.gg")] + api_endpoint: String, +} + +impl Opts { + pub async fn execute(&self) -> GlobalResult<()> { + let (run_config, _temp_dir) = RunConfig::with_temp_dir()?; + + // Check if linked + let output = + run_task::(run_config.clone(), check_login_state::Input {}) + .await?; + if output.logged_in { + eprintln!("Already logged in. Sign out with `rivet unlink`."); + return Ok(()); + } + + // Start device link + let output = run_task::( + run_config.clone(), + start_device_link::Input { + api_endpoint: self.api_endpoint.clone(), + }, + ) + .await?; + eprintln!("{}", output.device_link_url); + + // Wait for finish + run_task::( + run_config.clone(), + wait_for_login::Input { + api_endpoint: self.api_endpoint.clone(), + device_link_token: output.device_link_token, + }, + ) + .await?; + eprintln!("Logged in"); + + Ok(()) + } +} diff --git a/rivet-cli/src/commands/logout.rs b/rivet-cli/src/commands/logout.rs new file mode 100644 index 00000000..02438e99 --- /dev/null +++ b/rivet-cli/src/commands/logout.rs @@ -0,0 +1,20 @@ +use clap::Parser; +use global_error::prelude::*; +use toolchain::{ + tasks::{unlink, RunConfig}, + util::task::run_task, +}; + +#[derive(Parser)] +pub struct Opts {} + +impl Opts { + pub async fn execute(&self) -> GlobalResult<()> { + let (run_config, _temp_dir) = RunConfig::with_temp_dir()?; + + run_task::(run_config.clone(), unlink::Input {}).await?; + eprintln!("Logged out"); + + Ok(()) + } +} diff --git a/rivet-cli/src/commands/mod.rs b/rivet-cli/src/commands/mod.rs new file mode 100644 index 00000000..6bd5ec5b --- /dev/null +++ b/rivet-cli/src/commands/mod.rs @@ -0,0 +1,26 @@ +pub mod login; +pub mod logout; +pub mod task; + +use clap::Parser; +use global_error::prelude::*; + +#[derive(Parser)] +pub enum SubCommand { + Login(login::Opts), + Task { + #[clap(subcommand)] + subcommand: task::SubCommand, + }, + Logout(logout::Opts), +} + +impl SubCommand { + pub async fn execute(&self) -> GlobalResult<()> { + match self { + SubCommand::Login(opts) => opts.execute().await, + SubCommand::Task { subcommand } => subcommand.execute().await, + SubCommand::Logout(opts) => opts.execute().await, + } + } +} diff --git a/rivet-cli/src/commands/task.rs b/rivet-cli/src/commands/task.rs new file mode 100644 index 00000000..fde7b84c --- /dev/null +++ b/rivet-cli/src/commands/task.rs @@ -0,0 +1,35 @@ +use clap::Parser; +use global_error::prelude::*; + +/// EXPERIMENTAL +#[derive(Parser)] +pub enum SubCommand { + Run(RunOpts), +} + +impl SubCommand { + pub async fn execute(&self) -> GlobalResult<()> { + match self { + SubCommand::Run(opts) => opts.execute().await, + } + } +} + +#[derive(Parser)] +pub struct RunOpts { + #[clap(long)] + run_config: String, + #[clap(long)] + name: String, + #[clap(long)] + input: String, +} + +impl RunOpts { + pub async fn execute(&self) -> GlobalResult<()> { + let run_config = serde_json::from_str(&self.run_config)?; + let output = toolchain::tasks::run_task_json(run_config, &self.name, &self.input).await; + println!("{output}"); + Ok(()) + } +} diff --git a/rivet-cli/src/main.rs b/rivet-cli/src/main.rs new file mode 100644 index 00000000..9368d47f --- /dev/null +++ b/rivet-cli/src/main.rs @@ -0,0 +1,19 @@ +pub mod commands; + +use clap::Parser; +use global_error::GlobalResult; + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] +struct Cli { + #[command(subcommand)] + command: commands::SubCommand, +} + +#[tokio::main] +async fn main() -> GlobalResult<()> { + let cli = Cli::parse(); + cli.command.execute().await?; + Ok(()) +} + diff --git a/rivet-toolchain/src/tasks/check_login_state.rs b/rivet-toolchain/src/tasks/check_login_state.rs index 3811a091..1d614081 100644 --- a/rivet-toolchain/src/tasks/check_login_state.rs +++ b/rivet-toolchain/src/tasks/check_login_state.rs @@ -8,7 +8,7 @@ pub struct Input {} #[derive(Serialize)] pub struct Output { - logged_in: bool, + pub logged_in: bool, } pub struct Task; diff --git a/rivet-toolchain/src/tasks/unlink.rs b/rivet-toolchain/src/tasks/unlink.rs index a8528876..dcb6368e 100644 --- a/rivet-toolchain/src/tasks/unlink.rs +++ b/rivet-toolchain/src/tasks/unlink.rs @@ -3,8 +3,6 @@ use serde::{Deserialize, Serialize}; use crate::{config, util::task::TaskCtx}; -// use crate::commands; - #[derive(Deserialize)] pub struct Input {} diff --git a/rivet-toolchain/src/util/task/mod.rs b/rivet-toolchain/src/util/task/mod.rs index af61b71b..81f30d79 100644 --- a/rivet-toolchain/src/util/task/mod.rs +++ b/rivet-toolchain/src/util/task/mod.rs @@ -4,6 +4,7 @@ mod log; use global_error::prelude::*; use serde::Deserialize; use std::path::Path; +use tempfile::TempDir; use tokio::{ fs::OpenOptions, sync::{broadcast, mpsc}, @@ -15,7 +16,7 @@ pub use ctx::TaskCtx; use crate::tasks::Task; -#[derive(Deserialize)] +#[derive(Deserialize, Clone)] pub struct RunConfig { /// Path to file that will abort this task if exists. pub abort_path: String, @@ -23,6 +24,21 @@ pub struct RunConfig { pub output_path: String, } +impl RunConfig { + /// Creates a new config with paths in a temp dir. + pub fn with_temp_dir() -> GlobalResult<(Self, TempDir)> { + let temp_dir = tempfile::tempdir()?; + + Ok(( + Self { + abort_path: temp_dir.path().join("abort").display().to_string(), + output_path: temp_dir.path().join("output").display().to_string(), + }, + temp_dir, + )) + } +} + /// Executes a future that can be aborted by touching a file. pub async fn run_task(run_config: RunConfig, input: T::Input) -> GlobalResult where