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 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
|
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 on the top file.
|
||||||
to `run` in `main()`. Eventually you should be able to set the mode from the
|
|
||||||
command line or from a config file or something.
|
|
||||||
|
|
||||||
|
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
|
## Use cases
|
||||||
|
|
||||||
|
@ -9,23 +9,47 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![cfg(not(test))]
|
#![cfg(not(test))]
|
||||||
|
#![feature(result_expect)]
|
||||||
|
|
||||||
extern crate rustfmt;
|
extern crate rustfmt;
|
||||||
|
|
||||||
use rustfmt::{WriteMode, run};
|
use rustfmt::{WriteMode, run};
|
||||||
|
use rustfmt::config::Config;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Vec<_> = std::env::args().collect();
|
|
||||||
let mut def_config_file = File::open("default.toml").unwrap_or_else(|e| {
|
let mut def_config_file = File::open("default.toml").unwrap_or_else(|e| {
|
||||||
panic!("Unable to open configuration file [default.toml] {}",e)
|
panic!("Unable to open configuration file [default.toml] {}",e)
|
||||||
});
|
});
|
||||||
let mut def_config = String::new();
|
let mut def_config = String::new();
|
||||||
def_config_file.read_to_string(&mut def_config).unwrap();
|
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);
|
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 {
|
match mode {
|
||||||
WriteMode::Overwrite => {
|
WriteMode::Replace => {
|
||||||
// Do a little dance to make writing safer - write to a temp file
|
// 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
|
// rename the original to a .bk, then rename the temp file to the
|
||||||
// original.
|
// original.
|
||||||
let tmp_name = filename.to_owned() + ".tmp";
|
let tmp_name = filename.to_owned() + ".tmp";
|
||||||
let bk_name = filename.to_owned() + ".bk";
|
let bk_name = filename.to_owned() + ".bk";
|
||||||
{
|
{
|
||||||
// Write text to temp file
|
// Write text to temp file
|
||||||
let tmp_file = try!(File::create(&tmp_name));
|
let tmp_file = try!(File::create(&tmp_name));
|
||||||
try!(write_system_newlines(tmp_file, text, config));
|
try!(write_system_newlines(tmp_file, text, config));
|
||||||
}
|
}
|
||||||
|
|
||||||
try!(fs::rename(filename, bk_name));
|
try!(fs::rename(filename, bk_name));
|
||||||
try!(fs::rename(tmp_name, filename));
|
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()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
25
src/lib.rs
25
src/lib.rs
@ -42,6 +42,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::mem::swap;
|
use std::mem::swap;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use issues::{BadIssueSeeker, Issue};
|
use issues::{BadIssueSeeker, Issue};
|
||||||
use filemap::FileMap;
|
use filemap::FileMap;
|
||||||
@ -71,8 +72,11 @@
|
|||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum WriteMode {
|
pub enum WriteMode {
|
||||||
|
// Backups the original file and overwrites the orignal.
|
||||||
|
Replace,
|
||||||
|
// Overwrites original file without backup.
|
||||||
Overwrite,
|
Overwrite,
|
||||||
// str is the extension of the new file
|
// str is the extension of the new file.
|
||||||
NewFile(&'static str),
|
NewFile(&'static str),
|
||||||
// Write the output to stdout.
|
// Write the output to stdout.
|
||||||
Display,
|
Display,
|
||||||
@ -80,6 +84,19 @@ pub enum WriteMode {
|
|||||||
Return(&'static Fn(HashMap<String, String>)),
|
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)]
|
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||||
pub enum NewlineStyle {
|
pub enum NewlineStyle {
|
||||||
Windows, // \r\n
|
Windows, // \r\n
|
||||||
@ -343,9 +360,7 @@ fn build_controller(&mut self, _: &Session) -> driver::CompileController<'a> {
|
|||||||
// to the compiler.
|
// to the compiler.
|
||||||
// write_mode determines what happens to the result of running rustfmt, see
|
// write_mode determines what happens to the result of running rustfmt, see
|
||||||
// WriteMode.
|
// WriteMode.
|
||||||
// default_config is a string of toml data to be used to configure rustfmt.
|
pub fn run(args: Vec<String>, write_mode: WriteMode, config: Box<Config>) {
|
||||||
pub fn run(args: Vec<String>, write_mode: WriteMode, default_config: &str) {
|
let mut call_ctxt = RustFmtCalls { write_mode: write_mode, config: Some(config) };
|
||||||
let config = Some(Box::new(config::Config::from_toml(default_config)));
|
|
||||||
let mut call_ctxt = RustFmtCalls { write_mode: write_mode, config: config };
|
|
||||||
rustc_driver::run_compiler(&args, &mut call_ctxt);
|
rustc_driver::run_compiler(&args, &mut call_ctxt);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
use std::io::{self, Read, BufRead, BufReader};
|
use std::io::{self, Read, BufRead, BufReader};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use rustfmt::*;
|
use rustfmt::*;
|
||||||
|
use rustfmt::config::Config;
|
||||||
|
|
||||||
fn get_path_string(dir_entry: io::Result<fs::DirEntry>) -> String {
|
fn get_path_string(dir_entry: io::Result<fs::DirEntry>) -> String {
|
||||||
let path = dir_entry.ok().expect("Couldn't get DirEntry.").path();
|
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
|
// panic to return a result in case of failure. This has the advantage of smoothing the road to
|
||||||
// multithreaded rustfmt
|
// multithreaded rustfmt
|
||||||
thread::catch_panic(move || {
|
thread::catch_panic(move || {
|
||||||
run(args, WriteMode::Return(HANDLE_RESULT), &config);
|
run(args, WriteMode::Return(HANDLE_RESULT), config);
|
||||||
}).map_err(|any|
|
}).map_err(|any|
|
||||||
*any.downcast().ok().expect("Downcast failed.")
|
*any.downcast().ok().expect("Downcast failed.")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads test config file from comments and loads it
|
// 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")
|
let config_file_name = read_significant_comment(file_name, "config")
|
||||||
.map(|file_name| {
|
.map(|file_name| {
|
||||||
let mut full_path = "tests/config/".to_owned();
|
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();
|
let mut def_config = String::new();
|
||||||
def_config_file.read_to_string(&mut def_config).ok().expect("Couldn't read config.");
|
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> {
|
fn read_significant_comment(file_name: &str, option: &str) -> Option<String> {
|
||||||
|
Loading…
Reference in New Issue
Block a user