Base commandline interface

main
~erin 2023-04-02 23:17:57 -04:00
parent 1282848df3
commit a51d5808db
Signed by: erin
GPG Key ID: 9A8E308CEFA37A47
4 changed files with 311 additions and 80 deletions

200
Cargo.lock generated
View File

@ -2,6 +2,46 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "anstream"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-wincon",
"concolor-override",
"concolor-query",
"is-terminal",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2"
[[package]]
name = "anstyle-parse"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-wincon"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa"
dependencies = [
"anstyle",
"windows-sys",
]
[[package]]
name = "argon2"
version = "0.5.0"
@ -55,12 +95,75 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
[[package]]
name = "cc"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3"
dependencies = [
"clap_builder",
"clap_derive",
"once_cell",
]
[[package]]
name = "clap_builder"
version = "4.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "223163f58c9a40c3b0a43e1c4b50a9ce09f007ea2cb1ec258a687945b4b7929f"
dependencies = [
"anstream",
"anstyle",
"bitflags",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1"
[[package]]
name = "concolor-override"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f"
[[package]]
name = "concolor-query"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf"
dependencies = [
"windows-sys",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
@ -102,10 +205,32 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "errno"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0"
dependencies = [
"errno-dragonfly",
"libc",
"windows-sys",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "forge-client"
version = "0.1.0"
dependencies = [
"clap",
"paris",
"serde",
"serde_json",
@ -166,6 +291,12 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "hermit-abi"
version = "0.2.6"
@ -175,6 +306,12 @@ dependencies = [
"libc",
]
[[package]]
name = "hermit-abi"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
[[package]]
name = "idna"
version = "0.3.0"
@ -195,6 +332,29 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "io-lifetimes"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb"
dependencies = [
"hermit-abi 0.3.1",
"libc",
"windows-sys",
]
[[package]]
name = "is-terminal"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8"
dependencies = [
"hermit-abi 0.3.1",
"io-lifetimes",
"rustix",
"windows-sys",
]
[[package]]
name = "itoa"
version = "1.0.6"
@ -207,6 +367,12 @@ version = "0.2.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
[[package]]
name = "linux-raw-sys"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f"
[[package]]
name = "lock_api"
version = "0.4.9"
@ -250,10 +416,16 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
dependencies = [
"hermit-abi",
"hermit-abi 0.2.6",
"libc",
]
[[package]]
name = "once_cell"
version = "1.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
[[package]]
name = "outref"
version = "0.5.1"
@ -386,6 +558,20 @@ dependencies = [
"thiserror",
]
[[package]]
name = "rustix"
version = "0.37.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d097081ed288dfe45699b72f5b5d648e5f15d64d900c7080273baa20c16a6849"
dependencies = [
"bitflags",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "ryu"
version = "1.0.13"
@ -463,6 +649,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "subtle"
version = "2.4.1"
@ -618,6 +810,12 @@ dependencies = [
"serde",
]
[[package]]
name = "utf8parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "uuid"
version = "1.3.0"

View File

@ -10,31 +10,6 @@ Authentication will use *Argon2id* to hash and verify passwords.
Actually building stuff is a **WIP**.
## Client
Fully **WIP**. Right now it just sends test data.
Fully **WIP**.
Eventually, everything will be specified via command arguments, using [clap](https://lib.rs/crates/clap) for parsing.
```
Usage: forge-client [OPTIONS] [COMMAND]
Options:
-V, --version Print version info and exit
-H, --host Host IP to connect to (default 127.0.0.1)
-p, --port Host port to connect to (default 9134)
--json <FILE> Recieve information in JSON format (or read build command from JSON file)
--auth <PASSWD> Password for authentication
--profile Whether to profile the build
--prexec <CMD> Command(s) to run before building
--repo <URL> Remote git repository to clone from
--base <NAME> Basename of the git repo (used to cd into)
--build [cargo|make] Build system to use
--subcommand [run|build|install] Cargo/Make subcommand to use
--features <FEATURES> Comma-separated cargo features
--tag [release|debug] Optional cargo flag (default debug)
Command:
send Send a new build request
status Get status of a build request
fetch Fetch the binary result of a build request
```
Sends data to the server specified via commandline options.

View File

@ -10,3 +10,4 @@ serde.workspace = true
url.workspace = true
uuid.workspace = true
paris.workspace = true
clap = { version = "4.2.1", features = ["derive"]}

View File

@ -1,3 +1,4 @@
use clap::{Args, Parser, Subcommand, ValueEnum};
use paris::{error, info, success};
use serde::{Deserialize, Serialize};
use std::error::Error;
@ -7,61 +8,103 @@ use tokio::net::TcpStream;
use url::Url;
use uuid::Uuid;
#[derive(Serialize, Deserialize, Debug)]
#[derive(Debug, Parser)]
#[command(name = "forge-server")]
#[command(about = "A simple remote build system", long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Debug, Subcommand)]
enum Commands {
/// Send a new build request
#[command(arg_required_else_help = true)]
Send {
/// Password for authentication
#[arg(long, value_name = "PASSWD")]
auth: Option<String>,
/// Whether to profile the build
#[arg(long, default_value_t = false)]
profile: bool,
/// Command(s) to run before building
#[arg(long, value_name = "CMD")]
prexec: Option<String>,
/// Remote git repository to clone from
#[arg(long, value_name = "URL")]
repo: String,
/// Build system to use
#[arg(long,require_equals = true, num_args = 0..=1, default_value_t = BuildSystem::Cargo,default_missing_value = "cargo")]
build: BuildSystem,
/// Cargo/Make subcommand to use
#[arg(long, require_equals = true, num_args = 0..=1, default_value_t = BuildSubcommand::Build, default_missing_value = "build")]
subcommand: BuildSubcommand,
/// Comma-separated cargo features
#[arg(long, value_name = "FEATURES")]
features: Option<Vec<String>>,
/// Optional cargo flag
#[arg(long, require_equals = true, num_args = 0..=1, default_value_t = Tag::Debug, default_missing_value = "debug")]
tag: Tag,
},
}
#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq, ValueEnum)]
enum BuildSystem {
Cargo,
Make,
Custom(String),
}
impl fmt::Display for BuildSystem {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
BuildSystem::Cargo => write!(f, "cargo"),
BuildSystem::Make => write!(f, "make"),
BuildSystem::Custom(s) => write!(f, "{}", s),
}
impl std::fmt::Display for BuildSystem {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.to_possible_value()
.expect("no values are skipped")
.get_name()
.fmt(f)
}
}
#[derive(Serialize, Deserialize, Debug)]
enum Subcommand {
#[derive(Serialize, Deserialize, ValueEnum, Copy, Clone, Debug, PartialEq, Eq)]
enum BuildSubcommand {
Run,
Build,
Install,
Custom(String),
}
impl fmt::Display for Subcommand {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Subcommand::Run => write!(f, "run"),
Subcommand::Build => write!(f, "build"),
Subcommand::Install => write!(f, "install"),
Subcommand::Custom(s) => write!(f, "{}", s),
}
impl std::fmt::Display for BuildSubcommand {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.to_possible_value()
.expect("no values are skipped")
.get_name()
.fmt(f)
}
}
#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, ValueEnum, Copy, Clone, Debug, PartialEq, Eq)]
enum Tag {
Release,
Debug,
}
impl fmt::Display for Tag {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Tag::Release => write!(f, "--release"),
Tag::Debug => write!(f, "--debug"),
}
impl std::fmt::Display for Tag {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.to_possible_value()
.expect("no values are skipped")
.get_name()
.fmt(f)
}
}
#[derive(Serialize, Deserialize)]
struct Command {
build_system: BuildSystem,
subcommand: Subcommand,
subcommand: BuildSubcommand,
features: Option<Vec<String>>,
tag: Tag,
}
@ -79,32 +122,46 @@ struct Message {
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// Connect to a peer
let mut stream = TcpStream::connect("127.0.0.1:9134").await?;
success!("Connected to: <green>127.0.0.1:9134<//>");
let args = Cli::parse();
match args.command {
Commands::Send {
auth,
repo,
profile,
prexec,
build,
subcommand,
features,
tag,
} => {
// Connect to a peer
let mut stream = TcpStream::connect("127.0.0.1:9134").await?;
success!("Connected to: <green>127.0.0.1:9134<//>");
let test_command = Command {
build_system: BuildSystem::Cargo,
subcommand: Subcommand::Build,
features: Some(vec!["one".to_string(), "two".to_string()]),
tag: Tag::Debug,
};
let test_message = Message {
authentication: Some("test123".to_string()),
uuid: Uuid::new_v4(),
pre_exec: None,
profile: false,
command: test_command,
repository: Url::parse("https://lib.rs/crates/serde_json").unwrap(),
basename: "serde_json".to_string(),
};
let test_command = Command {
build_system: build,
subcommand,
features,
tag,
};
let test_message = Message {
authentication: auth,
uuid: Uuid::new_v4(),
pre_exec: prexec,
profile,
command: test_command,
repository: Url::parse(&repo).unwrap(),
basename: "serde_json".to_string(),
};
let j = serde_json::to_string(&test_message)?;
stream.write_all(&j.as_bytes()).await?;
info!(
"Sent JSON:\n<bright-white>{}<//>",
serde_json::to_string_pretty(&test_message)?
);
let j = serde_json::to_string(&test_message)?;
stream.write_all(&j.as_bytes()).await?;
info!(
"Sent JSON:\n<bright-white>{}<//>",
serde_json::to_string_pretty(&test_message)?
);
}
}
Ok(())
}