diff --git a/Cargo.lock b/Cargo.lock index 9c6cf68..608c1c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -137,12 +137,58 @@ dependencies = [ "ansi_term", "atty", "bitflags", - "strsim", + "strsim 0.8.0", "textwrap", "unicode-width", "vec_map", ] +[[package]] +name = "clap" +version = "4.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ef582e2c00a63a0c0aa1fb4a4870781c4f5729f51196d3537fa7c1c1992eaa3" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "clap_lex", + "once_cell", + "strsim 0.10.0", + "termcolor", +] + +[[package]] +name = "clap_complete" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11cba7abac9b56dfe2f035098cdb3a43946f276e6db83b72c4e692343f9aab9a" +dependencies = [ + "clap 4.0.16", +] + +[[package]] +name = "clap_derive" +version = "4.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c42f169caba89a7d512b5418b09864543eeb4d497416c917d7137863bd2076ad" +dependencies = [ + "heck 0.4.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -182,7 +228,7 @@ checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" dependencies = [ "atty", "cast", - "clap", + "clap 2.34.0", "criterion-plot", "csv", "itertools", @@ -525,6 +571,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -934,9 +986,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.10.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" [[package]] name = "oorandom" @@ -993,6 +1045,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "os_str_bytes" +version = "6.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" + [[package]] name = "parking_lot" version = "0.11.2" @@ -1151,11 +1209,11 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] @@ -1457,13 +1515,19 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "structopt" version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" dependencies = [ - "clap", + "clap 2.34.0", "lazy_static", "structopt-derive", ] @@ -1474,7 +1538,7 @@ version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ - "heck", + "heck 0.3.3", "proc-macro-error", "proc-macro2", "quote", @@ -1553,6 +1617,16 @@ dependencies = [ "tungstenite", ] +[[package]] +name = "syndicate-tools" +version = "0.1.0" +dependencies = [ + "clap 4.0.16", + "clap_complete", + "preserves", + "syndicate", +] + [[package]] name = "tempfile" version = "3.3.0" @@ -1567,6 +1641,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -1816,6 +1899,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + [[package]] name = "unicode-normalization" version = "0.1.19" diff --git a/Cargo.toml b/Cargo.toml index 42ba38a..dff4a2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "syndicate", "syndicate-macros", "syndicate-server", + "syndicate-tools", ] # [patch.crates-io] diff --git a/syndicate-tools/Cargo.toml b/syndicate-tools/Cargo.toml new file mode 100644 index 0000000..ea5bb91 --- /dev/null +++ b/syndicate-tools/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "syndicate-tools" +version = "0.1.0" +authors = ["Tony Garnock-Jones "] +edition = "2018" + +description = "Syndicate command-line utilities." +homepage = "https://syndicate-lang.org/" +repository = "https://git.syndicate-lang.org/syndicate-lang/syndicate-rs" +license = "Apache-2.0" + +[dependencies] +preserves = "^2" +syndicate = { path = "../syndicate", version = "^0.23.0"} + +clap = { version = "^4.0", features = ["derive"] } +clap_complete = "^4.0" diff --git a/syndicate-tools/src/bin/syndicate-macaroon.rs b/syndicate-tools/src/bin/syndicate-macaroon.rs new file mode 100644 index 0000000..b5a714b --- /dev/null +++ b/syndicate-tools/src/bin/syndicate-macaroon.rs @@ -0,0 +1,101 @@ +use std::io; + +use clap::arg; +use clap::value_parser; +use clap::ArgGroup; +use clap::Command; +use clap::Id; +use clap_complete::{generate, Shell}; +use preserves::hex::HexParser; +use preserves::value::NoEmbeddedDomainCodec; +use preserves::value::ViaCodec; +use preserves::value::TextWriter; +use syndicate::language; +use syndicate::preserves_schema::Codec; + +// #[derive(Subcommand, Clone, Debug)] +// enum Key { +// KeyPhrase { +// text: String, +// }, +// KeyHex { +// hex: String, +// }, +// } + +// #[derive(Subcommand, Clone, Debug)] +// enum Mode { +// Completions { +// #[arg(value_enum)] +// dialect: Shell, +// }, +// Mint { +// oid: String, +// #[command(subcommand)] +// key: Key, +// }, +// } + +// #[derive(Parser, Clone, Debug)] +// #[command(version)] +// struct CommandLine { +// #[command(subcommand)] +// command: Mode, +// } + +fn cli() -> Command { + Command::new("syndicate-macaroon") + .subcommand_required(true) + .subcommand( + Command::new("mint") + .about("Mint a fresh macaroon") + .arg(arg!(--oid "Preserves value to use as SturdyRef OID").required(true)) + .arg(arg!(--phrase "Key phrase")) + .arg(arg!(--hex "Key bytes, encoded as hex")) + .group( + ArgGroup::new("key") + .args(["phrase", "hex"]) + .required(true))) + .subcommand( + Command::new("completions") + .about("Generate shell completions for this command") + .arg(arg!( "Shell dialect to generate").value_parser(value_parser!(Shell)))) +} + +fn main() -> io::Result<()> { + let args = cli().get_matches(); + + if let Some(args) = args.subcommand_matches("completions") { + let shell = args.get_one::("shell").unwrap().clone(); + let mut cmd = cli(); + let name = cmd.get_name().to_string(); + generate(shell, &mut cmd, name, &mut io::stdout()); + } + + if let Some(args) = args.subcommand_matches("mint") { + let oid_str = args.get_one::("oid").unwrap(); + let oid = match preserves::value::text::from_str(&oid_str, ViaCodec::new(NoEmbeddedDomainCodec)) { + Ok(oid) => oid, + Err(e) => { + eprintln!("Could not parse oid: {}", e); + std::process::exit(1); + } + }; + let key = match args.get_one::("key").unwrap().as_str() { + "hex" => { + let hex = args.get_one::("hex").unwrap(); + HexParser::Liberal.decode(hex).expect("hex encoded sturdyref") + } + "phrase" => { + let text = args.get_one::("phrase").unwrap(); + text.as_bytes().to_owned() + } + &_ => unreachable!(), + }; + let m = syndicate::sturdy::SturdyRef::mint(oid, &key); + println!("{}", TextWriter::encode(&mut NoEmbeddedDomainCodec, + &language().unparse(&m))?); + } + + Ok(()) +}