Skip to content

Commit

Permalink
feat: New command - deploy (#113)
Browse files Browse the repository at this point in the history
  • Loading branch information
FroVolod authored and frol committed Oct 19, 2023
1 parent 577c41b commit a4cecb6
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 5 deletions.
7 changes: 6 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions cargo-near/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,15 @@ color-eyre = "0.6"
inquire = "0.6"
strum = { version = "0.24", features = ["derive"] }
strum_macros = "0.24"
interactive-clap = "0.2.6"
interactive-clap-derive = "0.2.6"
linked-hash-map = { version = "0.5", features = ["serde_impl"] }
names = { version = "0.14.0", default-features = false }
near-cli-rs = { git = "https://github.com/near/near-cli-rs" }
derive_more = "0.99.9"
shell-words = "1.0.0"
dunce = "1"
interactive-clap = "0.2.7"
interactive-clap-derive = "0.2.7"
near-cli-rs = { version = "0.6.2" }
near-crypto = "0.17.0"
near-primitives = "0.17.0"
near-jsonrpc-client = "0.6.0"
near-jsonrpc-primitives = "0.17.0"
dunce = "1"
127 changes: 127 additions & 0 deletions cargo-near/src/commands/deploy/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
use near_cli_rs::commands::contract::deploy::initialize_mode::InitializeMode;

use crate::commands::build_command;

#[derive(Debug, Clone, interactive_clap::InteractiveClap)]
#[interactive_clap(input_context = near_cli_rs::GlobalContext)]
#[interactive_clap(output_context = ContractContext)]
#[interactive_clap(skip_default_from_cli)]
pub struct Contract {
#[interactive_clap(skip_default_input_arg)]
#[interactive_clap(flatten)]
/// Specify a build command args:
build_command_args: build_command::BuildCommand,
#[interactive_clap(skip_default_input_arg)]
/// What is the contract account ID?
contract_account_id: near_cli_rs::types::account_id::AccountId,
#[interactive_clap(subcommand)]
initialize: InitializeMode,
}

#[derive(Debug, Clone)]
pub struct ContractContext(near_cli_rs::commands::contract::deploy::ContractFileContext);

impl ContractContext {
pub fn from_previous_context(
previous_context: near_cli_rs::GlobalContext,
scope: &<Contract as interactive_clap::ToInteractiveClapContextScope>::InteractiveClapContextScope,
) -> color_eyre::eyre::Result<Self> {
let file_path = build_command::build::run(scope.build_command_args.clone())?.path;
Ok(Self(
near_cli_rs::commands::contract::deploy::ContractFileContext {
global_context: previous_context,
receiver_account_id: scope.contract_account_id.clone().into(),
signer_account_id: scope.contract_account_id.clone().into(),
code: std::fs::read(file_path)?,
},
))
}
}

impl From<ContractContext> for near_cli_rs::commands::contract::deploy::ContractFileContext {
fn from(item: ContractContext) -> Self {
item.0
}
}

impl interactive_clap::FromCli for Contract {
type FromCliContext = near_cli_rs::GlobalContext;
type FromCliError = color_eyre::eyre::Error;
fn from_cli(
optional_clap_variant: Option<<Self as interactive_clap::ToCli>::CliVariant>,
context: Self::FromCliContext,
) -> interactive_clap::ResultFromCli<
<Self as interactive_clap::ToCli>::CliVariant,
Self::FromCliError,
>
where
Self: Sized + interactive_clap::ToCli,
{
let mut clap_variant = optional_clap_variant.unwrap_or_default();

let build_command_args =
if let Some(cli_build_command_args) = &clap_variant.build_command_args {
build_command::BuildCommand {
release: cli_build_command_args.release,
embed_abi: cli_build_command_args.embed_abi,
doc: cli_build_command_args.doc,
no_abi: cli_build_command_args.no_abi,
out_dir: cli_build_command_args.out_dir.clone(),
manifest_path: cli_build_command_args.manifest_path.clone(),
color: cli_build_command_args.color.clone(),
}
} else {
build_command::BuildCommand::default()
};

if clap_variant.contract_account_id.is_none() {
clap_variant.contract_account_id = match Self::input_contract_account_id(&context) {
Ok(Some(contract_account_id)) => Some(contract_account_id),
Ok(None) => return interactive_clap::ResultFromCli::Cancel(Some(clap_variant)),
Err(err) => return interactive_clap::ResultFromCli::Err(Some(clap_variant), err),
};
}
let contract_account_id = clap_variant
.contract_account_id
.clone()
.expect("Unexpected error");

let new_context_scope = InteractiveClapContextScopeForContract {
build_command_args,
contract_account_id,
};

let output_context =
match ContractContext::from_previous_context(context, &new_context_scope) {
Ok(new_context) => new_context,
Err(err) => return interactive_clap::ResultFromCli::Err(Some(clap_variant), err),
};

match InitializeMode::from_cli(clap_variant.initialize.take(), output_context.into()) {
interactive_clap::ResultFromCli::Ok(initialize) => {
clap_variant.initialize = Some(initialize);
interactive_clap::ResultFromCli::Ok(clap_variant)
}
interactive_clap::ResultFromCli::Cancel(optional_initialize) => {
clap_variant.initialize = optional_initialize;
interactive_clap::ResultFromCli::Cancel(Some(clap_variant))
}
interactive_clap::ResultFromCli::Back => interactive_clap::ResultFromCli::Back,
interactive_clap::ResultFromCli::Err(optional_initialize, err) => {
clap_variant.initialize = optional_initialize;
interactive_clap::ResultFromCli::Err(Some(clap_variant), err)
}
}
}
}

impl Contract {
pub fn input_contract_account_id(
context: &near_cli_rs::GlobalContext,
) -> color_eyre::eyre::Result<Option<near_cli_rs::types::account_id::AccountId>> {
near_cli_rs::common::input_signer_account_id_from_used_account_list(
&context.config.credentials_home_dir,
"What is the contract account ID?",
)
}
}
4 changes: 4 additions & 0 deletions cargo-near/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use strum::{EnumDiscriminants, EnumIter, EnumMessage};
pub mod abi_command;
pub mod build_command;
pub mod create_dev_account;
pub mod deploy;

#[derive(Debug, EnumDiscriminants, Clone, interactive_clap::InteractiveClap)]
#[interactive_clap(context = near_cli_rs::GlobalContext)]
Expand All @@ -28,4 +29,7 @@ pub enum NearCommand {
))]
/// Create a development account using the faucet service sponsor to cover the cost of creating an account (testnet only for now)
CreateDevAccount(self::create_dev_account::CreateAccount),
#[strum_discriminants(strum(message = "deploy - Add a new contract code"))]
/// Add a new contract code
Deploy(self::deploy::Contract),
}
2 changes: 2 additions & 0 deletions cargo-near/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(clippy::large_enum_variant)]

pub use near_cli_rs::CliResult;
use strum::{EnumDiscriminants, EnumIter, EnumMessage};

Expand Down
9 changes: 9 additions & 0 deletions cargo-near/src/types/utf8_path_buf.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use color_eyre::eyre::Context;

#[derive(
Debug,
Default,
Expand All @@ -19,3 +21,10 @@ impl std::fmt::Display for Utf8PathBufInner {
impl interactive_clap::ToCli for Utf8PathBufInner {
type CliVariant = Utf8PathBufInner;
}

impl Utf8PathBufInner {
pub fn read_bytes(&self) -> color_eyre::Result<Vec<u8>> {
std::fs::read(self.0.clone().into_std_path_buf())
.wrap_err_with(|| format!("Error reading data from file: {:?}", self.0))
}
}
1 change: 1 addition & 0 deletions integration-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ macro_rules! invoke_cargo_near {
cargo_near::commands::build_command::build::run(args)?;
},
Some(cargo_near::commands::CliNearCommand::CreateDevAccount(_)) => todo!(),
Some(cargo_near::commands::CliNearCommand::Deploy(_)) => todo!(),
None => ()
}

Expand Down

0 comments on commit a4cecb6

Please sign in to comment.