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(templates): Make templates and providers generic #226

Merged
merged 16 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion crates/pop-cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use crate::{cache, cli::Cli};
use clap::Subcommand;
use pop_common::templates::Template;
use serde_json::{json, Value};

pub(crate) mod build;
Expand Down Expand Up @@ -56,7 +57,7 @@ impl Command {
Ok(template) => {
// telemetry should never cause a panic or early exit
Ok(
json!({template.provider().unwrap_or("provider-missing"): template.name()}),
json!({template.template_type().unwrap_or("provider-missing"): template.name()}),
peterwht marked this conversation as resolved.
Show resolved Hide resolved
)
},
Err(e) => Err(e),
Expand Down
22 changes: 13 additions & 9 deletions crates/pop-cli/src/commands/new/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ use clap::{
};
use cliclack::{clear_screen, confirm, input, intro, log::success, outro, outro_cancel, set_theme};
use console::style;
use pop_contracts::{create_smart_contract, is_valid_contract_name, ContractType, Template};
use pop_common::{
enum_variants,
templates::{Template, Type},
};
use pop_contracts::{create_smart_contract, is_valid_contract_name, Contract, ContractType};
use std::{env::current_dir, fs, path::PathBuf, str::FromStr};
use strum::VariantArray;

Expand All @@ -21,7 +25,7 @@ pub struct NewContractCommand {
short = 'c',
long,
help = "Contract type.",
value_parser = crate::enum_variants!(ContractType)
value_parser = enum_variants!(ContractType)
)]
pub(crate) contract_type: Option<ContractType>,
#[arg(short = 'p', long, help = "Path for the contract project, [default: current directory]")]
Expand All @@ -30,9 +34,9 @@ pub struct NewContractCommand {
short = 't',
long,
help = "Template to use.",
value_parser = crate::enum_variants!(Template)
value_parser = enum_variants!(Contract)
)]
pub(crate) template: Option<Template>,
pub(crate) template: Option<Contract>,
}

