stellar_scaffold_cli/commands/
mod.rs

1use std::str::FromStr;
2
3use clap::{command, CommandFactory, FromArgMatches, Parser};
4use stellar_cli;
5
6pub mod build;
7pub mod generate;
8pub mod init;
9pub mod update_env;
10pub mod upgrade;
11pub mod version;
12pub mod watch;
13
14const ABOUT: &str = "Build smart contracts with frontend support";
15
16#[derive(Parser, Debug)]
17#[command(
18    name = "stellar-scaffold",
19    about = ABOUT,
20    disable_help_subcommand = true,
21)]
22pub struct Root {
23    #[clap(flatten)]
24    pub global_args: stellar_cli::commands::global::Args,
25
26    #[command(subcommand)]
27    pub cmd: Cmd,
28}
29
30impl Root {
31    pub fn new() -> Result<Self, clap::Error> {
32        let mut matches = Self::command().get_matches();
33        Self::from_arg_matches_mut(&mut matches)
34    }
35
36    pub fn from_arg_matches<I, T>(itr: I) -> Result<Self, clap::Error>
37    where
38        I: IntoIterator<Item = T>,
39        T: Into<std::ffi::OsString> + Clone,
40    {
41        Self::from_arg_matches_mut(&mut Self::command().get_matches_from(itr))
42    }
43    pub async fn run(&mut self) -> Result<(), Error> {
44        match &mut self.cmd {
45            Cmd::Init(init_info) => init_info.run(&self.global_args).await?,
46            Cmd::Version(version_info) => version_info.run(),
47            Cmd::Build(build_info) => build_info.run(&self.global_args).await?,
48            Cmd::Generate(generate) => match &mut generate.cmd {
49                generate::Command::Contract(contract) => contract.run(&self.global_args).await?,
50            },
51            Cmd::Upgrade(upgrade_info) => upgrade_info.run(&self.global_args).await?,
52            Cmd::UpdateEnv(e) => e.run()?,
53            Cmd::Watch(watch_info) => watch_info.run(&self.global_args).await?,
54        }
55        Ok(())
56    }
57}
58
59impl FromStr for Root {
60    type Err = clap::Error;
61
62    fn from_str(s: &str) -> Result<Self, Self::Err> {
63        Self::from_arg_matches(s.split_whitespace())
64    }
65}
66
67#[derive(Parser, Debug)]
68pub enum Cmd {
69    /// Initialize the project
70    Init(init::Cmd),
71    /// Version of the scaffold-stellar-cli
72    Version(version::Cmd),
73
74    /// Build contracts, resolving dependencies in the correct order. If you have an `environments.toml` file, it will also follow its instructions to configure the environment set by the `STELLAR_SCAFFOLD_ENV` environment variable, turning your contracts into frontend packages (NPM dependencies).
75    Build(build::Command),
76
77    /// generate contracts
78    Generate(generate::Cmd),
79
80    /// Upgrade an existing Soroban workspace to a scaffold project
81    Upgrade(upgrade::Cmd),
82
83    /// Update an environment variable in a .env file
84    UpdateEnv(update_env::Cmd),
85
86    /// Monitor contracts and environments.toml for changes and rebuild as needed
87    Watch(watch::Cmd),
88}
89
90#[derive(thiserror::Error, Debug)]
91pub enum Error {
92    // TODO: stop using Debug for displaying errors
93    #[error(transparent)]
94    Init(#[from] init::Error),
95    #[error(transparent)]
96    BuildContracts(#[from] build::Error),
97    #[error(transparent)]
98    Contract(#[from] generate::contract::Error),
99    #[error(transparent)]
100    Upgrade(#[from] upgrade::Error),
101    #[error(transparent)]
102    UpdateEnv(#[from] update_env::Error),
103    #[error(transparent)]
104    Watch(#[from] watch::Error),
105}
106
107pub fn npm_cmd() -> &'static str {
108    if cfg!(target_os = "windows") {
109        "npm.cmd"
110    } else {
111        "npm"
112    }
113}