feat: cli contract build (#138)

This commit is contained in:
Daniel Gushchyan 2024-08-09 08:52:06 -07:00 committed by GitHub
parent 84ccbb201d
commit 048f8e7d0f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 92 additions and 8 deletions

View file

@ -48,6 +48,7 @@ pub enum Command {
#[clap(long, default_value = "quartz_app")] #[clap(long, default_value = "quartz_app")]
name: String, name: String,
}, },
/// Perform handshake
Handshake { Handshake {
/// path to create & init a Quartz app, defaults to current path if unspecified /// path to create & init a Quartz app, defaults to current path if unspecified
#[arg(short, long, value_parser = wasmaddr_to_id)] #[arg(short, long, value_parser = wasmaddr_to_id)]
@ -72,7 +73,7 @@ pub enum Command {
#[clap(long)] #[clap(long)]
app_dir: Option<PathBuf>, app_dir: Option<PathBuf>,
}, },
/// Create an empty Quartz app from a template /// Subcommands for handling the Quartz app contract
Contract { Contract {
#[command(subcommand)] #[command(subcommand)]
contract_command: ContractCommand, contract_command: ContractCommand,
@ -88,7 +89,7 @@ pub enum Command {
pub enum ContractCommand { pub enum ContractCommand {
Build { Build {
#[clap(long)] #[clap(long)]
path: Option<PathBuf>, manifest_path: PathBuf,
}, },
Deploy { Deploy {
/// Json-formatted cosmwasm contract initialization message /// Json-formatted cosmwasm contract initialization message

View file

@ -7,6 +7,6 @@ pub enum Error {
PathNotDir(String), PathNotDir(String),
/// Specified file `{0}` does not exist /// Specified file `{0}` does not exist
PathNotFile(String), PathNotFile(String),
/// {0} /// unspecified error: {0}
GenericErr(String), GenericErr(String),
} }

View file

@ -4,6 +4,7 @@ use crate::{error::Error, request::Request, response::Response, Config};
pub mod utils; pub mod utils;
// commands // commands
pub mod contract_build;
pub mod contract_deploy; pub mod contract_deploy;
pub mod enclave_build; pub mod enclave_build;
pub mod handshake; pub mod handshake;
@ -26,6 +27,7 @@ impl Handler for Request {
match self { match self {
Request::Init(request) => request.handle(config).await, Request::Init(request) => request.handle(config).await,
Request::Handshake(request) => request.handle(config).await, Request::Handshake(request) => request.handle(config).await,
Request::ContractBuild(request) => request.handle(config).await,
Request::ContractDeploy(request) => request.handle(config).await, Request::ContractDeploy(request) => request.handle(config).await,
Request::EnclaveBuild(request) => request.handle(config).await, Request::EnclaveBuild(request) => request.handle(config).await,
} }

View file

@ -0,0 +1,45 @@
use std::process::Command;
use async_trait::async_trait;
use tracing::{debug, trace};
use crate::{
error::Error,
handler::Handler,
request::contract_build::ContractBuildRequest,
response::{contract_build::ContractBuildResponse, Response},
Config,
};
#[async_trait]
impl Handler for ContractBuildRequest {
type Error = Error;
type Response = Response;
async fn handle(self, config: Config) -> Result<Self::Response, Self::Error> {
let mut cargo = Command::new("cargo");
let command = cargo
.arg("wasm")
.args(["--manifest-path", &self.manifest_path.display().to_string()])
.env("RUSTFLAGS", "-C link-arg=-s");
if config.mock_sgx {
debug!("Building with mock-sgx enabled");
command.arg("--features=mock-sgx");
}
trace!("🚧 Building contract binary ...");
let status = command
.status()
.map_err(|e| Error::GenericErr(e.to_string()))?;
if !status.success() {
return Err(Error::GenericErr(format!(
"Couldn't build contract. \n{:?}",
status
)));
}
Ok(ContractBuildResponse.into())
}
}

View file

@ -4,11 +4,12 @@ use crate::{
cli::{Command, ContractCommand, EnclaveCommand}, cli::{Command, ContractCommand, EnclaveCommand},
error::Error, error::Error,
request::{ request::{
contract_deploy::ContractDeployRequest, enclave_build::EnclaveBuildRequest, contract_build::ContractBuildRequest, contract_deploy::ContractDeployRequest,
handshake::HandshakeRequest, init::InitRequest, enclave_build::EnclaveBuildRequest, handshake::HandshakeRequest, init::InitRequest,
}, },
}; };
pub mod contract_build;
pub mod contract_deploy; pub mod contract_deploy;
pub mod enclave_build; pub mod enclave_build;
pub mod handshake; pub mod handshake;
@ -18,6 +19,7 @@ pub mod init;
pub enum Request { pub enum Request {
Init(InitRequest), Init(InitRequest),
Handshake(HandshakeRequest), Handshake(HandshakeRequest),
ContractBuild(ContractBuildRequest),
ContractDeploy(ContractDeployRequest), ContractDeploy(ContractDeployRequest),
EnclaveBuild(EnclaveBuildRequest), EnclaveBuild(EnclaveBuildRequest),
} }
@ -94,7 +96,13 @@ impl TryFrom<ContractCommand> for Request {
} }
.into()) .into())
} }
ContractCommand::Build { path: _ } => todo!(), ContractCommand::Build { manifest_path } => {
if !manifest_path.exists() {
return Err(Error::PathNotFile(manifest_path.display().to_string()));
}
Ok(ContractBuildRequest { manifest_path }.into())
}
} }
} }
} }

View file

@ -0,0 +1,14 @@
use std::path::PathBuf;
use crate::request::Request;
#[derive(Clone, Debug)]
pub struct ContractBuildRequest {
pub manifest_path: PathBuf,
}
impl From<ContractBuildRequest> for Request {
fn from(request: ContractBuildRequest) -> Self {
Self::ContractBuild(request)
}
}

View file

@ -1,10 +1,11 @@
use serde::Serialize; use serde::Serialize;
use crate::response::{ use crate::response::{
contract_deploy::ContractDeployResponse, enclave_build::EnclaveBuildResponse, contract_build::ContractBuildResponse, contract_deploy::ContractDeployResponse,
handshake::HandshakeResponse, init::InitResponse, enclave_build::EnclaveBuildResponse, handshake::HandshakeResponse, init::InitResponse,
}; };
pub mod contract_build;
pub mod contract_deploy; pub mod contract_deploy;
pub mod enclave_build; pub mod enclave_build;
pub mod handshake; pub mod handshake;
@ -14,6 +15,7 @@ pub mod init;
pub enum Response { pub enum Response {
Init(InitResponse), Init(InitResponse),
Handshake(HandshakeResponse), Handshake(HandshakeResponse),
ContractBuild(ContractBuildResponse),
ContractDeploy(ContractDeployResponse), ContractDeploy(ContractDeployResponse),
EnclaveBuild(EnclaveBuildResponse), EnclaveBuild(EnclaveBuildResponse),
} }

View file

@ -0,0 +1,12 @@
use serde::Serialize;
use crate::response::Response;
#[derive(Clone, Debug, Serialize)]
pub struct ContractBuildResponse;
impl From<ContractBuildResponse> for Response {
fn from(response: ContractBuildResponse) -> Self {
Self::ContractBuild(response)
}
}