Skip to content

Commit 8e4d260

Browse files
committed
refactor: deduplicate cli_options retrieval and unify stream filter functions
Extract repeated `self.cli_options.as_ref().ok_or_else(...)` pattern (9 occurrences) into a `cli_options()` helper method on SubcommandResolver. Merge `resolve_and_execute_with_stdout_filter` and `resolve_and_execute_with_stderr_filter` into a single `resolve_and_execute_with_filter` that takes a `FilterStream` enum.
1 parent 91f56f2 commit 8e4d260

File tree

3 files changed

+41
-74
lines changed

3 files changed

+41
-74
lines changed

packages/cli/binding/src/cli/execution.rs

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -65,56 +65,45 @@ pub(super) async fn resolve_and_execute(
6565
Ok(ExitStatus(status.code().unwrap_or(1) as u8))
6666
}
6767

68-
/// Like `resolve_and_execute`, but captures stdout, applies a text filter,
69-
/// and writes the result to real stdout. Stderr remains inherited.
70-
pub(super) async fn resolve_and_execute_with_stdout_filter(
71-
resolver: &SubcommandResolver,
72-
subcommand: SynthesizableSubcommand,
73-
resolved_vite_config: Option<&ResolvedUniversalViteConfig>,
74-
envs: &Arc<FxHashMap<Arc<OsStr>, Arc<OsStr>>>,
75-
cwd: &AbsolutePathBuf,
76-
cwd_arc: &Arc<AbsolutePath>,
77-
filter: impl Fn(&str) -> Cow<'_, str>,
78-
) -> Result<ExitStatus, Error> {
79-
let mut cmd =
80-
resolve_and_build_command(resolver, subcommand, resolved_vite_config, envs, cwd, cwd_arc)
81-
.await?;
82-
cmd.stdout(Stdio::piped());
83-
84-
let child = cmd.spawn().map_err(|e| Error::Anyhow(e.into()))?;
85-
let output = child.wait_with_output().await.map_err(|e| Error::Anyhow(e.into()))?;
86-
87-
use std::io::Write;
88-
let stdout = String::from_utf8_lossy(&output.stdout);
89-
let filtered = filter(&stdout);
90-
let _ = std::io::stdout().lock().write_all(filtered.as_bytes());
91-
92-
Ok(ExitStatus(output.status.code().unwrap_or(1) as u8))
68+
pub(super) enum FilterStream {
69+
Stdout,
70+
Stderr,
9371
}
9472

95-
/// Like `resolve_and_execute`, but captures stderr, applies a text filter,
96-
/// and writes the result to real stderr. Stdout remains inherited (streaming).
97-
pub(super) async fn resolve_and_execute_with_stderr_filter(
73+
/// Like `resolve_and_execute`, but captures one stream (stdout or stderr),
74+
/// applies a text filter, and writes the result back. The other stream remains inherited.
75+
pub(super) async fn resolve_and_execute_with_filter(
9876
resolver: &SubcommandResolver,
9977
subcommand: SynthesizableSubcommand,
10078
resolved_vite_config: Option<&ResolvedUniversalViteConfig>,
10179
envs: &Arc<FxHashMap<Arc<OsStr>, Arc<OsStr>>>,
10280
cwd: &AbsolutePathBuf,
10381
cwd_arc: &Arc<AbsolutePath>,
82+
stream: FilterStream,
10483
filter: impl Fn(&str) -> Cow<'_, str>,
10584
) -> Result<ExitStatus, Error> {
10685
let mut cmd =
10786
resolve_and_build_command(resolver, subcommand, resolved_vite_config, envs, cwd, cwd_arc)
10887
.await?;
109-
cmd.stderr(Stdio::piped());
88+
match stream {
89+
FilterStream::Stdout => cmd.stdout(Stdio::piped()),
90+
FilterStream::Stderr => cmd.stderr(Stdio::piped()),
91+
};
11092

11193
let child = cmd.spawn().map_err(|e| Error::Anyhow(e.into()))?;
11294
let output = child.wait_with_output().await.map_err(|e| Error::Anyhow(e.into()))?;
11395

11496
use std::io::Write;
115-
let stderr = String::from_utf8_lossy(&output.stderr);
116-
let filtered = filter(&stderr);
117-
let _ = std::io::stderr().lock().write_all(filtered.as_bytes());
97+
match stream {
98+
FilterStream::Stdout => {
99+
let text = String::from_utf8_lossy(&output.stdout);
100+
let _ = std::io::stdout().lock().write_all(filter(&text).as_bytes());
101+
}
102+
FilterStream::Stderr => {
103+
let text = String::from_utf8_lossy(&output.stderr);
104+
let _ = std::io::stderr().lock().write_all(filter(&text).as_bytes());
105+
}
106+
}
118107

119108
Ok(ExitStatus(output.status.code().unwrap_or(1) as u8))
120109
}

packages/cli/binding/src/cli/mod.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,7 @@ use vite_str::Str;
3030
use vite_task::{ExitStatus, Session, SessionConfig};
3131

3232
use self::{
33-
execution::{
34-
resolve_and_execute, resolve_and_execute_with_stderr_filter,
35-
resolve_and_execute_with_stdout_filter,
36-
},
33+
execution::{FilterStream, resolve_and_execute, resolve_and_execute_with_filter},
3734
handler::{VitePlusCommandHandler, VitePlusConfigLoader},
3835
help::{
3936
handle_cli_parse_error, normalize_help_args, print_help, should_print_help,
@@ -74,24 +71,26 @@ async fn execute_direct_subcommand(
7471
}
7572
other => {
7673
if should_suppress_subcommand_stdout(&other) {
77-
resolve_and_execute_with_stdout_filter(
74+
resolve_and_execute_with_filter(
7875
&resolver,
7976
other,
8077
None,
8178
&envs,
8279
cwd,
8380
&cwd_arc,
81+
FilterStream::Stdout,
8482
|_| Cow::Borrowed(""),
8583
)
8684
.await?
8785
} else if matches!(&other, SynthesizableSubcommand::Fmt { .. }) {
88-
resolve_and_execute_with_stderr_filter(
86+
resolve_and_execute_with_filter(
8987
&resolver,
9088
other,
9189
None,
9290
&envs,
9391
cwd,
9492
&cwd_arc,
93+
FilterStream::Stderr,
9594
|s| s.cow_replace("oxfmt --init", "vp fmt --init"),
9695
)
9796
.await?

packages/cli/binding/src/cli/resolver.rs

Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,16 @@ impl SubcommandResolver {
3838
self
3939
}
4040

41+
fn cli_options(&self) -> anyhow::Result<&CliOptions> {
42+
self.cli_options
43+
.as_ref()
44+
.ok_or_else(|| anyhow::anyhow!("CLI options not available (running without NAPI?)"))
45+
}
46+
4147
pub(crate) async fn resolve_universal_vite_config(
4248
&self,
4349
) -> anyhow::Result<ResolvedUniversalViteConfig> {
44-
let cli_options = self
45-
.cli_options
46-
.as_ref()
47-
.ok_or_else(|| anyhow::anyhow!("CLI options required for vite config resolution"))?;
50+
let cli_options = self.cli_options()?;
4851
let workspace_path_str = self
4952
.workspace_path
5053
.as_path()
@@ -68,10 +71,7 @@ impl SubcommandResolver {
6871
) -> anyhow::Result<ResolvedSubcommand> {
6972
match subcommand {
7073
SynthesizableSubcommand::Lint { mut args } => {
71-
let cli_options = self
72-
.cli_options
73-
.as_ref()
74-
.ok_or_else(|| anyhow::anyhow!("CLI options required for lint command"))?;
74+
let cli_options = self.cli_options()?;
7575
let resolved = (cli_options.lint)().await?;
7676
let js_path = resolved.bin_path;
7777
let js_path_str = js_path
@@ -107,10 +107,7 @@ impl SubcommandResolver {
107107
})
108108
}
109109
SynthesizableSubcommand::Fmt { mut args } => {
110-
let cli_options = self
111-
.cli_options
112-
.as_ref()
113-
.ok_or_else(|| anyhow::anyhow!("CLI options required for fmt command"))?;
110+
let cli_options = self.cli_options()?;
114111
let resolved = (cli_options.fmt)().await?;
115112
let js_path = resolved.bin_path;
116113
let js_path_str = js_path
@@ -145,10 +142,7 @@ impl SubcommandResolver {
145142
})
146143
}
147144
SynthesizableSubcommand::Build { args } => {
148-
let cli_options = self
149-
.cli_options
150-
.as_ref()
151-
.ok_or_else(|| anyhow::anyhow!("CLI options required for build command"))?;
145+
let cli_options = self.cli_options()?;
152146
let resolved = (cli_options.vite)().await?;
153147
let js_path = resolved.bin_path;
154148
let js_path_str = js_path
@@ -170,10 +164,7 @@ impl SubcommandResolver {
170164
})
171165
}
172166
SynthesizableSubcommand::Test { args } => {
173-
let cli_options = self
174-
.cli_options
175-
.as_ref()
176-
.ok_or_else(|| anyhow::anyhow!("CLI options required for test command"))?;
167+
let cli_options = self.cli_options()?;
177168
let resolved = (cli_options.test)().await?;
178169
let js_path = resolved.bin_path;
179170
let js_path_str = js_path
@@ -205,10 +196,7 @@ impl SubcommandResolver {
205196
})
206197
}
207198
SynthesizableSubcommand::Pack { args } => {
208-
let cli_options = self
209-
.cli_options
210-
.as_ref()
211-
.ok_or_else(|| anyhow::anyhow!("CLI options required for pack command"))?;
199+
let cli_options = self.cli_options()?;
212200
let resolved = (cli_options.pack)().await?;
213201
let js_path = resolved.bin_path;
214202
let js_path_str = js_path
@@ -229,10 +217,7 @@ impl SubcommandResolver {
229217
})
230218
}
231219
SynthesizableSubcommand::Dev { args } => {
232-
let cli_options = self
233-
.cli_options
234-
.as_ref()
235-
.ok_or_else(|| anyhow::anyhow!("CLI options required for dev command"))?;
220+
let cli_options = self.cli_options()?;
236221
let resolved = (cli_options.vite)().await?;
237222
let js_path = resolved.bin_path;
238223
let js_path_str = js_path
@@ -250,10 +235,7 @@ impl SubcommandResolver {
250235
})
251236
}
252237
SynthesizableSubcommand::Preview { args } => {
253-
let cli_options = self
254-
.cli_options
255-
.as_ref()
256-
.ok_or_else(|| anyhow::anyhow!("CLI options required for preview command"))?;
238+
let cli_options = self.cli_options()?;
257239
let resolved = (cli_options.vite)().await?;
258240
let js_path = resolved.bin_path;
259241
let js_path_str = js_path
@@ -271,10 +253,7 @@ impl SubcommandResolver {
271253
})
272254
}
273255
SynthesizableSubcommand::Doc { args } => {
274-
let cli_options = self
275-
.cli_options
276-
.as_ref()
277-
.ok_or_else(|| anyhow::anyhow!("CLI options required for doc command"))?;
256+
let cli_options = self.cli_options()?;
278257
let resolved = (cli_options.doc)().await?;
279258
let js_path = resolved.bin_path;
280259
let js_path_str = js_path

0 commit comments

Comments
 (0)