diff --git a/.github/README.md b/.github/README.md new file mode 120000 index 00000000..e5dc7c0d --- /dev/null +++ b/.github/README.md @@ -0,0 +1 @@ +../crates/pop-cli/README.md \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 20af21b2..b61ae280 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5518,6 +5518,8 @@ dependencies = [ "reqwest", "serde", "serde_json", + "strum 0.26.2", + "strum_macros 0.26.2", "symlink", "tempfile", "thiserror", diff --git a/Cargo.toml b/Cargo.toml index 5bc68de1..023946d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ askama = "0.12" regex="1.5.4" walkdir = "2.4" indexmap = { version = "2.2"} -toml_edit = { version = "0.22" } +toml_edit = { version = "0.22", features = ["serde"] } symlink = { version = "0.1" } reqwest = { version = "0.11" } serde_json = { version = "1.0"} diff --git a/README.md b/README.md index 4477a124..a0c543b9 100644 --- a/README.md +++ b/README.md @@ -18,32 +18,32 @@ cargo install --locked --git https://github.com/r0gue-io/pop-cli ### Parachains -Use `pop` to create a new Parachain project: +Use `pop` to create a new Parachain project. +To be guided through the entire parachain creation process, simply execute +```sh +pop new parachain +``` +If no guidance is needed, proceed with: ```sh # Create a minimal parachain pop new parachain my-app -# Get a pallet-contracts enabled parachain -pop new parachain my-app cpt -# Get a evm compatible parachain -pop new parachain my-app fpt ``` -Use `pop` to build your Parachain: +We also integrate other provider templates in the tool, check them running: ```sh -# Build your parachain -pop build parachain -p ./my-app +pop new parachain --help ``` - -or - +Some examples are: ```sh -cd my-app -pop build parachain +# Get Parity's pallet-contracts enabled parachain template +pop new parachain my-app parity -t cpt +# Get Parity's evm compatible parachain template +pop new parachain my-app parity -t fpt ``` -You can also customize your parachain by providing config options for token symbol (as it appears in chain metadata), +For Pop templates you can also customize your parachain by providing config options for token symbol (as it appears in chain metadata), token decimals, and the initial endowment for developer accounts. Here's how: ```sh @@ -57,6 +57,21 @@ There's also the shorter version: pop new parachain my-app -s DOT -d 6 -i 1_000_000_000 ``` +Use `pop` to build your Parachain: + +```sh +# Build your parachain +pop build parachain -p ./my-app +``` + +or + +```sh +cd my-app +pop build parachain +``` + + Finally, to build your Parachain: ```sh diff --git a/crates/pop-cli/README.md b/crates/pop-cli/README.md deleted file mode 100644 index 2aa0cfa0..00000000 --- a/crates/pop-cli/README.md +++ /dev/null @@ -1,257 +0,0 @@ -# Pop CLI - - - -An all-in-one tool for Polkadot development. - -## Install - -You can install Pop CLI as follows: - -```shell -cargo install --locked --git https://github.com/r0gue-io/pop-cli -``` - -> :information_source: A [crates.io](https://crates.io/crates/pop-cli) version will be available soon! - -## Getting Started - -### Parachains - -Use `pop` to create a new Parachain project: - -```sh -# Create a minimal parachain -pop new parachain my-app -# Get a pallet-contracts enabled parachain -pop new parachain my-app cpt -# Get a evm compatible parachain -pop new parachain my-app fpt -``` - -Use `pop` to build your Parachain: - -```sh -# Build your parachain -pop build parachain -p ./my-app -``` - -or - -```sh -cd my-app -pop build parachain -``` - -You can also customize your parachain by providing config options for token symbol (as it appears in chain metadata), -token decimals, and the initial endowment for developer accounts. Here's how: - -```sh -# Create a minimal parachain with "DOT" as token symbol, 6 token decimals and 1 billion tokens per dev account -pop new parachain my-app --symbol DOT --decimals 6 --endowment 1_000_000_000 -``` - -There's also the shorter version: - -```sh -pop new parachain my-app -s DOT -d 6 -i 1_000_000_000 -``` - -Finally, to build your Parachain: - -```sh -cd my-app -pop build parachain --release -``` - -## Spawn Network using Zombienet - -You can spawn a local network using [zombienet](https://github.com/paritytech/zombienet-sdk) as follows: - -```shell -pop up parachain -f ./tests/zombienet.toml -p https://github.com/r0gue-io/pop-node -``` - -> :information_source: Pop CLI will automatically source the necessary polkadot binaries. Currently, these will be built -> if on a non-linux system. - - -### Contracts - -Use `pop` to create a new Smart Contract project: - -```sh -# Create a minimal Smart Contract -pop new contract my_contract -``` - -Test the Smart Contract: - -```sh -# Test an existing Smart Contract -pop test contract -p ./my_contract -``` - -Build the Smart Contract: - -```sh -# Build an existing Smart Contract -pop build contract -p ./my_contract -``` - -To deploy a Smart Contract you need a chain running. For testing purposes one option is to -run [substrate-contracts-node](https://github.com/paritytech/substrate-contracts-node): - -```sh -cargo install contracts-node -substrate-contracts-node -``` - -> :information_source: We plan to automate this in the future. - -Deploy and instantiate the Smart Contract: - -```sh -pop up contract -p ./my_contract --constructor new --args "false" --suri //Alice -``` - -Some of the options available are: - -- Specify the contract `constructor `to use, which in this example is `new()`. -- Specify the argument (`args`) to the constructor, which in this example is `false`. -- Specify the account uploading and instantiating the contract with `--suri`, which in this example is the default - development account of `//Alice`. - For other accounts, the actual secret key must be provided e.g. an 0x prefixed 64 bit hex string, or the seed phrase. - -> :warning: **Use only for development**: Use a safer method of signing here before using this feature with production -> projects. We will be looking to provide alternative solutions in the future! - -- You also can specify the url of your node with `--url ws://your-endpoint`, by default it is - using `ws://localhost:9944`. - -For more information about the options, -check [cargo-contract documentation](https://github.com/paritytech/cargo-contract/blob/master/crates/extrinsics/README.md#instantiate) - -Interacting with the Smart Contract: - -1. Read-only Operations: For operations that only require reading from the blockchain state. This approach does not - require to submit an extrinsic. - Example using the get() message: - -```sh -pop call contract -p ./my_contract --contract $INSTANTIATED_CONTRACT_ADDRESS --message get --suri //Alice -``` - -2. State-modifying Operations: For operations that change a storage value, thus altering the blockchain state. Include - the `x / --execute` flag to submit an extrinsic on-chain. - -Example executing the `flip()` message: - -```sh -pop call contract -p ./my_contract --contract $INSTANTIATED_CONTRACT_ADDRESS --message flip --suri //Alice -x -``` - -## E2E testing - -For end-to-end testing you will need to have a Substrate node with `pallet contracts`. -You do not need to run it in the background since the node is started for each test independently. -To install the latest version: - -``` -cargo install contracts-node --git https://github.com/paritytech/substrate-contracts-node.git -``` - -If you want to run any other node with `pallet-contracts` you need to change `CONTRACTS_NODE` environment variable: - -``` -export CONTRACTS_NODE="YOUR_CONTRACTS_NODE_PATH" -``` - -Run e2e testing on the Smart Contract: - -```sh -# Run e2e tests for an existing smart contract - pop test contract -p ./my_contract --features e2e-tests -``` - -### Pallets - -To create a new Pallet, simply run `pop new pallet`. You will have a new pallet ready for hacking. -To customize the new Pallet you can follow these options: - -```sh -# create a pallet with name `pallet-awesome` in the current working directory -pop new pallet pallet-awesome -# or with options -pop new pallet pallet-awesome --authors Me --description "This pallet oozes awesomeness" --path my_app/pallets -``` - -## Building Pop CLI locally - -Build the tool locally with all the features: - -```sh -cargo build --all-features -``` - -Build the tool only for Parachain functionality: - -```sh -cargo build --features parachain -``` - -Build the tool only for Smart Contracts functionality: - -```sh -cargo build --features contract -``` - -## Testing Pop CLI - -To test the tool locally. - -Run the unit tests: - -```sh -cargo test -``` - -Due to the time it can take to build a Parachain or a Smart Contract, some tests have been separated from the normal testing flow. - -To run the unit tests that involves building a Smart Contract: - -```sh -cargo test --features unit_contract -``` - -To run the unit tests that involves building a Parachain: - -```sh -cargo test --features unit_parachain -``` - -Then we have some tests that check all the flows are correct: - -Run the e2e tests for Smart Contracts functionality: - -```sh -cargo test --features e2e_contract -``` - -Run the e2e tests for Parachain functionality: - -```sh -cargo test --features e2e_parachain -``` - -Run all tests: - -```sh -cargo test --all-features -``` -## Acknowledgements - -Pop CLI would not be possible without these awesome crates! - -- Local network deployment powered by [zombienet-sdk](https://github.com/paritytech/zombienet-sdk) -- [cargo contract](https://github.com/paritytech/cargo-contract) a setup and deployment tool for developing Wasm based Smart Contracts via ink! diff --git a/crates/pop-cli/README.md b/crates/pop-cli/README.md new file mode 120000 index 00000000..fe840054 --- /dev/null +++ b/crates/pop-cli/README.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/crates/pop-cli/src/commands/new/contract.rs b/crates/pop-cli/src/commands/new/contract.rs index 0e9b6770..b86a7530 100644 --- a/crates/pop-cli/src/commands/new/contract.rs +++ b/crates/pop-cli/src/commands/new/contract.rs @@ -18,7 +18,7 @@ pub struct NewContractCommand { } impl NewContractCommand { - pub(crate) fn execute(self) -> anyhow::Result<()> { + pub(crate) async fn execute(&self) -> anyhow::Result<()> { clear_screen()?; intro(format!( "{}: Generating new contract \"{}\"!", @@ -49,7 +49,7 @@ impl NewContractCommand { fs::create_dir_all(contract_path.as_path())?; let mut spinner = cliclack::spinner(); spinner.start("Generating contract..."); - create_smart_contract(self.name, contract_path.as_path())?; + create_smart_contract(&self.name, contract_path.as_path())?; spinner.stop("Smart contract created!"); outro(format!("cd into \"{}\" and enjoy hacking! 🚀", contract_path.display()))?; Ok(()) @@ -61,14 +61,14 @@ mod tests { use super::*; use anyhow::Result; - #[test] - fn test_new_contract_command_execute_success() -> Result<()> { + #[tokio::test] + async fn test_new_contract_command_execute_success() -> Result<()> { let temp_contract_dir = tempfile::tempdir().expect("Could not create temp dir"); let command = NewContractCommand { name: "test_contract".to_string(), path: Some(PathBuf::from(temp_contract_dir.path())), }; - let result = command.execute(); + let result = command.execute().await; assert!(result.is_ok()); Ok(()) diff --git a/crates/pop-cli/src/commands/new/pallet.rs b/crates/pop-cli/src/commands/new/pallet.rs index d5746c80..f729b5f9 100644 --- a/crates/pop-cli/src/commands/new/pallet.rs +++ b/crates/pop-cli/src/commands/new/pallet.rs @@ -19,7 +19,7 @@ pub struct NewPalletCommand { } impl NewPalletCommand { - pub(crate) fn execute(&self) -> anyhow::Result<()> { + pub(crate) async fn execute(&self) -> anyhow::Result<()> { clear_screen()?; intro(format!( "{}: Generating new pallet \"{}\"!", diff --git a/crates/pop-cli/src/commands/new/parachain.rs b/crates/pop-cli/src/commands/new/parachain.rs index d0785be1..737b0808 100644 --- a/crates/pop-cli/src/commands/new/parachain.rs +++ b/crates/pop-cli/src/commands/new/parachain.rs @@ -1,40 +1,30 @@ // SPDX-License-Identifier: GPL-3.0 use crate::style::{style, Theme}; -use clap::{Args, Parser}; -use std::{fs, path::PathBuf}; -use strum_macros::{Display, EnumString}; - -use cliclack::{clear_screen, confirm, intro, log, outro, outro_cancel, set_theme}; -use pop_parachains::{instantiate_template_dir, Config, Git, Template as ParachainTemplate}; - -#[derive(Clone, Parser, Debug, Display, EnumString, PartialEq)] -pub enum Template { - #[strum(serialize = "Contracts Node Template", serialize = "cpt")] - Contracts, - #[strum(serialize = "Frontier Parachain Template", serialize = "fpt")] - FPT, - #[strum(serialize = "Base Parachain Template", serialize = "base")] - Base, -} -impl Template { - pub fn into_parachain_template(&self) -> ParachainTemplate { - match self { - Template::Base => ParachainTemplate::Base, - Template::Contracts => ParachainTemplate::Contracts, - Template::FPT => ParachainTemplate::FPT, - } - } -} +use anyhow::Result; +use clap::Args; +use std::{ + fs, + path::{Path, PathBuf}, +}; + +use cliclack::{clear_screen, confirm, input, intro, log, outro, outro_cancel, set_theme}; +use pop_parachains::{instantiate_template_dir, Config, Git, GitHub, Provider, Release, Template}; #[derive(Args)] pub struct NewParachainCommand { - #[arg(help = "Name of the project")] - pub(crate) name: String, + #[arg(help = "Name of the project. If empty assistance in the process will be provided.")] + pub(crate) name: Option, #[arg( - help = "Template to use; Options are 'cpt', 'fpt'. Leave empty for default parachain template" + help = "Template provider. Options are pop or parity (deprecated).", + default_value = "pop" )] - #[arg(default_value = "base")] - pub(crate) template: Template, + pub(crate) provider: Option, + #[arg( + short = 't', + long, + help = "Template to use: 'base' for Pop and 'cpt' and 'fpt' for Parity templates" + )] + pub(crate) template: Option