cargo_tangle/create/
mod.rs

1pub use crate::create::error::Error;
2pub use crate::create::source::Source;
3pub use crate::create::types::BlueprintType;
4use crate::foundry::FoundryToolchain;
5use gadget_sdk::tracing;
6use types::*;
7
8pub mod error;
9pub mod source;
10pub mod types;
11
12pub fn new_blueprint(
13    name: String,
14    source: Option<Source>,
15    blueprint_type: Option<BlueprintType>,
16) -> Result<(), Error> {
17    println!("Generating blueprint with name: {}", name);
18
19    let source = source.unwrap_or_default();
20    let blueprint_variant = blueprint_type
21        .clone()
22        .map(|t| t.get_type())
23        .unwrap_or_default();
24    let template_path_opt: Option<cargo_generate::TemplatePath> = source.into();
25
26    let template_path = template_path_opt.unwrap_or_else(|| {
27        // TODO: Interactive selection (#352)
28        let template_repo: String = match blueprint_variant {
29            Some(BlueprintVariant::Tangle) | None => {
30                "https://github.com/tangle-network/blueprint-template".into()
31            }
32            Some(BlueprintVariant::Eigenlayer(EigenlayerVariant::BLS)) => {
33                "https://github.com/tangle-network/eigenlayer-bls-template".into()
34            }
35            Some(BlueprintVariant::Eigenlayer(EigenlayerVariant::ECDSA)) => {
36                "https://github.com/tangle-network/eigenlayer-ecdsa-template".into()
37            }
38        };
39
40        cargo_generate::TemplatePath {
41            git: Some(template_repo),
42            branch: Some(String::from("main")),
43            ..Default::default()
44        }
45    });
46
47    let path = cargo_generate::generate(cargo_generate::GenerateArgs {
48        template_path,
49        list_favorites: false,
50        name: Some(name.to_string()),
51        force: false,
52        verbose: false,
53        template_values_file: None,
54        silent: false,
55        config: None,
56        vcs: Some(cargo_generate::Vcs::Git),
57        lib: false,
58        bin: true,
59        ssh_identity: None,
60        define: Default::default(),
61        init: false,
62        destination: None,
63        force_git_init: false,
64        allow_commands: false,
65        overwrite: false,
66        skip_submodules: false,
67        other_args: Default::default(),
68    })
69    .map_err(Error::GenerationFailed)?;
70
71    println!("Blueprint generated at: {}", path.display());
72    let contracts = path.join("contracts");
73    if !contracts.exists() {
74        return Ok(());
75    }
76
77    let foundry = FoundryToolchain::new();
78    if !foundry.forge.is_installed() {
79        tracing::warn!("Forge not installed, skipping dependencies");
80        tracing::warn!("NOTE: See <https://getfoundry.sh>");
81        tracing::warn!("NOTE: After installing Forge, you can run `forge soldeer update -d` to install dependencies");
82        return Ok(());
83    }
84
85    std::env::set_current_dir(contracts)?;
86    if let Err(e) = foundry.forge.install_dependencies() {
87        tracing::error!("{e}");
88    }
89
90    Ok(())
91}