use std::{fmt, path::PathBuf};
use clap::{Args, Subcommand, ValueEnum};
use super::{app, kmod, quick_start, rootfs, test};
use crate::context::StarryCliArgs;
#[derive(Subcommand)]
pub enum Command {
Build(ArgsBuild),
Qemu(ArgsQemu),
Defconfig(ArgsDefconfig),
Config(ArgsConfig),
Perf(ArgsPerf),
Test(test::ArgsTest),
App(app::ArgsApp),
Rootfs(rootfs::ArgsRootfs),
#[command(name = "quick-start")]
QuickStart(quick_start::ArgsQuickStart),
Uboot(ArgsUboot),
Board(ArgsBoard),
Kmod(kmod::ArgsKmod),
}
#[derive(Args, Clone)]
pub struct ArgsBuild {
#[arg(short, long)]
pub config: Option<PathBuf>,
#[arg(long)]
pub arch: Option<String>,
#[arg(short, long)]
pub target: Option<String>,
#[arg(long, value_name = "CPUS")]
pub smp: Option<usize>,
#[arg(long)]
pub debug: bool,
}
#[derive(Args)]
pub struct ArgsQemu {
#[command(flatten)]
pub build: ArgsBuild,
#[arg(long)]
pub qemu_config: Option<PathBuf>,
#[arg(long, value_name = "IMAGE")]
pub rootfs: Option<PathBuf>,
}
#[derive(Args, Debug, Clone)]
pub struct ArgsPerf {
#[arg(long, default_value = "boot")]
pub case: String,
#[arg(long)]
pub arch: Option<String>,
#[arg(long, default_value_t = 99)]
pub freq: u32,
#[arg(long = "out", hide = true)]
pub out: Option<PathBuf>,
#[arg(long)]
pub output_dir: Option<PathBuf>,
#[arg(long, value_enum, default_value_t = PerfFormat::All)]
pub format: PerfFormat,
#[arg(long, default_value_t = 128)]
pub max_depth: usize,
#[arg(long, value_name = "SECONDS", default_value_t = 20)]
pub timeout: u64,
#[arg(long, value_enum, default_value_t = PerfMode::Tb)]
pub mode: PerfMode,
#[arg(long, default_value_t = 80)]
pub top: usize,
#[arg(long, default_value_t = 0.3)]
pub min_percent: f64,
#[arg(long)]
pub debug: bool,
#[arg(long)]
pub kernel_filter: bool,
#[arg(long)]
pub host_time: bool,
#[arg(long)]
pub no_host_time: bool,
#[arg(long)]
pub host_perf: bool,
#[arg(
long,
default_value = "task-clock,cycles,instructions,cache-references,cache-misses,\
context-switches,cpu-migrations,page-faults"
)]
pub host_perf_events: String,
#[arg(long, visible_alias = "workload")]
pub shell_init_cmd: Option<String>,
#[arg(long)]
pub shell_prefix: Option<String>,
#[arg(long = "qemu-arg", value_name = "ARG", allow_hyphen_values = true)]
pub qemu_args: Vec<String>,
#[arg(long)]
pub start_marker: Option<String>,
#[arg(long)]
pub stop_marker: Option<String>,
#[arg(long, value_name = "SECONDS")]
pub workload_timeout: Option<u64>,
#[arg(long)]
pub qperf_metrics: bool,
#[arg(long)]
pub flamegraph: bool,
#[arg(long, value_enum, default_value_t = PerfFlamegraphKind::Svg)]
pub flamegraph_kind: PerfFlamegraphKind,
#[arg(long)]
pub full_stack: bool,
#[arg(long = "perf-callchain", visible_alias = "callchain", value_enum)]
pub callchain: Option<PerfCallchain>,
#[arg(long = "perf-debuginfo")]
pub debuginfo: bool,
#[arg(long = "perf-force-frame-pointers")]
pub force_frame_pointers: bool,
#[arg(long)]
pub demangle: bool,
#[arg(long)]
pub no_truncate: bool,
#[arg(long)]
pub include_kernel_symbols: bool,
#[arg(long)]
pub include_user_symbols: bool,
#[arg(long, value_enum, default_value_t = PerfSymbolStyle::Full)]
pub symbol_style: PerfSymbolStyle,
#[arg(long, value_name = "REGEX")]
pub focus: Option<String>,
#[arg(long, value_name = "CPUS")]
pub smp: Option<usize>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum PerfFormat {
Folded,
Svg,
Pprof,
All,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum PerfMode {
Tb,
Insn,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum PerfCallchain {
Leaf,
Fp,
Logical,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum PerfFlamegraphKind {
Svg,
Html,
Folded,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum PerfSymbolStyle {
Full,
Short,
Module,
}
impl fmt::Display for PerfMode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::Tb => "tb",
Self::Insn => "insn",
})
}
}
impl fmt::Display for PerfCallchain {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::Leaf => "leaf",
Self::Fp => "fp",
Self::Logical => "logical",
})
}
}
impl fmt::Display for PerfFlamegraphKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::Svg => "svg",
Self::Html => "html",
Self::Folded => "folded",
})
}
}
impl fmt::Display for PerfSymbolStyle {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::Full => "full",
Self::Short => "short",
Self::Module => "module",
})
}
}
#[derive(Args)]
pub struct ArgsUboot {
#[command(flatten)]
pub build: ArgsBuild,
#[arg(long)]
pub uboot_config: Option<PathBuf>,
}
#[derive(Args)]
pub struct ArgsBoard {
#[command(flatten)]
pub build: ArgsBuild,
#[arg(long = "board-config")]
pub board_config: Option<PathBuf>,
#[arg(short = 'b', long)]
pub board_type: Option<String>,
#[arg(long)]
pub server: Option<String>,
#[arg(long)]
pub port: Option<u16>,
}
#[derive(Args)]
pub struct ArgsDefconfig {
pub board: String,
}
#[derive(Args)]
pub struct ArgsConfig {
#[command(subcommand)]
pub command: ConfigCommand,
}
#[derive(Subcommand)]
pub enum ConfigCommand {
Ls,
}
impl From<&ArgsBuild> for StarryCliArgs {
fn from(args: &ArgsBuild) -> Self {
Self {
config: args.config.clone(),
arch: args.arch.clone(),
target: args.target.clone(),
smp: args.smp,
debug: args.debug,
}
}
}