use crate::{Artifact, Command, artifact::Artifacts, metadata::Metadata, utils};
use anyhow::{Result, anyhow};
use cargo_toml::Manifest;
use clap::Parser;
use colored::Colorize;
use gear_wasm_optimizer::CargoCommand;
use std::{
env, fs,
path::{Path, PathBuf},
};
const DEV_PROFILE: &str = "dev";
const DEBUG_ARTIFACT: &str = "debug";
const RELEASE_PROFILE: &str = "release";
const ARTIFACT_DIR: &str = "gbuild";
#[derive(Parser, Default)]
pub struct GBuild {
#[command(subcommand)]
pub command: Option<Command>,
#[clap(short = 'F', long)]
pub features: Vec<String>,
#[clap(short, long)]
pub manifest_path: Option<PathBuf>,
#[clap(long)]
pub profile: Option<String>,
#[clap(short, long)]
pub release: bool,
#[clap(short, long)]
pub target_dir: Option<PathBuf>,
#[clap(short, long)]
pub workspace: bool,
}
impl GBuild {
pub fn manifest_path(mut self, manifest: PathBuf) -> Self {
self.manifest_path = Some(manifest);
self
}
pub fn workspace(mut self) -> Self {
self.workspace = true;
self
}
pub fn run(self) -> Result<()> {
if let Some(command) = self.command {
command.run()
} else {
self.build().map(|_| ())
}
}
pub fn build(&self) -> Result<Artifacts> {
let manifest_path = self
.manifest_path
.clone()
.unwrap_or(etc::find_up("Cargo.toml")?);
let (artifact, profile) = self.artifact_and_profile();
let metadata =
Metadata::parse(self.workspace, manifest_path.clone(), self.features.clone())?;
let target_dir = self
.target_dir
.clone()
.unwrap_or(metadata.target_directory.clone().into());
let mut kargo = CargoCommand::default();
kargo.set_features(&self.features);
kargo.set_target_dir(target_dir.clone());
if let Some(profile) = profile {
kargo.set_profile(profile);
}
let artifacts = Artifacts::new(
target_dir.join(ARTIFACT_DIR),
target_dir.join("wasm32v1-none").join(artifact),
metadata,
kargo,
)?;
artifacts.process()?;
Ok(artifacts)
}
fn artifact_and_profile(&self) -> (String, Option<String>) {
let mut artifact = DEBUG_ARTIFACT.to_string();
let mut profile: Option<String> = None;
if let Some(p) = &self.profile {
if self.release {
utils::error(
b"conflicting usage of --profile={} and --release
The `--release` flag is the same as `--profile=release`.
Remove one flag or the other to continue.",
);
}
profile = Some(p.to_string());
if p != DEV_PROFILE {
artifact = p.into()
}
} else if self.release {
artifact = RELEASE_PROFILE.into();
profile = Some(artifact.clone());
}
(artifact, profile)
}
}