Add --check flag for format command

Closes #2495
This commit is contained in:
Ryan Olson 2022-02-16 10:55:02 -07:00
parent c15c8d57a2
commit 60b5465de2
3 changed files with 44 additions and 7 deletions

View file

@ -1,5 +1,6 @@
use std::path::PathBuf; use std::path::PathBuf;
use crate::FormatMode;
use bumpalo::collections::Vec; use bumpalo::collections::Vec;
use bumpalo::Bump; use bumpalo::Bump;
use roc_error_macros::{internal_error, user_error}; use roc_error_macros::{internal_error, user_error};
@ -24,7 +25,7 @@ use roc_parse::{
}; };
use roc_region::all::{Loc, Region}; use roc_region::all::{Loc, Region};
pub fn format(files: std::vec::Vec<PathBuf>) { pub fn format(files: std::vec::Vec<PathBuf>, mode: FormatMode) -> Result<(), String> {
for file in files { for file in files {
let arena = Bump::new(); let arena = Bump::new();
@ -99,9 +100,22 @@ pub fn format(files: std::vec::Vec<PathBuf>) {
unstable_2_file.display()); unstable_2_file.display());
} }
// If all the checks above passed, actually write out the new file. match mode {
std::fs::write(&file, buf.as_str()).unwrap(); FormatMode::CheckOnly => {
// If we notice that this file needs to be formatted, return early
if buf.as_str() != src {
return Err("One or more files need to be reformatted.".to_string());
}
}
FormatMode::Format => {
// If all the checks above passed, actually write out the new file.
std::fs::write(&file, buf.as_str()).unwrap();
}
}
} }
Ok(())
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]

View file

@ -37,6 +37,7 @@ pub const FLAG_TIME: &str = "time";
pub const FLAG_LINK: &str = "roc-linker"; pub const FLAG_LINK: &str = "roc-linker";
pub const FLAG_PRECOMPILED: &str = "precompiled-host"; pub const FLAG_PRECOMPILED: &str = "precompiled-host";
pub const FLAG_VALGRIND: &str = "valgrind"; pub const FLAG_VALGRIND: &str = "valgrind";
pub const FLAG_CHECK: &str = "check";
pub const ROC_FILE: &str = "ROC_FILE"; pub const ROC_FILE: &str = "ROC_FILE";
pub const ROC_DIR: &str = "ROC_DIR"; pub const ROC_DIR: &str = "ROC_DIR";
pub const BACKEND: &str = "BACKEND"; pub const BACKEND: &str = "BACKEND";
@ -122,6 +123,12 @@ pub fn build_app<'a>() -> App<'a> {
.index(1) .index(1)
.multiple_values(true) .multiple_values(true)
.required(false)) .required(false))
.arg(
Arg::new(FLAG_CHECK)
.long(FLAG_CHECK)
.about("Checks that specified files are formatted. If formatting is needed, it will return a non-zero exit code.")
.required(false),
)
) )
.subcommand(App::new(CMD_VERSION) .subcommand(App::new(CMD_VERSION)
.about("Print version information") .about("Print version information")
@ -242,6 +249,11 @@ pub enum BuildConfig {
BuildAndRun { roc_file_arg_index: usize }, BuildAndRun { roc_file_arg_index: usize },
} }
pub enum FormatMode {
Format,
CheckOnly,
}
pub fn build(matches: &ArgMatches, config: BuildConfig) -> io::Result<i32> { pub fn build(matches: &ArgMatches, config: BuildConfig) -> io::Result<i32> {
use build::build_file; use build::build_file;
use std::str::FromStr; use std::str::FromStr;

View file

@ -1,7 +1,7 @@
use roc_cli::build::check_file; use roc_cli::build::check_file;
use roc_cli::{ use roc_cli::{
build_app, docs, format, BuildConfig, CMD_BUILD, CMD_CHECK, CMD_DOCS, CMD_EDIT, CMD_FORMAT, build_app, docs, format, BuildConfig, FormatMode, CMD_BUILD, CMD_CHECK, CMD_DOCS, CMD_EDIT,
CMD_REPL, CMD_VERSION, DIRECTORY_OR_FILES, FLAG_TIME, ROC_FILE, CMD_FORMAT, CMD_REPL, CMD_VERSION, DIRECTORY_OR_FILES, FLAG_CHECK, FLAG_TIME, ROC_FILE,
}; };
use roc_load::file::LoadingProblem; use roc_load::file::LoadingProblem;
use std::fs::{self, FileType}; use std::fs::{self, FileType};
@ -150,9 +150,20 @@ fn main() -> io::Result<()> {
roc_files_recursive(os_str.as_os_str(), metadata.file_type(), &mut roc_files)?; roc_files_recursive(os_str.as_os_str(), metadata.file_type(), &mut roc_files)?;
} }
format(roc_files); let format_mode = match matches.is_present(FLAG_CHECK) {
true => FormatMode::CheckOnly,
false => FormatMode::Format,
};
Ok(0) let format_exit_code = match format(roc_files, format_mode) {
Ok(_) => 0,
Err(message) => {
eprintln!("{}", message);
1
}
};
Ok(format_exit_code)
} }
Some((CMD_VERSION, _)) => { Some((CMD_VERSION, _)) => {
println!("roc {}", concatcp!(include_str!("../../version.txt"), "\n")); println!("roc {}", concatcp!(include_str!("../../version.txt"), "\n"));