mod config;
mod output;
mod project;
mod tools;
mod vercel;
use std::path::PathBuf;
use anyhow::Result;
use clap::{Args, Parser, Subcommand};
use crate::project::Project;
use crate::vercel::Vercel;
#[derive(Parser)]
#[command(version, about)]
struct Cli {
#[command(subcommand)]
command: Command,
}
#[derive(Subcommand)]
enum Command {
Build(BuildArgs),
Deploy {
#[command(flatten)]
build: BuildArgs,
#[arg(long)]
prod: bool,
#[arg(long)]
project: Option<String>,
#[arg(long, requires = "project")]
save: bool,
},
}
#[derive(Args)]
struct BuildArgs {
#[arg(long, default_value = ".")]
path: PathBuf,
#[arg(long, short)]
package: Option<String>,
#[arg(long)]
skip_bundle: bool,
#[arg(long)]
no_fallback: bool,
}
fn main() -> Result<()> {
match Cli::parse().command {
Command::Build(args) => {
build(&args)?;
}
Command::Deploy {
build: args,
prod,
project,
save,
} => {
let vercel = Vercel::find()?;
let built = build(&args)?;
let target = project.as_deref().or(built.vercel_project.as_deref());
let created = vercel.deploy(&built.root, prod, target)?;
if let Some(project) = &project {
if save {
config::save_project(&built.manifest_path, project)?;
println!(
"Saved project `{project}` to {}",
built.manifest_path.display()
);
} else if built.vercel_project.as_deref() != Some(project.as_str()) {
println!("Tip: add --save to remember `{project}` in Cargo.toml.");
}
}
if !prod && !created {
println!(
"Note: preview deployments need a Vercel login to view unless you turn off Deployment Protection."
);
}
}
}
Ok(())
}
fn build(args: &BuildArgs) -> Result<Project> {
let project = Project::load(&args.path, args.package.as_deref())?;
if !args.skip_bundle {
let dx = tools::find("dx", "Install it with `cargo install dioxus-cli --locked`.")?;
tools::warn_on_dx_mismatch(&dx, &project.dioxus_version)?;
tools::dx_bundle(&dx, &project.root, args.package.as_deref())?;
}
let out_dir = project.root.join(".vercel").join("output");
let stats = output::write(
&project.dx_public_dir(),
&out_dir,
&output::Options {
fallback: !args.no_fallback,
},
)?;
println!(
"Wrote {} ({} files, {} KB)",
out_dir.display(),
stats.files,
stats.bytes.div_ceil(1024)
);
Ok(project)
}