Add an option to forgo backups
This commit is contained in:
parent
229415bca2
commit
10a80bb8be
14
README.md
14
README.md
@ -13,12 +13,18 @@ the rustfmt command. You can look at this repo for an example default.toml file.
|
||||
|
||||
`cargo test` to run all tests.
|
||||
|
||||
`cargo run filename` to run on a file, if the file includes out of line modules,
|
||||
`cargo run -- filename` to run on a file, if the file includes out of line modules,
|
||||
then we reformat those too. So to run on a whole module or crate, you just need
|
||||
to run on the top file. You'll probably want to set the `WriteMode` in the call
|
||||
to `run` in `main()`. Eventually you should be able to set the mode from the
|
||||
command line or from a config file or something.
|
||||
to run on the top file.
|
||||
|
||||
You'll probably want to specify the write mode. Currently, there are the replace,
|
||||
overwrite and display mode. The replace mode is the default and overwrites the
|
||||
original files after renaming them. In overwrite mode, rustfmt does not backup
|
||||
the source files. To print the output to stdout, use the display mode. The write
|
||||
mode can be set by passing the `--write-mode` flag on the command line.
|
||||
|
||||
`cargo run -- filename --write-mode=display` prints the output of rustfmt to the
|
||||
screen, for example.
|
||||
|
||||
## Use cases
|
||||
|
||||
|
@ -9,23 +9,47 @@
|
||||
// except according to those terms.
|
||||
|
||||
#![cfg(not(test))]
|
||||
#![feature(result_expect)]
|
||||
|
||||
extern crate rustfmt;
|
||||
|
||||
use rustfmt::{WriteMode, run};
|
||||
use rustfmt::config::Config;
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::str::FromStr;
|
||||
|
||||
fn main() {
|
||||
let args: Vec<_> = std::env::args().collect();
|
||||
let mut def_config_file = File::open("default.toml").unwrap_or_else(|e| {
|
||||
panic!("Unable to open configuration file [default.toml] {}",e)
|
||||
});
|
||||
let mut def_config = String::new();
|
||||
def_config_file.read_to_string(&mut def_config).unwrap();
|
||||
let config = Box::new(Config::from_toml(&def_config));
|
||||
let (args, write_mode) = determine_params(std::env::args());
|
||||
|
||||
run(args, WriteMode::Overwrite, &def_config);
|
||||
run(args, write_mode, config);
|
||||
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
fn determine_params<I>(args: I) -> (Vec<String>, WriteMode)
|
||||
where I: Iterator<Item = String>
|
||||
{
|
||||
let prefix = "--write-mode=";
|
||||
let mut write_mode = WriteMode::Replace;
|
||||
|
||||
// The NewFile option currently isn't supported because it requires another
|
||||
// parameter, but it can be added later.
|
||||
let args = args.filter(|arg| {
|
||||
if arg.starts_with(prefix) {
|
||||
write_mode = FromStr::from_str(&arg[prefix.len()..]).expect("Unrecognized write mode");
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}).collect();
|
||||
|
||||
(args, write_mode)
|
||||
}
|
||||
|
@ -73,40 +73,46 @@ fn write_system_newlines<T>(mut writer: T,
|
||||
}
|
||||
|
||||
match mode {
|
||||
WriteMode::Overwrite => {
|
||||
// Do a little dance to make writing safer - write to a temp file
|
||||
// rename the original to a .bk, then rename the temp file to the
|
||||
// original.
|
||||
let tmp_name = filename.to_owned() + ".tmp";
|
||||
let bk_name = filename.to_owned() + ".bk";
|
||||
{
|
||||
// Write text to temp file
|
||||
let tmp_file = try!(File::create(&tmp_name));
|
||||
try!(write_system_newlines(tmp_file, text, config));
|
||||
}
|
||||
WriteMode::Replace => {
|
||||
// Do a little dance to make writing safer - write to a temp file
|
||||
// rename the original to a .bk, then rename the temp file to the
|
||||
// original.
|
||||
let tmp_name = filename.to_owned() + ".tmp";
|
||||
let bk_name = filename.to_owned() + ".bk";
|
||||
{
|
||||
// Write text to temp file
|
||||
let tmp_file = try!(File::create(&tmp_name));
|
||||
try!(write_system_newlines(tmp_file, text, config));
|
||||
}
|
||||
|
||||
try!(fs::rename(filename, bk_name));
|
||||
try!(fs::rename(tmp_name, filename));
|
||||
}
|
||||
WriteMode::NewFile(extn) => {
|
||||
let filename = filename.to_owned() + "." + extn;
|
||||
let file = try!(File::create(&filename));
|
||||
try!(write_system_newlines(file, text, config));
|
||||
}
|
||||
WriteMode::Display => {
|
||||
println!("{}:\n", filename);
|
||||
let stdout = stdout();
|
||||
let stdout_lock = stdout.lock();
|
||||
try!(write_system_newlines(stdout_lock, text, config));
|
||||
}
|
||||
WriteMode::Return(_) => {
|
||||
// io::Write is not implemented for String, working around with Vec<u8>
|
||||
let mut v = Vec::new();
|
||||
try!(write_system_newlines(&mut v, text, config));
|
||||
// won't panic, we are writing correct utf8
|
||||
return Ok(Some(String::from_utf8(v).unwrap()));
|
||||
}
|
||||
try!(fs::rename(filename, bk_name));
|
||||
try!(fs::rename(tmp_name, filename));
|
||||
}
|
||||
WriteMode::Overwrite => {
|
||||
// Write text directly over original file.
|
||||
let file = try!(File::create(filename));
|
||||
try!(write_system_newlines(file, text, config));
|
||||
}
|
||||
WriteMode::NewFile(extn) => {
|
||||
let filename = filename.to_owned() + "." + extn;
|
||||
let file = try!(File::create(&filename));
|
||||
try!(write_system_newlines(file, text, config));
|
||||
}
|
||||
WriteMode::Display => {
|
||||
println!("{}:\n", filename);
|
||||
let stdout = stdout();
|
||||
let stdout_lock = stdout.lock();
|
||||
try!(write_system_newlines(stdout_lock, text, config));
|
||||
}
|
||||
WriteMode::Return(_) => {
|
||||
// io::Write is not implemented for String, working around with
|
||||
// Vec<u8>
|
||||
let mut v = Vec::new();
|
||||
try!(write_system_newlines(&mut v, text, config));
|
||||
// won't panic, we are writing correct utf8
|
||||
return Ok(Some(String::from_utf8(v).unwrap()));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
25
src/lib.rs
25
src/lib.rs
@ -42,6 +42,7 @@
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::mem::swap;
|
||||
use std::str::FromStr;
|
||||
|
||||
use issues::{BadIssueSeeker, Issue};
|
||||
use filemap::FileMap;
|
||||
@ -71,8 +72,11 @@
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum WriteMode {
|
||||
// Backups the original file and overwrites the orignal.
|
||||
Replace,
|
||||
// Overwrites original file without backup.
|
||||
Overwrite,
|
||||
// str is the extension of the new file
|
||||
// str is the extension of the new file.
|
||||
NewFile(&'static str),
|
||||
// Write the output to stdout.
|
||||
Display,
|
||||
@ -80,6 +84,19 @@ pub enum WriteMode {
|
||||
Return(&'static Fn(HashMap<String, String>)),
|
||||
}
|
||||
|
||||
impl FromStr for WriteMode {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"replace" => Ok(WriteMode::Replace),
|
||||
"display" => Ok(WriteMode::Display),
|
||||
"overwrite" => Ok(WriteMode::Overwrite),
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||
pub enum NewlineStyle {
|
||||
Windows, // \r\n
|
||||
@ -343,9 +360,7 @@ fn build_controller(&mut self, _: &Session) -> driver::CompileController<'a> {
|
||||
// to the compiler.
|
||||
// write_mode determines what happens to the result of running rustfmt, see
|
||||
// WriteMode.
|
||||
// default_config is a string of toml data to be used to configure rustfmt.
|
||||
pub fn run(args: Vec<String>, write_mode: WriteMode, default_config: &str) {
|
||||
let config = Some(Box::new(config::Config::from_toml(default_config)));
|
||||
let mut call_ctxt = RustFmtCalls { write_mode: write_mode, config: config };
|
||||
pub fn run(args: Vec<String>, write_mode: WriteMode, config: Box<Config>) {
|
||||
let mut call_ctxt = RustFmtCalls { write_mode: write_mode, config: Some(config) };
|
||||
rustc_driver::run_compiler(&args, &mut call_ctxt);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
use std::io::{self, Read, BufRead, BufReader};
|
||||
use std::thread;
|
||||
use rustfmt::*;
|
||||
use rustfmt::config::Config;
|
||||
|
||||
fn get_path_string(dir_entry: io::Result<fs::DirEntry>) -> String {
|
||||
let path = dir_entry.ok().expect("Couldn't get DirEntry.").path();
|
||||
@ -103,14 +104,14 @@ pub fn idempotent_check(filename: String) -> Result<(), HashMap<String, String>>
|
||||
// panic to return a result in case of failure. This has the advantage of smoothing the road to
|
||||
// multithreaded rustfmt
|
||||
thread::catch_panic(move || {
|
||||
run(args, WriteMode::Return(HANDLE_RESULT), &config);
|
||||
run(args, WriteMode::Return(HANDLE_RESULT), config);
|
||||
}).map_err(|any|
|
||||
*any.downcast().ok().expect("Downcast failed.")
|
||||
)
|
||||
}
|
||||
|
||||
// Reads test config file from comments and loads it
|
||||
fn get_config(file_name: &str) -> String {
|
||||
fn get_config(file_name: &str) -> Box<Config> {
|
||||
let config_file_name = read_significant_comment(file_name, "config")
|
||||
.map(|file_name| {
|
||||
let mut full_path = "tests/config/".to_owned();
|
||||
@ -123,7 +124,7 @@ fn get_config(file_name: &str) -> String {
|
||||
let mut def_config = String::new();
|
||||
def_config_file.read_to_string(&mut def_config).ok().expect("Couldn't read config.");
|
||||
|
||||
def_config
|
||||
Box::new(Config::from_toml(&def_config))
|
||||
}
|
||||
|
||||
fn read_significant_comment(file_name: &str, option: &str) -> Option<String> {
|
||||
|
Loading…
Reference in New Issue
Block a user