feat: support style edition differing defaults in config loading
This commit is contained in:
parent
c0c3dc7a25
commit
0c6515cacc
@ -271,11 +271,20 @@ pub(crate) fn version_meets_requirement(&self) -> bool {
|
|||||||
///
|
///
|
||||||
/// Returns a `Config` if the config could be read and parsed from
|
/// Returns a `Config` if the config could be read and parsed from
|
||||||
/// the file, otherwise errors.
|
/// the file, otherwise errors.
|
||||||
pub(super) fn from_toml_path(file_path: &Path) -> Result<Config, Error> {
|
pub(super) fn from_toml_path(
|
||||||
|
file_path: &Path,
|
||||||
|
edition: Option<Edition>,
|
||||||
|
style_edition: Option<StyleEdition>,
|
||||||
|
) -> Result<Config, Error> {
|
||||||
let mut file = File::open(&file_path)?;
|
let mut file = File::open(&file_path)?;
|
||||||
let mut toml = String::new();
|
let mut toml = String::new();
|
||||||
file.read_to_string(&mut toml)?;
|
file.read_to_string(&mut toml)?;
|
||||||
Config::from_toml(&toml, file_path.parent().unwrap())
|
Config::from_toml_for_style_edition(
|
||||||
|
&toml,
|
||||||
|
file_path.parent().unwrap(),
|
||||||
|
edition,
|
||||||
|
style_edition,
|
||||||
|
)
|
||||||
.map_err(|err| Error::new(ErrorKind::InvalidData, err))
|
.map_err(|err| Error::new(ErrorKind::InvalidData, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,7 +297,11 @@ pub(super) fn from_toml_path(file_path: &Path) -> Result<Config, Error> {
|
|||||||
///
|
///
|
||||||
/// Returns the `Config` to use, and the path of the project file if there was
|
/// Returns the `Config` to use, and the path of the project file if there was
|
||||||
/// one.
|
/// one.
|
||||||
pub(super) fn from_resolved_toml_path(dir: &Path) -> Result<(Config, Option<PathBuf>), Error> {
|
pub(super) fn from_resolved_toml_path(
|
||||||
|
dir: &Path,
|
||||||
|
edition: Option<Edition>,
|
||||||
|
style_edition: Option<StyleEdition>,
|
||||||
|
) -> Result<(Config, Option<PathBuf>), Error> {
|
||||||
/// Try to find a project file in the given directory and its parents.
|
/// Try to find a project file in the given directory and its parents.
|
||||||
/// Returns the path of the nearest project file if one exists,
|
/// Returns the path of the nearest project file if one exists,
|
||||||
/// or `None` if no project file was found.
|
/// or `None` if no project file was found.
|
||||||
@ -333,12 +346,26 @@ fn resolve_project_file(dir: &Path) -> Result<Option<PathBuf>, Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match resolve_project_file(dir)? {
|
match resolve_project_file(dir)? {
|
||||||
None => Ok((Config::default(), None)),
|
None => Ok((
|
||||||
Some(path) => Config::from_toml_path(&path).map(|config| (config, Some(path))),
|
Config::default_for_possible_style_edition(style_edition, edition),
|
||||||
|
None,
|
||||||
|
)),
|
||||||
|
Some(path) => Config::from_toml_path(&path, edition, style_edition)
|
||||||
|
.map(|config| (config, Some(path))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_toml(toml: &str, dir: &Path) -> Result<Config, String> {
|
#[allow(dead_code)]
|
||||||
|
pub(super) fn from_toml(toml: &str, dir: &Path) -> Result<Config, String> {
|
||||||
|
Self::from_toml_for_style_edition(toml, dir, None, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn from_toml_for_style_edition(
|
||||||
|
toml: &str,
|
||||||
|
dir: &Path,
|
||||||
|
edition: Option<Edition>,
|
||||||
|
style_edition: Option<StyleEdition>,
|
||||||
|
) -> Result<Config, String> {
|
||||||
let parsed: ::toml::Value = toml
|
let parsed: ::toml::Value = toml
|
||||||
.parse()
|
.parse()
|
||||||
.map_err(|e| format!("Could not parse TOML: {}", e))?;
|
.map_err(|e| format!("Could not parse TOML: {}", e))?;
|
||||||
@ -358,7 +385,7 @@ pub(crate) fn from_toml(toml: &str, dir: &Path) -> Result<Config, String> {
|
|||||||
if !err.is_empty() {
|
if !err.is_empty() {
|
||||||
eprint!("{err}");
|
eprint!("{err}");
|
||||||
}
|
}
|
||||||
Ok(parsed_config.to_parsed_config(None, None, dir))
|
Ok(parsed_config.to_parsed_config(style_edition, edition, dir))
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
err.push_str("Error: Decoding config file failed:\n");
|
err.push_str("Error: Decoding config file failed:\n");
|
||||||
@ -376,21 +403,21 @@ pub fn load_config<O: CliOptions>(
|
|||||||
file_path: Option<&Path>,
|
file_path: Option<&Path>,
|
||||||
options: Option<O>,
|
options: Option<O>,
|
||||||
) -> Result<(Config, Option<PathBuf>), Error> {
|
) -> Result<(Config, Option<PathBuf>), Error> {
|
||||||
let (over_ride, _edition, _style_edition) = match options {
|
let (over_ride, edition, style_edition) = match options {
|
||||||
Some(ref opts) => (
|
Some(ref opts) => (config_path(opts)?, opts.edition(), opts.style_edition()),
|
||||||
config_path(opts)?,
|
|
||||||
opts.edition(),
|
|
||||||
opts.style_edition(),
|
|
||||||
),
|
|
||||||
None => (None, None, None),
|
None => (None, None, None),
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = if let Some(over_ride) = over_ride {
|
let result = if let Some(over_ride) = over_ride {
|
||||||
Config::from_toml_path(over_ride.as_ref()).map(|p| (p, Some(over_ride.to_owned())))
|
Config::from_toml_path(over_ride.as_ref(), edition, style_edition)
|
||||||
|
.map(|p| (p, Some(over_ride.to_owned())))
|
||||||
} else if let Some(file_path) = file_path {
|
} else if let Some(file_path) = file_path {
|
||||||
Config::from_resolved_toml_path(file_path)
|
Config::from_resolved_toml_path(file_path, edition, style_edition)
|
||||||
} else {
|
} else {
|
||||||
Ok((Config::default(), None))
|
Ok((
|
||||||
|
Config::default_for_possible_style_edition(style_edition, edition),
|
||||||
|
None,
|
||||||
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
result.map(|(mut c, p)| {
|
result.map(|(mut c, p)| {
|
||||||
|
@ -6,14 +6,17 @@
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
use std::str::Chars;
|
use std::str::{Chars, FromStr};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
use crate::config::{Color, Config, EmitMode, FileName, NewlineStyle};
|
use crate::config::{Color, Config, EmitMode, FileName, NewlineStyle};
|
||||||
use crate::formatting::{ReportedErrors, SourceFile};
|
use crate::formatting::{ReportedErrors, SourceFile};
|
||||||
use crate::rustfmt_diff::{make_diff, print_diff, DiffLine, Mismatch, ModifiedChunk, OutputWriter};
|
use crate::rustfmt_diff::{make_diff, print_diff, DiffLine, Mismatch, ModifiedChunk, OutputWriter};
|
||||||
use crate::source_file;
|
use crate::source_file;
|
||||||
use crate::{is_nightly_channel, FormatReport, FormatReportFormatterBuilder, Input, Session};
|
use crate::{
|
||||||
|
is_nightly_channel, Edition, FormatReport, FormatReportFormatterBuilder, Input, Session,
|
||||||
|
StyleEdition,
|
||||||
|
};
|
||||||
|
|
||||||
use rustfmt_config_proc_macro::nightly_only_test;
|
use rustfmt_config_proc_macro::nightly_only_test;
|
||||||
|
|
||||||
@ -710,13 +713,22 @@ fn print_mismatches<T: Fn(u32) -> String>(
|
|||||||
|
|
||||||
fn read_config(filename: &Path) -> Config {
|
fn read_config(filename: &Path) -> Config {
|
||||||
let sig_comments = read_significant_comments(filename);
|
let sig_comments = read_significant_comments(filename);
|
||||||
|
let (edition, style_edition) = get_editions_from_comments(&sig_comments);
|
||||||
// Look for a config file. If there is a 'config' property in the significant comments, use
|
// Look for a config file. If there is a 'config' property in the significant comments, use
|
||||||
// that. Otherwise, if there are no significant comments at all, look for a config file with
|
// that. Otherwise, if there are no significant comments at all, look for a config file with
|
||||||
// the same name as the test file.
|
// the same name as the test file.
|
||||||
let mut config = if !sig_comments.is_empty() {
|
let mut config = if !sig_comments.is_empty() {
|
||||||
get_config(sig_comments.get("config").map(Path::new))
|
get_config(
|
||||||
|
sig_comments.get("config").map(Path::new),
|
||||||
|
edition,
|
||||||
|
style_edition,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
get_config(filename.with_extension("toml").file_name().map(Path::new))
|
get_config(
|
||||||
|
filename.with_extension("toml").file_name().map(Path::new),
|
||||||
|
edition,
|
||||||
|
style_edition,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
for (key, val) in &sig_comments {
|
for (key, val) in &sig_comments {
|
||||||
@ -747,13 +759,28 @@ enum IdempotentCheckError {
|
|||||||
Parse,
|
Parse,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_editions_from_comments(
|
||||||
|
comments: &HashMap<String, String>,
|
||||||
|
) -> (Option<Edition>, Option<StyleEdition>) {
|
||||||
|
(
|
||||||
|
comments
|
||||||
|
.get("edition")
|
||||||
|
.map(|e| Edition::from_str(e).expect(&format!("invalid edition value: '{}'", e))),
|
||||||
|
comments.get("style_edition").map(|se| {
|
||||||
|
StyleEdition::from_str(se).expect(&format!("invalid style_edition value: '{}'", se))
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn idempotent_check(
|
fn idempotent_check(
|
||||||
filename: &PathBuf,
|
filename: &PathBuf,
|
||||||
opt_config: &Option<PathBuf>,
|
opt_config: &Option<PathBuf>,
|
||||||
) -> Result<FormatReport, IdempotentCheckError> {
|
) -> Result<FormatReport, IdempotentCheckError> {
|
||||||
let sig_comments = read_significant_comments(filename);
|
let sig_comments = read_significant_comments(filename);
|
||||||
let config = if let Some(ref config_file_path) = opt_config {
|
let config = if let Some(ref config_file_path) = opt_config {
|
||||||
Config::from_toml_path(config_file_path).expect("`rustfmt.toml` not found")
|
let (edition, style_edition) = get_editions_from_comments(&sig_comments);
|
||||||
|
Config::from_toml_path(config_file_path, edition, style_edition)
|
||||||
|
.expect("`rustfmt.toml` not found")
|
||||||
} else {
|
} else {
|
||||||
read_config(filename)
|
read_config(filename)
|
||||||
};
|
};
|
||||||
@ -777,14 +804,18 @@ fn idempotent_check(
|
|||||||
// Reads test config file using the supplied (optional) file name. If there's no file name or the
|
// Reads test config file using the supplied (optional) file name. If there's no file name or the
|
||||||
// file doesn't exist, just return the default config. Otherwise, the file must be read
|
// file doesn't exist, just return the default config. Otherwise, the file must be read
|
||||||
// successfully.
|
// successfully.
|
||||||
fn get_config(config_file: Option<&Path>) -> Config {
|
fn get_config(
|
||||||
|
config_file: Option<&Path>,
|
||||||
|
edition: Option<Edition>,
|
||||||
|
style_edition: Option<StyleEdition>,
|
||||||
|
) -> Config {
|
||||||
let config_file_name = match config_file {
|
let config_file_name = match config_file {
|
||||||
None => return Default::default(),
|
None => return Config::default_for_possible_style_edition(style_edition, edition),
|
||||||
Some(file_name) => {
|
Some(file_name) => {
|
||||||
let mut full_path = PathBuf::from("tests/config/");
|
let mut full_path = PathBuf::from("tests/config/");
|
||||||
full_path.push(file_name);
|
full_path.push(file_name);
|
||||||
if !full_path.exists() {
|
if !full_path.exists() {
|
||||||
return Default::default();
|
return Config::default_for_possible_style_edition(style_edition, edition);
|
||||||
};
|
};
|
||||||
full_path
|
full_path
|
||||||
}
|
}
|
||||||
@ -796,7 +827,13 @@ fn get_config(config_file: Option<&Path>) -> Config {
|
|||||||
.read_to_string(&mut def_config)
|
.read_to_string(&mut def_config)
|
||||||
.expect("Couldn't read config");
|
.expect("Couldn't read config");
|
||||||
|
|
||||||
Config::from_toml(&def_config, Path::new("tests/config/")).expect("invalid TOML")
|
Config::from_toml_for_style_edition(
|
||||||
|
&def_config,
|
||||||
|
Path::new("tests/config/"),
|
||||||
|
edition,
|
||||||
|
style_edition,
|
||||||
|
)
|
||||||
|
.expect("invalid TOML")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads significant comments of the form: `// rustfmt-key: value` into a hash map.
|
// Reads significant comments of the form: `// rustfmt-key: value` into a hash map.
|
||||||
|
Loading…
Reference in New Issue
Block a user