From ebcf7d53c8d18cd72c17d24862b1e5a8e0e1bb40 Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Tue, 18 Jul 2023 08:39:49 +0000 Subject: [PATCH] fix: tilde in path not expanded Fixes an issue that when providing option values using `=`, the tilde does not get expanded by the shell and thus causes file not found errors. --- Cargo.lock | 37 +++++++++++++++++++ Cargo.toml | 1 + src/main.rs | 1 + src/path.rs | 28 ++++++++++++++ src/subcommands/account/deploy.rs | 6 ++- src/subcommands/account/oz/init.rs | 6 ++- src/subcommands/class_hash.rs | 7 +++- src/subcommands/declare.rs | 7 +++- src/subcommands/deploy.rs | 2 + src/subcommands/invoke.rs | 2 + src/subcommands/signer/keystore/from_key.rs | 7 +++- src/subcommands/signer/keystore/inspect.rs | 7 +++- .../signer/keystore/inspect_private.rs | 7 +++- src/subcommands/signer/keystore/new.rs | 7 +++- 14 files changed, 117 insertions(+), 8 deletions(-) create mode 100644 src/path.rs diff --git a/Cargo.lock b/Cargo.lock index 2278128..ff95fff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1006,6 +1006,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + [[package]] name = "dirs-next" version = "2.0.0" @@ -1016,6 +1025,18 @@ dependencies = [ "dirs-sys-next", ] +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys", +] + [[package]] name = "dirs-sys-next" version = "0.1.2" @@ -1909,6 +1930,12 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "parity-scale-codec" version = "3.6.1" @@ -2609,6 +2636,15 @@ dependencies = [ "keccak", ] +[[package]] +name = "shellexpand" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b" +dependencies = [ + "dirs", +] + [[package]] name = "siphasher" version = "0.3.10" @@ -2691,6 +2727,7 @@ dependencies = [ "serde", "serde_json", "serde_with", + "shellexpand", "starknet", "thiserror", "tokio", diff --git a/Cargo.toml b/Cargo.toml index b6a53bd..c52fad0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ rpassword = "7.2.0" serde = { version = "1.0.164", features = ["derive"] } serde_json = { version = "1.0.99", features = ["preserve_order"] } serde_with = "2.3.3" +shellexpand = "3.1.0" starknet = "0.5.0" thiserror = "1.0.40" tokio = { version = "1.28.2", default-features = false, features = ["macros", "rt-multi-thread"] } diff --git a/src/main.rs b/src/main.rs index 366fc62..0c72eb9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,7 @@ mod compiler; mod decode; mod fee; mod network; +mod path; mod provider; mod signer; mod subcommands; diff --git a/src/path.rs b/src/path.rs new file mode 100644 index 0000000..696031f --- /dev/null +++ b/src/path.rs @@ -0,0 +1,28 @@ +use std::path::PathBuf; + +use clap::{builder::TypedValueParser, error::ErrorKind, Arg, Command, Error}; + +#[derive(Clone)] +pub struct ExpandedPathbufParser; + +impl TypedValueParser for ExpandedPathbufParser { + type Value = PathBuf; + + fn parse_ref( + &self, + cmd: &Command, + _arg: Option<&Arg>, + value: &std::ffi::OsStr, + ) -> Result { + if value.is_empty() { + Err(cmd.clone().error(ErrorKind::InvalidValue, "empty path")) + } else { + let path = match value.to_str() { + Some(value) => PathBuf::from(shellexpand::tilde(value).into_owned()), + None => PathBuf::from(value), + }; + + Ok(path) + } + } +} diff --git a/src/subcommands/account/deploy.rs b/src/subcommands/account/deploy.rs index 086bd01..5779932 100644 --- a/src/subcommands/account/deploy.rs +++ b/src/subcommands/account/deploy.rs @@ -13,6 +13,7 @@ use starknet::{ use crate::{ account::{AccountConfig, AccountVariant, DeployedStatus, DeploymentStatus}, fee::{FeeArgs, FeeSetting}, + path::ExpandedPathbufParser, signer::SignerArgs, utils::watch_tx, verbosity::VerbosityArgs, @@ -27,7 +28,10 @@ pub struct Deploy { signer: SignerArgs, #[clap(flatten)] fee: FeeArgs, - #[clap(help = "Path to the account config file")] + #[clap( + value_parser = ExpandedPathbufParser, + help = "Path to the account config file" + )] file: PathBuf, #[clap(flatten)] verbosity: VerbosityArgs, diff --git a/src/subcommands/account/oz/init.rs b/src/subcommands/account/oz/init.rs index b550dbf..d2d881a 100644 --- a/src/subcommands/account/oz/init.rs +++ b/src/subcommands/account/oz/init.rs @@ -11,6 +11,7 @@ use starknet::{ use crate::{ account::{AccountConfig, AccountVariant, DeploymentStatus, OzAccountConfig, UndeployedStatus}, + path::ExpandedPathbufParser, signer::SignerArgs, }; @@ -29,7 +30,10 @@ pub struct Init { help = "Overwrite the account config file if it already exists" )] force: bool, - #[clap(help = "Path to save the account config file")] + #[clap( + value_parser = ExpandedPathbufParser, + help = "Path to save the account config file" + )] output: PathBuf, } diff --git a/src/subcommands/class_hash.rs b/src/subcommands/class_hash.rs index 1659dce..54afd33 100644 --- a/src/subcommands/class_hash.rs +++ b/src/subcommands/class_hash.rs @@ -4,9 +4,14 @@ use anyhow::Result; use clap::Parser; use starknet::core::types::contract::{legacy::LegacyContractClass, CompiledClass, SierraClass}; +use crate::path::ExpandedPathbufParser; + #[derive(Debug, Parser)] pub struct ClassHash { - #[clap(help = "Path to contract artifact file")] + #[clap( + value_parser = ExpandedPathbufParser, + help = "Path to contract artifact file" + )] file: PathBuf, } diff --git a/src/subcommands/declare.rs b/src/subcommands/declare.rs index af842bc..3717c3b 100644 --- a/src/subcommands/declare.rs +++ b/src/subcommands/declare.rs @@ -16,6 +16,7 @@ use crate::{ account::{AccountConfig, DeploymentStatus}, casm::{CasmArgs, CasmHashSource}, fee::{FeeArgs, FeeSetting}, + path::ExpandedPathbufParser, signer::SignerArgs, utils::watch_tx, verbosity::VerbosityArgs, @@ -33,6 +34,7 @@ pub struct Declare { #[clap( long, env = "STARKNET_ACCOUNT", + value_parser = ExpandedPathbufParser, help = "Path to account config JSON file" )] account: PathBuf, @@ -40,7 +42,10 @@ pub struct Declare { fee: FeeArgs, #[clap(long, help = "Wait for the transaction to confirm")] watch: bool, - #[clap(help = "Path to contract artifact file")] + #[clap( + value_parser = ExpandedPathbufParser, + help = "Path to contract artifact file" + )] file: PathBuf, #[clap(flatten)] verbosity: VerbosityArgs, diff --git a/src/subcommands/deploy.rs b/src/subcommands/deploy.rs index de04727..ace6491 100644 --- a/src/subcommands/deploy.rs +++ b/src/subcommands/deploy.rs @@ -19,6 +19,7 @@ use crate::{ address_book::AddressBookResolver, decode::FeltDecoder, fee::{FeeArgs, FeeSetting}, + path::ExpandedPathbufParser, signer::SignerArgs, utils::watch_tx, verbosity::VerbosityArgs, @@ -44,6 +45,7 @@ pub struct Deploy { #[clap( long, env = "STARKNET_ACCOUNT", + value_parser = ExpandedPathbufParser, help = "Path to account config JSON file" )] account: PathBuf, diff --git a/src/subcommands/invoke.rs b/src/subcommands/invoke.rs index 712f2eb..e73d94e 100644 --- a/src/subcommands/invoke.rs +++ b/src/subcommands/invoke.rs @@ -17,6 +17,7 @@ use crate::{ address_book::AddressBookResolver, decode::FeltDecoder, fee::{FeeArgs, FeeSetting}, + path::ExpandedPathbufParser, signer::SignerArgs, utils::watch_tx, verbosity::VerbosityArgs, @@ -32,6 +33,7 @@ pub struct Invoke { #[clap( long, env = "STARKNET_ACCOUNT", + value_parser = ExpandedPathbufParser, help = "Path to account config JSON file" )] account: PathBuf, diff --git a/src/subcommands/signer/keystore/from_key.rs b/src/subcommands/signer/keystore/from_key.rs index 7b5518b..761cd4e 100644 --- a/src/subcommands/signer/keystore/from_key.rs +++ b/src/subcommands/signer/keystore/from_key.rs @@ -5,6 +5,8 @@ use clap::Parser; use colored::Colorize; use starknet::{core::types::FieldElement, signers::SigningKey}; +use crate::path::ExpandedPathbufParser; + #[derive(Debug, Parser)] pub struct FromKey { #[clap(long, help = "Overwrite the file if it already exists")] @@ -16,7 +18,10 @@ pub struct FromKey { help = "Supply password from command line option instead of prompt" )] password: Option, - #[clap(help = "Path to save the JSON keystore")] + #[clap( + value_parser = ExpandedPathbufParser, + help = "Path to save the JSON keystore" + )] file: PathBuf, } diff --git a/src/subcommands/signer/keystore/inspect.rs b/src/subcommands/signer/keystore/inspect.rs index 7a64552..8fda460 100644 --- a/src/subcommands/signer/keystore/inspect.rs +++ b/src/subcommands/signer/keystore/inspect.rs @@ -5,6 +5,8 @@ use clap::Parser; use colored::Colorize; use starknet::signers::SigningKey; +use crate::path::ExpandedPathbufParser; + #[derive(Debug, Parser)] pub struct Inspect { #[clap( @@ -14,7 +16,10 @@ pub struct Inspect { password: Option, #[clap(long, help = "Print the public key only")] raw: bool, - #[clap(help = "Path to the JSON keystore")] + #[clap( + value_parser = ExpandedPathbufParser, + help = "Path to the JSON keystore" + )] file: PathBuf, } diff --git a/src/subcommands/signer/keystore/inspect_private.rs b/src/subcommands/signer/keystore/inspect_private.rs index f4f8598..c5ce7c9 100644 --- a/src/subcommands/signer/keystore/inspect_private.rs +++ b/src/subcommands/signer/keystore/inspect_private.rs @@ -5,6 +5,8 @@ use clap::Parser; use colored::Colorize; use starknet::signers::SigningKey; +use crate::path::ExpandedPathbufParser; + #[derive(Debug, Parser)] pub struct InspectPrivate { #[clap( @@ -14,7 +16,10 @@ pub struct InspectPrivate { password: Option, #[clap(long, help = "Print the private key only")] raw: bool, - #[clap(help = "Path to the JSON keystore")] + #[clap( + value_parser = ExpandedPathbufParser, + help = "Path to the JSON keystore" + )] file: PathBuf, } diff --git a/src/subcommands/signer/keystore/new.rs b/src/subcommands/signer/keystore/new.rs index 435440d..1e1dfde 100644 --- a/src/subcommands/signer/keystore/new.rs +++ b/src/subcommands/signer/keystore/new.rs @@ -5,6 +5,8 @@ use clap::Parser; use colored::Colorize; use starknet::signers::SigningKey; +use crate::path::ExpandedPathbufParser; + #[derive(Debug, Parser)] pub struct New { #[clap( @@ -14,7 +16,10 @@ pub struct New { password: Option, #[clap(long, help = "Overwrite the file if it already exists")] force: bool, - #[clap(help = "Path to save the JSON keystore")] + #[clap( + value_parser = ExpandedPathbufParser, + help = "Path to save the JSON keystore" + )] file: PathBuf, }