1use std::{
2 net::IpAddr,
3 path::{Path, PathBuf},
4 str::FromStr,
5};
6
7use anyhow::anyhow;
8use bincode::{Decode, Encode};
9use clap::{Args, Parser, ValueEnum};
10use turbopack_core::issue::IssueSeverity;
11
12#[derive(Debug, Parser)]
13#[clap(author, version, about, long_about = None)]
14pub enum Arguments {
15 Build(BuildArguments),
16 Dev(DevArguments),
17}
18
19impl Arguments {
20 pub fn dir(&self) -> Option<&Path> {
22 match self {
23 Arguments::Build(args) => args.common.dir.as_deref(),
24 Arguments::Dev(args) => args.common.dir.as_deref(),
25 }
26 }
27
28 pub fn worker_threads(&self) -> Option<usize> {
30 match self {
31 Arguments::Build(args) => args.common.worker_threads,
32 Arguments::Dev(args) => args.common.worker_threads,
33 }
34 }
35}
36
37#[turbo_tasks::task_input]
38#[derive(Copy, Clone, Debug, ValueEnum, PartialEq, Eq, Hash, Encode, Decode)]
39pub enum Target {
40 Browser,
41 Node,
42}
43
44#[derive(Debug, Args, Clone)]
45pub struct CommonArguments {
46 #[clap(value_parser)]
49 pub entries: Option<Vec<String>>,
50
51 #[clap(short, long, value_parser)]
54 pub dir: Option<PathBuf>,
55
56 #[clap(long, value_parser)]
60 pub root: Option<PathBuf>,
61
62 #[clap(short, long)]
64 pub log_level: Option<IssueSeverityCliOption>,
65
66 #[clap(long)]
68 pub show_all: bool,
69
70 #[clap(long)]
72 pub log_detail: bool,
73
74 #[clap(long)]
76 pub full_stats: bool,
77
78 #[clap(long)]
80 pub target: Option<Target>,
81
82 #[clap(long)]
84 pub worker_threads: Option<usize>,
85
86 #[clap(long)]
89 pub persistent_caching: bool,
90
91 #[clap(long)]
94 pub cache_dir: Option<PathBuf>,
95 }
100
101#[derive(Debug, Args)]
102#[clap(author, version, about, long_about = None)]
103pub struct DevArguments {
104 #[clap(flatten)]
105 pub common: CommonArguments,
106
107 #[clap(short, long, value_parser, default_value_t = 3000, env = "PORT")]
112 pub port: u16,
113
114 #[clap(short = 'H', long, value_parser, default_value = "0.0.0.0")]
116 pub hostname: IpAddr,
117
118 #[clap(long)]
121 pub eager_compile: bool,
122
123 #[clap(long)]
125 pub no_open: bool,
126
127 #[clap(long)]
133 pub allow_retry: bool,
134}
135
136#[derive(Debug, Args)]
137#[clap(author, version, about, long_about = None)]
138pub struct BuildArguments {
139 #[clap(flatten)]
140 pub common: CommonArguments,
141
142 #[clap(long)]
144 pub no_sourcemap: bool,
145
146 #[clap(long)]
148 pub no_minify: bool,
149
150 #[clap(long)]
152 pub no_scope_hoist: bool,
153
154 #[clap(long, hide = true)]
158 pub force_memory_cleanup: bool,
159}
160
161#[derive(Clone, Copy, PartialEq, Eq, Debug)]
162pub struct IssueSeverityCliOption(pub IssueSeverity);
163
164impl ValueEnum for IssueSeverityCliOption {
165 fn value_variants<'a>() -> &'a [Self] {
166 const VARIANTS: [IssueSeverityCliOption; 8] = [
167 IssueSeverityCliOption(IssueSeverity::Bug),
168 IssueSeverityCliOption(IssueSeverity::Fatal),
169 IssueSeverityCliOption(IssueSeverity::Error),
170 IssueSeverityCliOption(IssueSeverity::Warning),
171 IssueSeverityCliOption(IssueSeverity::Hint),
172 IssueSeverityCliOption(IssueSeverity::Note),
173 IssueSeverityCliOption(IssueSeverity::Suggestion),
174 IssueSeverityCliOption(IssueSeverity::Info),
175 ];
176 &VARIANTS
177 }
178
179 fn to_possible_value<'a>(&self) -> Option<clap::builder::PossibleValue> {
180 Some(clap::builder::PossibleValue::new(self.0.as_str()).help(self.0.as_help_str()))
181 }
182}
183
184impl FromStr for IssueSeverityCliOption {
185 type Err = anyhow::Error;
186
187 fn from_str(s: &str) -> Result<Self, Self::Err> {
188 <IssueSeverityCliOption as clap::ValueEnum>::from_str(s, true).map_err(|s| anyhow!("{}", s))
189 }
190}