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