Skip to content

Commit acac963

Browse files
authored
internal: refactor cli commands (#682)
1 parent aef9f3f commit acac963

File tree

5 files changed

+193
-141
lines changed

5 files changed

+193
-141
lines changed

crates/squawk/src/cmd.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
use std::{path::PathBuf, process};
2+
3+
use crate::{
4+
Command, config::Config, debug::DebugArgs, file_finding::find_paths, reporter::LintArgs,
5+
};
6+
7+
pub(crate) struct Stdin {
8+
pub(crate) path: Option<String>,
9+
}
10+
11+
pub(crate) enum Input {
12+
Stdin(Stdin),
13+
Paths(Vec<PathBuf>),
14+
}
15+
16+
pub(crate) enum Cmd {
17+
Debug(DebugArgs),
18+
Lint(LintArgs),
19+
Help,
20+
None,
21+
Server,
22+
UploadToGithub(Box<Config>),
23+
}
24+
25+
impl Cmd {
26+
fn resolve_cli(conf: Config) -> Cmd {
27+
// TODO: do we need to do the same thing for the github command?
28+
let found_paths =
29+
find_paths(&conf.path_patterns, &conf.excluded_paths).unwrap_or_else(|e| {
30+
eprintln!("Failed to find files: {e}");
31+
process::exit(1);
32+
});
33+
if found_paths.is_empty() && !conf.path_patterns.is_empty() {
34+
eprintln!(
35+
"Failed to find files for provided patterns: {:?}",
36+
conf.path_patterns
37+
);
38+
if !conf.no_error_on_unmatched_pattern {
39+
process::exit(1);
40+
}
41+
}
42+
if !found_paths.is_empty() || conf.is_stdin {
43+
let read_stdin = found_paths.is_empty() && conf.is_stdin;
44+
let input = if read_stdin {
45+
Input::Stdin(Stdin {
46+
path: conf.stdin_filepath,
47+
})
48+
} else {
49+
Input::Paths(found_paths)
50+
};
51+
if let Some(debug_option) = conf.debug {
52+
return Cmd::Debug(DebugArgs {
53+
input,
54+
debug_option,
55+
verbose: conf.verbose,
56+
});
57+
} else {
58+
return Cmd::Lint(LintArgs {
59+
input,
60+
excluded_rules: conf.excluded_rules,
61+
pg_version: conf.pg_version,
62+
assume_in_transaction: conf.assume_in_transaction,
63+
reporter: conf.reporter,
64+
github_annotations: conf.github_annotations,
65+
});
66+
}
67+
} else if !conf.no_error_on_unmatched_pattern {
68+
return Cmd::Help;
69+
} else {
70+
return Cmd::None;
71+
}
72+
}
73+
74+
pub(crate) fn from(opts: crate::Opts) -> Cmd {
75+
match opts.cmd {
76+
Some(Command::Server) => Cmd::Server,
77+
Some(Command::UploadToGithub(_)) => {
78+
let conf = Config::from(opts);
79+
Cmd::UploadToGithub(Box::new(conf))
80+
}
81+
None => {
82+
let conf = Config::from(opts);
83+
Cmd::resolve_cli(conf)
84+
}
85+
}
86+
}
87+
}

crates/squawk/src/debug.rs

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{io, path::PathBuf};
1+
use std::io;
22

33
use annotate_snippets::{AnnotationKind, Level, Renderer, Snippet, renderer::DecorStyle};
44
use anyhow::Result;
@@ -7,23 +7,24 @@ use squawk_syntax::{ast::AstNode, syntax_error::SyntaxError};
77

88
use crate::{
99
DebugOption,
10+
cmd::Input,
1011
file::{sql_from_path, sql_from_stdin},
1112
};
1213

13-
pub(crate) fn debug<W: io::Write>(
14-
f: &mut W,
15-
paths: &[PathBuf],
16-
read_stdin: bool,
17-
debug_option: &DebugOption,
18-
verbose: bool,
19-
) -> Result<()> {
14+
pub(crate) struct DebugArgs {
15+
pub(crate) input: Input,
16+
pub(crate) debug_option: DebugOption,
17+
pub(crate) verbose: bool,
18+
}
19+
20+
pub(crate) fn debug<W: io::Write>(f: &mut W, args: DebugArgs) -> Result<()> {
2021
let process_dump_ast = |sql: &str, filename: &str, f: &mut W| -> Result<()> {
21-
match debug_option {
22+
match args.debug_option {
2223
DebugOption::Lex => {
2324
let tokens = squawk_lexer::tokenize(sql);
2425
let mut start = 0;
2526
for token in tokens {
26-
if verbose {
27+
if args.verbose {
2728
let content = &sql[start as usize..(start + token.len) as usize];
2829
start += token.len;
2930
writeln!(f, "{content:?} @ {:?}", token.kind)?;
@@ -34,7 +35,7 @@ pub(crate) fn debug<W: io::Write>(
3435
}
3536
DebugOption::Parse => {
3637
let parse = squawk_syntax::SourceFile::parse(sql);
37-
if verbose {
38+
if args.verbose {
3839
writeln!(f, "{}\n---", parse.syntax_node())?;
3940
}
4041
writeln!(f, "{:#?}", parse.syntax_node())?;
@@ -65,16 +66,20 @@ pub(crate) fn debug<W: io::Write>(
6566
}
6667
Ok(())
6768
};
68-
if read_stdin {
69-
let sql = sql_from_stdin()?;
70-
process_dump_ast(&sql, "stdin", f)?;
71-
return Ok(());
72-
}
7369

74-
for path in paths {
75-
let sql = sql_from_path(path)?;
76-
process_dump_ast(&sql, &path.to_string_lossy(), f)?;
77-
}
70+
match args.input {
71+
Input::Stdin(_) => {
72+
let sql = sql_from_stdin()?;
73+
process_dump_ast(&sql, "stdin", f)?;
74+
}
75+
Input::Paths(path_bufs) => {
76+
for path in path_bufs {
77+
let sql = sql_from_path(&path)?;
78+
process_dump_ast(&sql, &path.to_string_lossy(), f)?;
79+
}
80+
}
81+
};
82+
7883
Ok(())
7984
}
8085

crates/squawk/src/github.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
use crate::UploadToGithubArgs;
1+
use crate::cmd::Input;
22
use crate::config::Config;
33
use crate::reporter::{CheckReport, fmt_github_annotations, fmt_tty_violation};
4-
use crate::{file_finding::find_paths, reporter::check_files};
4+
use crate::{LintArgs, UploadToGithubArgs};
5+
use crate::{file_finding::find_paths, reporter::lint_files};
56
use anyhow::{Context, Result, anyhow, bail};
67
use console::strip_ansi_codes;
78
use log::info;
@@ -117,14 +118,14 @@ pub fn check_and_comment_on_pr(cfg: Config) -> Result<()> {
117118
let found_paths = find_paths(&paths, &cfg.excluded_paths)?;
118119

119120
info!("checking files");
120-
let file_results = check_files(
121-
&found_paths,
122-
cfg.is_stdin,
123-
&cfg.stdin_filepath,
124-
&cfg.excluded_rules,
125-
cfg.pg_version,
126-
cfg.assume_in_transaction,
127-
)?;
121+
let file_results = lint_files(&LintArgs {
122+
input: Input::Paths(found_paths),
123+
excluded_rules: cfg.excluded_rules,
124+
pg_version: cfg.pg_version,
125+
assume_in_transaction: cfg.assume_in_transaction,
126+
reporter: cfg.reporter,
127+
github_annotations: cfg.github_annotations,
128+
})?;
128129

129130
// We should only leave a comment when there are files checked.
130131
if paths.is_empty() {

crates/squawk/src/main.rs

Lines changed: 24 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
1+
mod cmd;
12
mod config;
23
mod debug;
34
mod file;
45
mod file_finding;
56
mod github;
67
mod reporter;
7-
use crate::config::Config;
8-
use crate::file_finding::find_paths;
8+
use crate::cmd::Cmd;
9+
use crate::reporter::LintArgs;
910
use anyhow::{Context, Result};
1011
use clap::{CommandFactory, Parser, Subcommand, ValueEnum};
1112
use debug::debug;
12-
use reporter::check_and_dump_files;
13+
use reporter::lint_and_report;
1314
use simplelog::CombinedLogger;
1415
use squawk_linter::{Rule, Version};
1516
use std::io;
1617
use std::panic;
1718
use std::path::PathBuf;
18-
use std::process::{self, ExitCode};
19+
use std::process::ExitCode;
1920

2021
#[derive(Parser, Debug)]
2122
pub struct UploadToGithubArgs {
@@ -182,58 +183,29 @@ Please open an issue at https://github.com/sbdchd/squawk/issues/new with the log
182183
.expect("problem creating logger");
183184
}
184185

185-
match opts.cmd {
186-
Some(Command::Server) => {
186+
match Cmd::from(opts) {
187+
Cmd::Server => {
187188
squawk_server::run().context("language server failed")?;
188189
}
189-
Some(Command::UploadToGithub(_)) => {
190-
let conf = Config::from(opts);
191-
github::check_and_comment_on_pr(conf).context("Upload to GitHub failed")?;
190+
Cmd::UploadToGithub(config) => {
191+
github::check_and_comment_on_pr(*config).context("Upload to GitHub failed")?;
192192
}
193-
None => {
194-
let conf = Config::from(opts);
195-
// TODO: do we need to do the same thing for the github command?
196-
let found_paths =
197-
find_paths(&conf.path_patterns, &conf.excluded_paths).unwrap_or_else(|e| {
198-
eprintln!("Failed to find files: {e}");
199-
process::exit(1);
200-
});
201-
if found_paths.is_empty() && !conf.path_patterns.is_empty() {
202-
eprintln!(
203-
"Failed to find files for provided patterns: {:?}",
204-
conf.path_patterns
205-
);
206-
if !conf.no_error_on_unmatched_pattern {
207-
process::exit(1);
208-
}
209-
}
210-
if !found_paths.is_empty() || conf.is_stdin {
211-
let stdout = io::stdout();
212-
let mut handle = stdout.lock();
213-
214-
let read_stdin = found_paths.is_empty() && conf.is_stdin;
215-
if let Some(kind) = conf.debug {
216-
debug(&mut handle, &found_paths, read_stdin, &kind, conf.verbose)?;
217-
} else {
218-
let reporter = conf.reporter;
219-
let exit_code = check_and_dump_files(
220-
&mut handle,
221-
&found_paths,
222-
read_stdin,
223-
conf.stdin_filepath,
224-
&conf.excluded_rules,
225-
conf.pg_version,
226-
conf.assume_in_transaction,
227-
&reporter,
228-
conf.github_annotations,
229-
)?;
230-
return Ok(exit_code);
231-
}
232-
} else if !conf.no_error_on_unmatched_pattern {
233-
Opts::command().print_long_help()?;
234-
println!();
235-
}
193+
Cmd::Debug(debug_args) => {
194+
let stdout = io::stdout();
195+
let mut handle = stdout.lock();
196+
debug(&mut handle, debug_args)?;
197+
}
198+
Cmd::Lint(lint_args) => {
199+
let stdout = io::stdout();
200+
let mut handle = stdout.lock();
201+
return lint_and_report(&mut handle, lint_args);
236202
}
203+
Cmd::Help => {
204+
Opts::command().print_long_help()?;
205+
println!();
206+
}
207+
Cmd::None => (),
237208
}
209+
238210
Ok(ExitCode::SUCCESS)
239211
}

0 commit comments

Comments
 (0)