Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: pop up command #403

Draft
wants to merge 9 commits into
base: feat/deploy-parachain
Choose a base branch
from
8 changes: 4 additions & 4 deletions Cargo.lock

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

21 changes: 16 additions & 5 deletions crates/pop-cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0

use crate::{cache, cli::Cli};
use crate::{cache, cli::Cli, common::builds::get_project_path};
use clap::Subcommand;
use pop_common::templates::Template;
use serde_json::{json, Value};
Expand All @@ -15,33 +15,33 @@

#[derive(Subcommand)]
#[command(subcommand_required = true)]
pub(crate) enum Command {
/// Set up the environment for development by installing required packages.
#[clap(alias = "i")]
Install(install::InstallArgs),
/// Generate a new parachain, pallet or smart contract.
#[clap(alias = "n")]
#[cfg(any(feature = "parachain", feature = "contract"))]
New(new::NewArgs),
#[clap(alias = "b", about = about_build())]
#[cfg(any(feature = "parachain", feature = "contract"))]
Build(build::BuildArgs),
/// Call a chain or a smart contract.
#[clap(alias = "c")]
#[cfg(any(feature = "parachain", feature = "contract"))]
Call(call::CallArgs),
/// Launch a local network or deploy a smart contract.
#[clap(alias = "u")]
#[cfg(any(feature = "parachain", feature = "contract"))]
Up(up::UpArgs),
/// Test a smart contract.
#[clap(alias = "t")]
#[cfg(feature = "contract")]
Test(test::TestArgs),
/// Remove generated/cached artifacts.
#[clap(alias = "C")]
Clean(clean::CleanArgs),
}

Check warning on line 44 in crates/pop-cli/src/commands/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

large size difference between variants

