Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(fmt): add support for configuration file #11944

Merged
merged 15 commits into from
Sep 13, 2021
64 changes: 62 additions & 2 deletions cli/config_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ pub struct LintRulesConfig {

#[derive(Clone, Debug, Default, Deserialize)]
#[serde(default, deny_unknown_fields)]
pub struct LintFilesConfig {
pub struct FilesConfig {
pub include: Vec<String>,
pub exclude: Vec<String>,
}
Expand All @@ -286,14 +286,40 @@ pub struct LintFilesConfig {
#[serde(default, deny_unknown_fields)]
pub struct LintConfig {
pub rules: LintRulesConfig,
pub files: LintFilesConfig,
pub files: FilesConfig,
}

#[derive(Clone, Copy, Debug, Deserialize)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub enum TextWrap {
Always,
Never,
Preserve,
}

#[derive(Clone, Debug, Default, Deserialize)]
#[serde(default, deny_unknown_fields, rename_all = "camelCase")]
pub struct FmtOptionsConfig {
pub use_tabs: Option<bool>,
pub line_width: Option<u32>,
pub indent_width: Option<u8>,
pub single_quote: Option<bool>,
pub text_wrap: Option<TextWrap>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason this is called text_wrap in dprint-plugin-markdown is because it controls how the Text node wraps. Since this is a top level config and not markdown specific, I think we should call this prose_wrap to align with prettier.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with changing name, but I'm unsure about that it's not Markdown specific - I haven't found a setting in dprint-plugin-typescript that would be relevant for this setting. Can you elaborate?

}

#[derive(Clone, Debug, Default, Deserialize)]
#[serde(default, deny_unknown_fields)]
pub struct FmtConfig {
pub options: FmtOptionsConfig,
pub files: FilesConfig,
}

#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ConfigFileJson {
pub compiler_options: Option<Value>,
pub lint: Option<Value>,
pub fmt: Option<Value>,
}

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -374,6 +400,16 @@ impl ConfigFile {
Ok(None)
}
}

pub fn to_fmt_config(&self) -> Result<Option<FmtConfig>, AnyError> {
if let Some(config) = self.json.fmt.clone() {
let fmt_config: FmtConfig = serde_json::from_value(config)
.context("Failed to parse \"fmt\" configuration")?;
Ok(Some(fmt_config))
} else {
Ok(None)
}
}
}

#[cfg(test)]
Expand Down Expand Up @@ -441,6 +477,19 @@ mod tests {
"tags": ["recommended"],
"include": ["ban-untagged-todo"]
}
},
"fmt": {
"files": {
"include": ["src/"],
"exclude": ["src/testdata/"]
},
"options": {
"useTabs": true,
"lineWidth": 80,
"indentWidth": 4,
"singleQuote": true,
"textWrap": "preserve"
}
}
}"#;
let config_path = PathBuf::from("/deno/tsconfig.json");
Expand Down Expand Up @@ -474,6 +523,17 @@ mod tests {
Some(vec!["recommended".to_string()])
);
assert!(lint_config.rules.exclude.is_none());

let fmt_config = config_file
.to_fmt_config()
.expect("error parsing fmt object")
.expect("fmt object should be defined");
assert_eq!(fmt_config.files.include, vec!["src/"]);
assert_eq!(fmt_config.files.exclude, vec!["src/testdata/"]);
assert_eq!(fmt_config.options.use_tabs, Some(true));
assert_eq!(fmt_config.options.line_width, Some(80));
assert_eq!(fmt_config.options.indent_width, Some(4));
assert_eq!(fmt_config.options.single_quote, Some(true));
}

#[test]
Expand Down
40 changes: 40 additions & 0 deletions cli/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,7 @@ Ignore formatting a file by adding an ignore comment at the top of the file:

// deno-fmt-ignore-file",
)
.arg(config_arg())
.arg(
Arg::with_name("check")
.long("check")
Expand Down Expand Up @@ -1733,6 +1734,7 @@ fn eval_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
}

fn fmt_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
config_arg_parse(flags, matches);
flags.watch = matches.is_present("watch");
let files = match matches.values_of("files") {
Some(f) => f.map(PathBuf::from).collect(),
Expand Down Expand Up @@ -2535,6 +2537,44 @@ mod tests {
..Flags::default()
}
);

let r = flags_from_vec(svec!["deno", "fmt", "--config", "deno.jsonc"]);
assert_eq!(
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Fmt(FmtFlags {
ignore: vec![],
check: false,
files: vec![],
ext: "ts".to_string()
}),
config_path: Some("deno.jsonc".to_string()),
..Flags::default()
}
);

let r = flags_from_vec(svec![
"deno",
"fmt",
"--config",
"deno.jsonc",
"--watch",
"foo.ts"
]);
assert_eq!(
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Fmt(FmtFlags {
ignore: vec![],
check: false,
files: vec![PathBuf::from("foo.ts")],
ext: "ts".to_string()
}),
config_path: Some("deno.jsonc".to_string()),
watch: true,
..Flags::default()
}
);
}

#[test]
Expand Down
8 changes: 7 additions & 1 deletion cli/lsp/language_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1009,11 +1009,17 @@ impl Inner {
let source = document_data.source().clone();
let text_edits = tokio::task::spawn_blocking(move || {
let format_result = match source.module() {
// TODO(bartlomieju): add support for `fmt_config` from config file
Some(Ok(parsed_module)) => Ok(format_parsed_module(parsed_module)),
Some(Err(err)) => Err(err.to_string()),
None => {
// it's not a js/ts file, so attempt to format its contents
format_file(&file_path, source.text_info().text_str())
// TODO(bartlomieju): add support for `fmt_config` from config file
format_file(
&file_path,
source.text_info().text_str(),
Default::default(),
)
}
};

Expand Down
15 changes: 14 additions & 1 deletion cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -806,15 +806,28 @@ async fn format_command(
flags: Flags,
fmt_flags: FmtFlags,
) -> Result<(), AnyError> {
let program_state = ProgramState::build(flags.clone()).await?;
let maybe_fmt_config =
if let Some(config_file) = &program_state.maybe_config_file {
config_file.to_fmt_config()?
} else {
None
};

if fmt_flags.files.len() == 1 && fmt_flags.files[0].to_string_lossy() == "-" {
return tools::fmt::format_stdin(fmt_flags.check, fmt_flags.ext);
return tools::fmt::format_stdin(
fmt_flags.check,
fmt_flags.ext,
maybe_fmt_config.map(|c| c.options).unwrap_or_default(),
);
}

tools::fmt::format(
fmt_flags.files,
fmt_flags.ignore,
fmt_flags.check,
flags.watch,
maybe_fmt_config,
)
.await?;
Ok(())
Expand Down
Loading