-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cli): setup skeleton for quartz tool (#105)
Co-authored-by: Thane Thomson <[email protected]>
- Loading branch information
1 parent
a23ae1e
commit 2afbe50
Showing
13 changed files
with
332 additions
and
1 deletion.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
[package] | ||
name = "quartz" | ||
version.workspace = true | ||
authors.workspace = true | ||
edition.workspace = true | ||
rust-version.workspace = true | ||
license.workspace = true | ||
repository.workspace = true | ||
keywords = ["blockchain", "cosmos", "tendermint", "cycles", "quartz"] | ||
readme = "README.md" | ||
|
||
[dependencies] | ||
clap.workspace = true | ||
color-eyre.workspace = true | ||
displaydoc.workspace = true | ||
serde.workspace = true | ||
serde_json.workspace = true | ||
thiserror.workspace = true | ||
tracing.workspace = true | ||
tracing-subscriber = { workspace = true, features = ["env-filter"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# quartz CLI | ||
|
||
A CLI tool to manage Quartz applications. The `quartz` CLI tool is designed to streamline the development and deployment | ||
process of Quartz applications. | ||
|
||
It provides helpful information about each command and its options. To get a list of all available subcommands and their | ||
descriptions, use the `--help` flag: | ||
|
||
```shell | ||
$ quartz --help | ||
|
||
Quartz 0.1.0 | ||
A CLI tool to manage Quartz applications | ||
|
||
USAGE: | ||
quartz [SUBCOMMAND] | ||
|
||
OPTIONS: | ||
-h, --help Print help information | ||
-V, --version Print version information | ||
|
||
SUBCOMMANDS: | ||
init Create base Quartz app directory from template | ||
build Build the contract and enclave binaries | ||
enclave Enclave subcommads to configure Gramine, build, sign, and start the enclave binary | ||
contract Contract subcommads to build, deploy the WASM binary to the blockchain and call instantiate | ||
handshake Run the handshake between the contract and enclave | ||
``` | ||
|
||
## Installation | ||
|
||
To install Quartz, ensure you have Rust and Cargo installed. Then run: | ||
|
||
```shell | ||
cargo install quartz | ||
``` | ||
|
||
## Usage of subcommands | ||
|
||
### Init | ||
|
||
Initialize a new Quartz app directory structure with optional name and path arguments. | ||
|
||
#### Usage | ||
|
||
```shell | ||
$ quartz init --help | ||
quartz-init | ||
Create base Quartz app directory from template | ||
|
||
USAGE: | ||
quartz init [OPTIONS] | ||
|
||
OPTIONS: | ||
-n, --name <NAME> Set the name of the Quartz app [default: <name of parent directory>] | ||
-p, --path <PATH> Set the path where the Quartz app will be created [default: .] | ||
-h, --help Print help information | ||
``` | ||
|
||
#### Example | ||
|
||
```shell | ||
quartz init --name <app_name> --path <path> | ||
``` | ||
|
||
This command will create the following directory structure at the specified path (or the current directory if no path is | ||
provided): | ||
|
||
```shell | ||
$ tree /<path>/<app-name> -L 1 | ||
apps/transfers/ | ||
├── contracts/ | ||
├── enclave/ | ||
├── frontend/ | ||
└── README.md | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
use std::path::PathBuf; | ||
|
||
use clap::{Parser, Subcommand}; | ||
use tracing::metadata::LevelFilter; | ||
|
||
#[derive(clap::Args, Debug, Clone)] | ||
pub struct Verbosity { | ||
/// Increase verbosity, can be repeated up to 2 times | ||
#[arg(long, short, action = clap::ArgAction::Count)] | ||
pub verbose: u8, | ||
} | ||
|
||
impl Verbosity { | ||
pub fn to_level_filter(&self) -> LevelFilter { | ||
match self.verbose { | ||
0 => LevelFilter::INFO, | ||
1 => LevelFilter::DEBUG, | ||
_ => LevelFilter::TRACE, | ||
} | ||
} | ||
} | ||
|
||
#[derive(Debug, Parser)] | ||
#[command(version, long_about = None)] | ||
pub struct Cli { | ||
/// Increase log verbosity | ||
#[clap(flatten)] | ||
pub verbose: Verbosity, | ||
|
||
/// Main command | ||
#[command(subcommand)] | ||
pub command: Command, | ||
} | ||
|
||
#[derive(Debug, Subcommand)] | ||
pub enum Command { | ||
/// Create an empty Quartz app from a template | ||
Init { | ||
/// path to create & init a quartz app, defaults to current path if unspecified | ||
#[clap(long)] | ||
path: Option<PathBuf>, | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
use displaydoc::Display; | ||
use thiserror::Error; | ||
|
||
#[derive(Debug, Display, Error)] | ||
pub enum Error { | ||
/// specified path `{0}` is not a directory | ||
PathNotDir(String), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
use crate::{cli::Verbosity, error::Error, request::Request, response::Response}; | ||
|
||
pub mod init; | ||
|
||
pub trait Handler { | ||
type Error; | ||
type Response; | ||
|
||
fn handle(self, verbosity: Verbosity) -> Result<Self::Response, Self::Error>; | ||
} | ||
|
||
impl Handler for Request { | ||
type Error = Error; | ||
type Response = Response; | ||
|
||
fn handle(self, verbosity: Verbosity) -> Result<Self::Response, Self::Error> { | ||
match self { | ||
Request::Init(request) => request.handle(verbosity), | ||
} | ||
.map(Into::into) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use tracing::trace; | ||
|
||
use crate::{ | ||
cli::Verbosity, error::Error, handler::Handler, request::init::InitRequest, | ||
response::init::InitResponse, | ||
}; | ||
|
||
impl Handler for InitRequest { | ||
type Error = Error; | ||
type Response = InitResponse; | ||
|
||
fn handle(self, _verbosity: Verbosity) -> Result<Self::Response, Self::Error> { | ||
trace!("initializing directory structure..."); | ||
todo!() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
#![doc = include_str!("../README.md")] | ||
#![forbid(unsafe_code)] | ||
#![warn( | ||
clippy::checked_conversions, | ||
clippy::panic, | ||
clippy::panic_in_result_fn, | ||
clippy::unwrap_used, | ||
trivial_casts, | ||
trivial_numeric_casts, | ||
rust_2018_idioms, | ||
unused_lifetimes, | ||
unused_import_braces, | ||
unused_qualifications | ||
)] | ||
|
||
pub mod cli; | ||
pub mod error; | ||
pub mod handler; | ||
pub mod request; | ||
pub mod response; | ||
|
||
use clap::Parser; | ||
use color_eyre::eyre::Result; | ||
use tracing_subscriber::{util::SubscriberInitExt, EnvFilter}; | ||
|
||
use crate::{cli::Cli, handler::Handler, request::Request}; | ||
|
||
fn main() -> Result<()> { | ||
color_eyre::install()?; | ||
|
||
let args = Cli::parse(); | ||
|
||
let env_filter = EnvFilter::builder() | ||
.with_default_directive(args.verbose.to_level_filter().into()) | ||
.from_env_lossy(); | ||
|
||
tracing_subscriber::fmt() | ||
.with_target(false) | ||
.with_writer(std::io::stderr) | ||
.with_env_filter(env_filter) | ||
.finish() | ||
.init(); | ||
|
||
// The idea is to parse the input args and convert them into `Requests` which are | ||
// correct-by-construction types that this tool can handle. All validation should happen during | ||
// this conversion. | ||
let request = Request::try_from(args.command)?; | ||
|
||
// Each `Request` defines an associated `Handler` (i.e. logic) and `Response`. All handlers are | ||
// free to log to the terminal and these logs are sent to `stderr`. | ||
let response = request.handle(args.verbose)?; | ||
|
||
// `Handlers` must use `Responses` to output to `stdout`. | ||
println!( | ||
"{}", | ||
serde_json::to_string(&response).expect("infallible serializer") | ||
); | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
use crate::{cli::Command, error::Error, request::init::InitRequest}; | ||
|
||
pub mod init; | ||
|
||
#[derive(Clone, Debug)] | ||
pub enum Request { | ||
Init(InitRequest), | ||
} | ||
|
||
impl TryFrom<Command> for Request { | ||
type Error = Error; | ||
|
||
fn try_from(cmd: Command) -> Result<Self, Self::Error> { | ||
match cmd { | ||
Command::Init { path } => InitRequest::try_from(path), | ||
} | ||
.map(Into::into) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
use std::path::PathBuf; | ||
|
||
use crate::{error::Error, request::Request}; | ||
|
||
#[derive(Clone, Debug)] | ||
pub struct InitRequest { | ||
// TODO(hu55a1n1): remove `allow(unused)` here once init handler is implemented | ||
#[allow(unused)] | ||
directory: PathBuf, | ||
} | ||
|
||
impl TryFrom<Option<PathBuf>> for InitRequest { | ||
type Error = Error; | ||
|
||
fn try_from(path: Option<PathBuf>) -> Result<Self, Self::Error> { | ||
if let Some(path) = path { | ||
if !path.is_dir() { | ||
return Err(Error::PathNotDir(format!("{}", path.display()))); | ||
} | ||
} | ||
|
||
todo!() | ||
} | ||
} | ||
|
||
impl From<InitRequest> for Request { | ||
fn from(request: InitRequest) -> Self { | ||
Self::Init(request) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
use serde::Serialize; | ||
|
||
use crate::response::init::InitResponse; | ||
|
||
pub mod init; | ||
|
||
#[derive(Clone, Debug, Serialize)] | ||
pub enum Response { | ||
Init(InitResponse), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
use serde::Serialize; | ||
|
||
use crate::response::Response; | ||
|
||
#[derive(Clone, Debug, Serialize)] | ||
pub struct InitResponse; | ||
|
||
impl From<InitResponse> for Response { | ||
fn from(response: InitResponse) -> Self { | ||
Self::Init(response) | ||
} | ||
} |