warning: large size difference between variants --> crates/pop-cli/src/commands/mod.rs:18:1 | 18 | / pub(crate) enum Command { 19 | | /// Set up the environment for development by installing required packages. 20 | | #[clap(alias = "i")] 21 | | Install(install::InstallArgs), ... | 32 | | Call(call::CallArgs), | | -------------------- the second-largest variant contains at least 296 bytes ... | 36 | | Up(up::UpArgs), | | -------------- the largest variant contains at least 592 bytes ... | 43 | | Clean(clean::CleanArgs), 44 | | } | |_^ the entire enum is at least 592 bytes | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant = note: `#[warn(clippy::large_enum_variant)]` on by default help: consider boxing the large fields to reduce the total size of the enum | 36 | Up(Box<up::UpArgs>), | ~~~~~~~~~~~~~~~

/// Help message for the build command.
fn about_build() -> &'static str {
Expand Down Expand Up @@ -101,10 +101,21 @@
},
#[cfg(any(feature = "parachain", feature = "contract"))]
Self::Up(args) => match args.command {
#[cfg(feature = "parachain")]
up::Command::Parachain(cmd) => cmd.execute().await.map(|_| Value::Null),
#[cfg(feature = "contract")]
up::Command::Contract(cmd) => cmd.execute().await.map(|_| Value::Null),
None => up::Command::execute(args).await.map(|t| json!(t)),
Some(cmd) => match cmd {
#[cfg(feature = "parachain")]
up::Command::Network(mut cmd) => {
cmd.valid = true;
cmd.execute().await.map(|_| Value::Null)
},
#[cfg(feature = "parachain")]
up::Command::Parachain(cmd) => cmd.execute().await.map(|_| Value::Null),
#[cfg(feature = "contract")]
up::Command::Contract(mut cmd) => {
cmd.path = get_project_path(args.path, args.path_pos);
cmd.execute().await.map(|_| Value::Null)
},
},
},
#[cfg(feature = "contract")]
Self::Test(args) => match args.command {
Expand Down
40 changes: 19 additions & 21 deletions crates/pop-cli/src/commands/up/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
use crate::{
cli::{traits::Cli as _, Cli},
common::{
builds::get_project_path,
contracts::{check_contracts_node_and_prompt, has_contract_been_built, terminate_node},
wallet::request_signature,
},
Expand All @@ -29,15 +28,14 @@ const COMPLETE: &str = "🚀 Deployment complete";
const DEFAULT_URL: &str = "ws://localhost:9944/";
const DEFAULT_PORT: u16 = 9944;
const FAILED: &str = "🚫 Deployment failed.";
const HELP_HEADER: &str = "Smart Contract deployment options";

#[derive(Args, Clone)]
#[clap(next_help_heading = HELP_HEADER)]
pub struct UpContractCommand {
/// Path to the contract build directory.
#[arg(short, long)]
path: Option<PathBuf>,
/// Directory path without flag for your project [default: current directory]
#[arg(value_name = "PATH", index = 1, conflicts_with = "path")]
pub path_pos: Option<PathBuf>,
#[clap(skip)]
pub(crate) path: Option<PathBuf>,
/// The name of the contract constructor to call.
#[clap(short, long, default_value = "new")]
constructor: String,
Expand Down Expand Up @@ -89,25 +87,26 @@ pub struct UpContractCommand {
/// confirmation.
#[clap(short = 'y', long)]
skip_confirm: bool,
// Deprecation flag, used to specify whether the deprecation warning is shown.
#[clap(skip)]
pub(crate) valid: bool,
}

impl UpContractCommand {
/// Executes the command.
pub(crate) async fn execute(mut self) -> anyhow::Result<()> {
Cli.intro("Deploy a smart contract")?;

let project_path = get_project_path(self.path.clone(), self.path_pos.clone());
// Show warning if specified as deprecated.
if !self.valid {
Cli.warning("NOTE: this command is deprecated. Please use `pop up` (or simply `pop u`) in future...")?;
}
// Check if build exists in the specified "Contract build directory"
if !has_contract_been_built(project_path.as_deref()) {
if !has_contract_been_built(self.path.as_deref()) {
// Build the contract in release mode
Cli.warning("NOTE: contract has not yet been built.")?;
let spinner = spinner();
spinner.start("Building contract in RELEASE mode...");
let result = match build_smart_contract(
project_path.as_deref().map(|v| v),
true,
Verbosity::Quiet,
) {
let result = match build_smart_contract(self.path.as_deref(), true, Verbosity::Quiet) {
Ok(result) => result,
Err(e) => {
Cli.outro_cancel(format!("🚫 An error occurred building your contract: {e}\nUse `pop build` to retry with build output."))?;
Expand Down Expand Up @@ -369,8 +368,7 @@ impl UpContractCommand {

// get the call data and contract code hash
async fn get_contract_data(&self) -> anyhow::Result<(Vec<u8>, [u8; 32])> {
let project_path = get_project_path(self.path.clone(), self.path_pos.clone());
let contract_code = get_contract_code(project_path.as_ref())?;
let contract_code = get_contract_code(self.path.as_ref())?;
let hash = contract_code.code_hash();
if self.upload_only {
let call_data = get_upload_payload(contract_code, self.url.as_str()).await?;
Expand Down Expand Up @@ -445,7 +443,6 @@ mod tests {
fn default_up_contract_command() -> UpContractCommand {
UpContractCommand {
path: None,
path_pos: None,
constructor: "new".to_string(),
args: vec![],
value: "0".to_string(),
Expand All @@ -458,6 +455,7 @@ mod tests {
upload_only: false,
skip_confirm: false,
use_wallet: false,
valid: true,
}
}

Expand Down Expand Up @@ -521,8 +519,7 @@ mod tests {
let localhost_url = format!("ws://127.0.0.1:{}", port);

let up_contract_opts = UpContractCommand {
path: Some(temp_dir.clone()),
path_pos: Some(temp_dir),
path: Some(temp_dir),
constructor: "new".to_string(),
args: vec![],
value: "0".to_string(),
Expand All @@ -535,6 +532,7 @@ mod tests {
upload_only: true,
skip_confirm: true,
use_wallet: true,
valid: true,
};

let rpc_client = subxt::backend::rpc::RpcClient::from_url(&up_contract_opts.url).await?;
Expand Down Expand Up @@ -573,8 +571,7 @@ mod tests {
let localhost_url = format!("ws://127.0.0.1:{}", port);

let up_contract_opts = UpContractCommand {
path: Some(temp_dir.clone()),
path_pos: Some(temp_dir),
path: Some(temp_dir),
constructor: "new".to_string(),
args: vec!["false".to_string()],
value: "0".to_string(),
Expand All @@ -587,6 +584,7 @@ mod tests {
upload_only: false,
skip_confirm: true,
use_wallet: true,
valid: true,
};

// Retrieve call data based on the above command options.
Expand Down
48 changes: 42 additions & 6 deletions crates/pop-cli/src/commands/up/mod.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,65 @@
// SPDX-License-Identifier: GPL-3.0

use crate::common::builds::get_project_path;
use clap::{Args, Subcommand};
use std::path::PathBuf;

#[cfg(feature = "contract")]
mod contract;
#[cfg(feature = "parachain")]
mod parachain;
mod network;

/// Arguments for launching or deploying.
#[derive(Args)]
#[command(args_conflicts_with_subcommands = true)]
pub(crate) struct UpArgs {
/// Path to the project directory.
#[arg(long, global = true)]
// TODO: Introduce the short option in v0.8.0 once deprecated parachain command is removed.
pub path: Option<PathBuf>,

/// Directory path without flag for your project [default: current directory]
#[arg(value_name = "PATH", index = 1, global = true, conflicts_with = "path")]
pub path_pos: Option<PathBuf>,

#[command(flatten)]
#[cfg(feature = "contract")]
pub contract: contract::UpContractCommand,

#[command(subcommand)]
pub(crate) command: Command,
pub(crate) command: Option<Command>,
}

/// Launch a local network or deploy a smart contract.
#[derive(Subcommand)]
pub(crate) enum Command {
#[cfg(feature = "parachain")]
/// Launch a local network.
#[clap(alias = "p")]
Parachain(parachain::ZombienetCommand),
#[clap(alias = "n")]
Network(network::ZombienetCommand),
#[cfg(feature = "parachain")]
/// [DEPRECATED] Launch a local network (will be removed in v0.8.0).
#[clap(alias = "p", hide = true)]
Parachain(network::ZombienetCommand),
#[cfg(feature = "contract")]
/// Deploy a smart contract.
#[clap(alias = "c")]
/// [DEPRECATED] Deploy a smart contract (will be removed in v0.8.0).
#[clap(alias = "c", hide = true)]
Contract(contract::UpContractCommand),
}

impl Command {
/// Executes the command.
pub(crate) async fn execute(args: UpArgs) -> anyhow::Result<()> {
let project_path = get_project_path(args.path.clone(), args.path_pos.clone());
// If only contract feature enabled, deploy a contract
#[cfg(feature = "contract")]
if pop_contracts::is_supported(project_path.as_deref())? {
let mut cmd = args.contract;
cmd.path = project_path;
cmd.valid = true;
cmd.execute().await?;
}
// TODO: if pop_parachains::is_supported(project_path.as_deref())?
Ok(())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
/// Automatically source all needed binaries required without prompting for confirmation.
#[clap(short = 'y', long)]
skip_confirm: bool,
// Deprecation flag, used to specify whether the deprecation warning is shown.
#[clap(skip)]
pub(crate) valid: bool,
}

impl ZombienetCommand {
Expand All @@ -57,6 +60,11 @@
intro(format!("{}: Launch a local network", style(" Pop CLI ").black().on_magenta()))?;
set_theme(Theme);

// Show warning if specified as deprecated.
if !self.valid {
log::warning("NOTE: this command is deprecated. Please use `pop up network` (or simply `pop up n`) in future...")?;
}

// Parse arguments
let cache = crate::cache()?;
let mut zombienet = match Zombienet::new(
Expand Down Expand Up @@ -284,7 +292,7 @@
let binaries: Vec<_> = binaries
.into_iter()
.filter(|b| !b.exists() || (latest && b.stale()))
.map(|b| {

Check warning on line 295 in crates/pop-cli/src/commands/up/network.rs

View workflow job for this annotation

GitHub Actions / clippy

using `map` over `inspect`

warning: using `map` over `inspect` --> crates/pop-cli/src/commands/up/network.rs:295:5 | 295 | .map(|b| { | ^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_inspect = note: `#[warn(clippy::manual_inspect)]` on by default help: try | 295 ~ .inspect(|b| { 296 | if latest && b.stale() { 297 | b.use_latest() 298 ~ } |
if latest && b.stale() {
b.use_latest()
}
Expand Down
20 changes: 5 additions & 15 deletions crates/pop-cli/tests/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,11 @@ async fn contract_lifecycle() -> Result<()> {
sleep(Duration::from_secs(5)).await;

// Only upload the contract
// pop up contract --path ./test_contract --upload-only
// pop up --path ./test_contract --upload-only
Command::cargo_bin("pop")
.unwrap()
.current_dir(&temp_dir.join("test_contract"))
.args(&[
"up",
"contract",
"--path",
"./test_contract",
"--upload-only",
"--url",
default_endpoint,
])
.current_dir(&temp_dir)
.args(&["up", "--path", "./test_contract", "--upload-only", "--url", default_endpoint])
.assert()
.success();
// Instantiate contract, only dry-run
Expand All @@ -110,7 +102,6 @@ async fn contract_lifecycle() -> Result<()> {
.current_dir(&temp_dir.join("test_contract"))
.args(&[
"up",
"contract",
"--constructor",
"new",
"--args",
Expand Down Expand Up @@ -180,7 +171,7 @@ async fn contract_lifecycle() -> Result<()> {
.assert()
.success();

// pop up contract --upload-only --use-wallet
// pop up --upload-only --use-wallet
// Will run http server for wallet integration.
// Using `cargo run --` as means for the CI to pass.
// Possibly there's room for improvement here.
Expand All @@ -189,12 +180,11 @@ async fn contract_lifecycle() -> Result<()> {
"run",
"--",
"up",
"contract",
"--upload-only",
"--use-wallet",
"--skip-confirm",
"--dry-run",
"-p",
"--path",
temp_dir.join("test_contract").to_str().expect("to_str"),
"--url",
default_endpoint,
Expand Down
4 changes: 2 additions & 2 deletions crates/pop-cli/tests/parachain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,10 @@ name = "collator-01"
),
)?;

// `pop up parachain -f ./network.toml --skip-confirm`
// `pop up network -f ./network.toml --skip-confirm`
let mut cmd = Cmd::new(cargo_bin("pop"))
.current_dir(&temp_parachain_dir)
.args(&["up", "parachain", "-f", "./network.toml", "--skip-confirm"])
.args(&["up", "network", "-f", "./network.toml", "--skip-confirm"])
.spawn()
.unwrap();

Expand Down
Loading