impl NewContractCommand {
Expand All @@ -54,7 +58,7 @@ impl NewContractCommand {
let contract_type = &contract_config.contract_type.clone().unwrap_or_default();
let template = match &contract_config.template {
Some(template) => template.clone(),
None => contract_type.default_type(), // Default contract type
None => contract_type.default_template().expect("contract types have defaults; qed."), // Default contract type
};

is_template_supported(contract_type, &template)?;
Expand All @@ -64,8 +68,8 @@ impl NewContractCommand {
}
}

fn is_template_supported(contract_type: &ContractType, template: &Template) -> Result<()> {
if !template.matches(contract_type) {
fn is_template_supported(contract_type: &ContractType, template: &Contract) -> Result<()> {
if !contract_type.provides(template) {
return Err(anyhow::anyhow!(format!(
"The contract type \"{:?}\" doesn't support the {:?} template.",
contract_type, template
Expand Down Expand Up @@ -113,7 +117,7 @@ async fn guide_user_to_generate_contract() -> anyhow::Result<NewContractCommand>
})
}

fn display_select_options(contract_type: &ContractType) -> Result<&Template> {
fn display_select_options(contract_type: &ContractType) -> Result<&Contract> {
let mut prompt = cliclack::select("Select the contract:".to_string());
for (i, template) in contract_type.templates().into_iter().enumerate() {
if i == 0 {
Expand All @@ -127,7 +131,7 @@ fn display_select_options(contract_type: &ContractType) -> Result<&Template> {
fn generate_contract_from_template(
name: &String,
path: Option<PathBuf>,
template: &Template,
template: &Contract,
) -> anyhow::Result<()> {
intro(format!(
"{}: Generating \"{}\" using {}!",
Expand Down
4 changes: 1 addition & 3 deletions crates/pop-cli/src/commands/new/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ macro_rules! enum_variants {
.map(|p| PossibleValue::new(p.as_ref()))
.collect::<Vec<_>>(),
)
.try_map(|s| {
<$e>::from_str(&s).map_err(|e| format!("could not convert from {s} to provider"))
})
.try_map(|s| <$e>::from_str(&s).map_err(|e| format!("could not convert from {s} to type")))
}};
}

Expand Down
56 changes: 30 additions & 26 deletions crates/pop-cli/src/commands/new/parachain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ use cliclack::{
log::{self, success, warning},
outro, outro_cancel, set_theme,
};
use pop_common::{Git, GitHub, Release};
use pop_common::{
enum_variants,
templates::{Template, Type},
Git, GitHub, Release,
};
use pop_parachains::{
instantiate_template_dir, is_initial_endowment_valid, Config, Provider, Template,
instantiate_template_dir, is_initial_endowment_valid, Config, Parachain, Provider,
};
use strum::VariantArray;

Expand All @@ -28,16 +32,16 @@ pub struct NewParachainCommand {
#[arg(
help = "Template provider.",
default_value = Provider::Pop.as_ref(),
value_parser = crate::enum_variants!(Provider)
value_parser = enum_variants!(Provider)
)]
pub(crate) provider: Option<Provider>,
#[arg(
short = 't',
long,
help = "Template to use.",
value_parser = crate::enum_variants!(Template)
value_parser = enum_variants!(Parachain)
)]
pub(crate) template: Option<Template>,
pub(crate) template: Option<Parachain>,
#[arg(
short = 'r',
long,
Expand All @@ -59,7 +63,7 @@ pub struct NewParachainCommand {

impl NewParachainCommand {
/// Executes the command.
pub(crate) async fn execute(self) -> Result<Template> {
pub(crate) async fn execute(self) -> Result<Parachain> {
clear_screen()?;
set_theme(Theme);

Expand All @@ -77,7 +81,7 @@ impl NewParachainCommand {
let provider = &parachain_config.provider.clone().unwrap_or_default();
let template = match &parachain_config.template {
Some(template) => template.clone(),
None => provider.default_template(), // Each provider has a template by default
None => provider.default_template().expect("parachain templates have defaults; qed."), // Each provider has a template by default
};

is_template_supported(provider, &template)?;
Expand All @@ -99,7 +103,7 @@ async fn guide_user_to_generate_parachain() -> Result<NewParachainCommand> {
intro(format!("{}: Generate a parachain", style(" Pop CLI ").black().on_magenta()))?;

let mut prompt = cliclack::select("Select a template provider: ".to_string());
for (i, provider) in Provider::providers().iter().enumerate() {
for (i, provider) in Provider::types().iter().enumerate() {
if i == 0 {
prompt = prompt.initial_value(provider);
}
Expand Down Expand Up @@ -129,7 +133,7 @@ async fn guide_user_to_generate_parachain() -> Result<NewParachainCommand> {
decimals: 12,
initial_endowment: "1u64 << 60".to_string(),
};
if template.matches(&Provider::Pop) {
if Provider::Pop.provides(&template) {
customizable_options = prompt_customizable_options()?;
}

Expand All @@ -149,7 +153,7 @@ async fn guide_user_to_generate_parachain() -> Result<NewParachainCommand> {
fn generate_parachain_from_template(
name_template: &String,
provider: &Provider,
template: &Template,
template: &Parachain,
tag_version: Option<String>,
config: Config,
) -> Result<()> {
Expand Down Expand Up @@ -211,8 +215,8 @@ fn generate_parachain_from_template(
Ok(())
}

fn is_template_supported(provider: &Provider, template: &Template) -> Result<()> {
if !template.matches(provider) {
fn is_template_supported(provider: &Provider, template: &Parachain) -> Result<()> {
if !provider.provides(template) {
return Err(anyhow::anyhow!(format!(
"The provider \"{:?}\" doesn't support the {:?} template.",
provider, template
Expand All @@ -221,7 +225,7 @@ fn is_template_supported(provider: &Provider, template: &Template) -> Result<()>
return Ok(());
}

fn display_select_options(provider: &Provider) -> Result<&Template> {
fn display_select_options(provider: &Provider) -> Result<&Parachain> {
let mut prompt = cliclack::select("Select the type of parachain:".to_string());
for (i, template) in provider.templates().into_iter().enumerate() {
if i == 0 {
Expand All @@ -233,12 +237,12 @@ fn display_select_options(provider: &Provider) -> Result<&Template> {
}

fn get_customization_value(
template: &Template,
template: &Parachain,
symbol: Option<String>,
decimals: Option<u8>,
initial_endowment: Option<String>,
) -> Result<Config> {
if !matches!(template, Template::Standard)
if !matches!(template, Parachain::Standard)
&& (symbol.is_some() || decimals.is_some() || initial_endowment.is_some())
{
log::warning("Customization options are not available for this template")?;
Expand Down Expand Up @@ -277,7 +281,7 @@ fn check_destination_path(name_template: &String) -> Result<&Path> {
/// Otherwise, the default release is used.
///
/// return: `Option<String>` - The release name selected by the user or None if no releases found.
async fn choose_release(template: &Template) -> Result<Option<String>> {
async fn choose_release(template: &Parachain) -> Result<Option<String>> {
let url = url::Url::parse(&template.repository_url()?).expect("valid repository url");
let repo = GitHub::parse(url.as_str())?;

Expand Down Expand Up @@ -376,7 +380,7 @@ mod tests {

use super::*;
use crate::{
commands::new::{Command::Parachain, NewArgs},
commands::new::{Command::Parachain as ParachainCommand, NewArgs},
Cli,
Command::New,
};
Expand All @@ -394,7 +398,7 @@ mod tests {
dir.path().join("test_parachain").to_str().unwrap(),
]);

let New(NewArgs { command: Parachain(command) }) = cli.command else {
let New(NewArgs { command: ParachainCommand(command) }) = cli.command else {
panic!("unable to parse command")
};
// Execute
Expand All @@ -414,7 +418,7 @@ mod tests {
let command = NewParachainCommand {
name: Some(name.clone()),
provider: Some(Provider::Pop),
template: Some(Template::Standard),
template: Some(Parachain::Standard),
release_tag: None,
symbol: Some("UNIT".to_string()),
decimals: Some(12),
Expand All @@ -432,19 +436,19 @@ mod tests {

#[test]
fn test_is_template_supported() -> Result<()> {
is_template_supported(&Provider::Pop, &Template::Standard)?;
assert!(is_template_supported(&Provider::Pop, &Template::ParityContracts).is_err());
assert!(is_template_supported(&Provider::Pop, &Template::ParityFPT).is_err());
is_template_supported(&Provider::Pop, &Parachain::Standard)?;
assert!(is_template_supported(&Provider::Pop, &Parachain::ParityContracts).is_err());
assert!(is_template_supported(&Provider::Pop, &Parachain::ParityFPT).is_err());

assert!(is_template_supported(&Provider::Parity, &Template::Standard).is_err());
is_template_supported(&Provider::Parity, &Template::ParityContracts)?;
is_template_supported(&Provider::Parity, &Template::ParityFPT)
assert!(is_template_supported(&Provider::Parity, &Parachain::Standard).is_err());
is_template_supported(&Provider::Parity, &Parachain::ParityContracts)?;
is_template_supported(&Provider::Parity, &Parachain::ParityFPT)
}

#[test]
fn test_get_customization_values() -> Result<()> {
let config = get_customization_value(
&Template::Standard,
&Parachain::Standard,
Some("DOT".to_string()),
Some(6),
Some("10000".to_string()),
Expand Down
3 changes: 2 additions & 1 deletion crates/pop-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ regex.workspace = true
reqwest.workspace = true
serde_json.workspace = true
serde.workspace = true
strum.workspace = true
thiserror.workspace = true
tokio.workspace = true
url.workspace = true

[dev-dependencies]
mockito.workspace = true
tempfile.workspace = true
tempfile.workspace = true
5 changes: 5 additions & 0 deletions crates/pop-common/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

use thiserror::Error;

use crate::templates;

#[derive(Error, Debug)]
pub enum Error {
#[error("Configuration error: {0}")]
Expand All @@ -15,4 +17,7 @@ pub enum Error {

#[error("ParseError error: {0}")]
ParseError(#[from] url::ParseError),

#[error("TemplateError error: {0}")]
TemplateError(#[from] templates::Error),
}
1 change: 1 addition & 0 deletions crates/pop-common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod errors;
pub mod git;
pub mod helpers;
pub mod templates;

pub use errors::Error;
pub use git::{Git, GitHub, Release};
Expand Down
Loading
Loading