tuono/
cli.rs

1use clap::{Parser, Subcommand};
2use tracing::{Level, span};
3
4use crate::commands::{build, dev, new};
5use crate::mode::Mode;
6use crate::source_builder::SourceBuilder;
7
8#[derive(Subcommand, Debug)]
9enum Actions {
10    /// Start the development environment
11    Dev,
12    /// Build the production assets
13    Build {
14        #[arg(short, long = "static")]
15        /// Statically generate the website HTML
16        ssg: bool,
17
18        #[arg(short, long)]
19        /// Prevent to export the js assets
20        no_js_emit: bool,
21    },
22    /// Scaffold a new project
23    New {
24        /// The folder in which load the project. Default is the current directory.
25        folder_name: Option<String>,
26        /// The template to use to scaffold the project. The template should match one of the tuono
27        /// examples
28        #[arg(short, long)]
29        template: Option<String>,
30        /// Load the latest commit available on the main branch
31        #[arg(long)]
32        head: Option<bool>,
33    },
34}
35
36#[derive(Parser, Debug)]
37#[command(version, about = "The React/Rust full-stack framework")]
38struct Args {
39    #[command(subcommand)]
40    action: Actions,
41}
42
43pub fn app() -> std::io::Result<()> {
44    let args = Args::parse();
45
46    match args.action {
47        Actions::Dev => {
48            let span = span!(Level::TRACE, "DEV");
49
50            let _guard = span.enter();
51
52            let mut source_builder = SourceBuilder::new(Mode::Dev)?;
53
54            source_builder.base_build()?;
55
56            source_builder.app.check_server_availability(Mode::Dev);
57
58            dev::watch(source_builder).unwrap();
59        }
60        Actions::Build { ssg, no_js_emit } => {
61            let span = span!(Level::TRACE, "BUILD");
62
63            let _guard = span.enter();
64
65            let mut source_builder = SourceBuilder::new(Mode::Prod)?;
66            source_builder.base_build()?;
67            build::build(source_builder.app, ssg, no_js_emit);
68        }
69        Actions::New {
70            folder_name,
71            template,
72            head,
73        } => {
74            let span = span!(Level::TRACE, "NEW");
75
76            let _guard = span.enter();
77
78            new::create_new_project(folder_name, template, head);
79        }
80    }
81
82    Ok(())
83}