mirror of
https://github.com/denoland/deno.git
synced 2025-01-11 16:42:21 -05:00
feat: auto-discover config file (#13313)
This commit is contained in:
parent
b10563cb20
commit
39ea4abff4
15 changed files with 319 additions and 131 deletions
11
.dprint.json
11
.dprint.json
|
@ -21,19 +21,20 @@
|
|||
"cli/dts/lib.scripthost.d.ts",
|
||||
"cli/dts/lib.webworker*.d.ts",
|
||||
"cli/dts/typescript.d.ts",
|
||||
"cli/tests/testdata/encoding",
|
||||
"cli/tests/testdata/inline_js_source_map*",
|
||||
"cli/tests/testdata/badly_formatted.md",
|
||||
"cli/tests/testdata/badly_formatted.json",
|
||||
"cli/tests/testdata/badly_formatted.md",
|
||||
"cli/tests/testdata/byte_order_mark.ts",
|
||||
"cli/tests/testdata/encoding",
|
||||
"cli/tests/testdata/fmt/*",
|
||||
"cli/tests/testdata/import_assertions/json_with_shebang.json",
|
||||
"cli/tests/testdata/inline_js_source_map*",
|
||||
"cli/tests/testdata/malformed_config/*",
|
||||
"cli/tests/testdata/test/markdown_windows.md",
|
||||
"cli/tsc/*typescript.js",
|
||||
"test_util/std",
|
||||
"test_util/wpt",
|
||||
"gh-pages",
|
||||
"target",
|
||||
"test_util/std",
|
||||
"test_util/wpt",
|
||||
"third_party",
|
||||
"tools/wpt/expectation.json",
|
||||
"tools/wpt/manifest.json"
|
||||
|
|
|
@ -18,8 +18,10 @@ use deno_core::serde_json::Value;
|
|||
use deno_core::ModuleSpecifier;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub(crate) type MaybeImportsResult =
|
||||
Result<Option<Vec<(ModuleSpecifier, Vec<String>)>>, AnyError>;
|
||||
|
@ -156,6 +158,61 @@ pub const IGNORED_RUNTIME_COMPILER_OPTIONS: &[&str] = &[
|
|||
"watch",
|
||||
];
|
||||
|
||||
/// Filenames that Deno will recognize when discovering config.
|
||||
const CONFIG_FILE_NAMES: [&str; 2] = ["deno.json", "deno.jsonc"];
|
||||
|
||||
pub fn discover(flags: &crate::Flags) -> Result<Option<ConfigFile>, AnyError> {
|
||||
if let Some(config_path) = flags.config_path.as_ref() {
|
||||
Ok(Some(ConfigFile::read(config_path)?))
|
||||
} else {
|
||||
let mut checked = HashSet::new();
|
||||
for f in flags.config_path_args() {
|
||||
if let Some(cf) = discover_from(&f, &mut checked)? {
|
||||
return Ok(Some(cf));
|
||||
}
|
||||
}
|
||||
|
||||
// From CWD walk up to root looking for deno.json or deno.jsonc
|
||||
let cwd = std::env::current_dir()?;
|
||||
discover_from(&cwd, &mut checked)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn discover_from(
|
||||
start: &Path,
|
||||
checked: &mut HashSet<PathBuf>,
|
||||
) -> Result<Option<ConfigFile>, AnyError> {
|
||||
for ancestor in start.ancestors() {
|
||||
if checked.insert(ancestor.to_path_buf()) {
|
||||
for config_filename in CONFIG_FILE_NAMES {
|
||||
let f = ancestor.join(config_filename);
|
||||
match ConfigFile::read(f) {
|
||||
Ok(cf) => {
|
||||
return Ok(Some(cf));
|
||||
}
|
||||
Err(e) => {
|
||||
if let Some(ioerr) = e.downcast_ref::<std::io::Error>() {
|
||||
use std::io::ErrorKind::*;
|
||||
match ioerr.kind() {
|
||||
InvalidInput | PermissionDenied | NotFound => {
|
||||
// ok keep going
|
||||
}
|
||||
_ => {
|
||||
return Err(e); // Unknown error. Stop.
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(e); // Parse error or something else. Stop.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// No config file found.
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// A function that works like JavaScript's `Object.assign()`.
|
||||
pub fn json_merge(a: &mut Value, b: &Value) {
|
||||
match (a, b) {
|
||||
|
@ -823,4 +880,38 @@ mod tests {
|
|||
}));
|
||||
assert_eq!(tsconfig1.as_bytes(), tsconfig2.as_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn discover_from_success() {
|
||||
// testdata/fmt/deno.jsonc exists
|
||||
let testdata = test_util::testdata_path();
|
||||
let c_md = testdata.join("fmt/with_config/subdir/c.md");
|
||||
let mut checked = HashSet::new();
|
||||
let config_file = discover_from(&c_md, &mut checked).unwrap().unwrap();
|
||||
assert!(checked.contains(c_md.parent().unwrap()));
|
||||
assert!(!checked.contains(&testdata));
|
||||
let fmt_config = config_file.to_fmt_config().unwrap().unwrap();
|
||||
let expected_exclude = ModuleSpecifier::from_file_path(
|
||||
testdata.join("fmt/with_config/subdir/b.ts"),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(fmt_config.files.exclude, vec![expected_exclude]);
|
||||
|
||||
// Now add all ancestors of testdata to checked.
|
||||
for a in testdata.ancestors() {
|
||||
checked.insert(a.to_path_buf());
|
||||
}
|
||||
|
||||
// If we call discover_from again starting at testdata, we ought to get None.
|
||||
assert!(discover_from(&testdata, &mut checked).unwrap().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn discover_from_malformed() {
|
||||
let testdata = test_util::testdata_path();
|
||||
let d = testdata.join("malformed_config/");
|
||||
let mut checked = HashSet::new();
|
||||
let err = discover_from(&d, &mut checked).unwrap_err();
|
||||
assert!(err.to_string().contains("Unable to parse config file"));
|
||||
}
|
||||
}
|
||||
|
|
48
cli/flags.rs
48
cli/flags.rs
|
@ -361,6 +361,28 @@ impl Flags {
|
|||
|
||||
args
|
||||
}
|
||||
|
||||
/// Extract path arguments for config search paths.
|
||||
pub fn config_path_args(&self) -> Vec<PathBuf> {
|
||||
use DenoSubcommand::*;
|
||||
if let Fmt(FmtFlags { files, .. }) = &self.subcommand {
|
||||
files.clone()
|
||||
} else if let Lint(LintFlags { files, .. }) = &self.subcommand {
|
||||
files.clone()
|
||||
} else if let Run(RunFlags { script }) = &self.subcommand {
|
||||
if let Ok(module_specifier) = deno_core::resolve_url_or_path(script) {
|
||||
if let Ok(p) = module_specifier.to_file_path() {
|
||||
vec![p]
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Flags> for PermissionsOptions {
|
||||
|
@ -4628,4 +4650,30 @@ mod tests {
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_config_path_args() {
|
||||
let flags = flags_from_vec(svec!["deno", "run", "foo.js"]).unwrap();
|
||||
assert_eq!(
|
||||
flags.config_path_args(),
|
||||
vec![std::env::current_dir().unwrap().join("foo.js")]
|
||||
);
|
||||
|
||||
let flags =
|
||||
flags_from_vec(svec!["deno", "lint", "dir/a.js", "dir/b.js"]).unwrap();
|
||||
assert_eq!(
|
||||
flags.config_path_args(),
|
||||
vec![PathBuf::from("dir/a.js"), PathBuf::from("dir/b.js")]
|
||||
);
|
||||
|
||||
let flags = flags_from_vec(svec!["deno", "lint"]).unwrap();
|
||||
assert!(flags.config_path_args().is_empty());
|
||||
|
||||
let flags =
|
||||
flags_from_vec(svec!["deno", "fmt", "dir/a.js", "dir/b.js"]).unwrap();
|
||||
assert_eq!(
|
||||
flags.config_path_args(),
|
||||
vec![PathBuf::from("dir/a.js"), PathBuf::from("dir/b.js")]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,34 +139,6 @@ pub fn is_supported_ext(path: &Path) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// This function is similar to is_supported_ext but adds additional extensions
|
||||
/// supported by `deno fmt`.
|
||||
pub fn is_supported_ext_fmt(path: &Path) -> bool {
|
||||
if let Some(ext) = get_extension(path) {
|
||||
matches!(
|
||||
ext.as_str(),
|
||||
"ts"
|
||||
| "tsx"
|
||||
| "js"
|
||||
| "jsx"
|
||||
| "mjs"
|
||||
| "mts"
|
||||
| "cjs"
|
||||
| "cts"
|
||||
| "json"
|
||||
| "jsonc"
|
||||
| "md"
|
||||
| "mkd"
|
||||
| "mkdn"
|
||||
| "mdwn"
|
||||
| "mdown"
|
||||
| "markdown"
|
||||
)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if the path has a basename and extension Deno supports for tests.
|
||||
pub fn is_supported_test_path(path: &Path) -> bool {
|
||||
if let Some(name) = path.file_stem() {
|
||||
|
@ -458,46 +430,11 @@ mod tests {
|
|||
assert!(!is_supported_ext(Path::new("foo.mjsx")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_supported_ext_fmt() {
|
||||
assert!(!is_supported_ext_fmt(Path::new("tests/subdir/redirects")));
|
||||
assert!(is_supported_ext_fmt(Path::new("README.md")));
|
||||
assert!(is_supported_ext_fmt(Path::new("readme.MD")));
|
||||
assert!(is_supported_ext_fmt(Path::new("readme.mkd")));
|
||||
assert!(is_supported_ext_fmt(Path::new("readme.mkdn")));
|
||||
assert!(is_supported_ext_fmt(Path::new("readme.mdwn")));
|
||||
assert!(is_supported_ext_fmt(Path::new("readme.mdown")));
|
||||
assert!(is_supported_ext_fmt(Path::new("readme.markdown")));
|
||||
assert!(is_supported_ext_fmt(Path::new("lib/typescript.d.ts")));
|
||||
assert!(is_supported_ext_fmt(Path::new("testdata/001_hello.js")));
|
||||
assert!(is_supported_ext_fmt(Path::new("testdata/002_hello.ts")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.jsx")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.tsx")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.TS")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.TSX")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.JS")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.JSX")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.mjs")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.mts")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.cjs")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.cts")));
|
||||
assert!(!is_supported_ext_fmt(Path::new("foo.mjsx")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.jsonc")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.JSONC")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.json")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.JsON")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_supported_test_ext() {
|
||||
assert!(!is_supported_test_ext(Path::new("tests/subdir/redirects")));
|
||||
assert!(is_supported_test_ext(Path::new("README.md")));
|
||||
assert!(is_supported_test_ext(Path::new("readme.MD")));
|
||||
assert!(is_supported_ext_fmt(Path::new("readme.mkd")));
|
||||
assert!(is_supported_ext_fmt(Path::new("readme.mkdn")));
|
||||
assert!(is_supported_ext_fmt(Path::new("readme.mdwn")));
|
||||
assert!(is_supported_ext_fmt(Path::new("readme.mdown")));
|
||||
assert!(is_supported_ext_fmt(Path::new("readme.markdown")));
|
||||
assert!(is_supported_test_ext(Path::new("lib/typescript.d.ts")));
|
||||
assert!(is_supported_test_ext(Path::new("testdata/001_hello.js")));
|
||||
assert!(is_supported_test_ext(Path::new("testdata/002_hello.ts")));
|
||||
|
|
|
@ -320,7 +320,23 @@ impl Inner {
|
|||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
// Auto-discover config
|
||||
|
||||
// It is possible that root_uri is not set, for example when having a single
|
||||
// file open and not a workspace. In those situations we can't
|
||||
// automatically discover the configuration
|
||||
if let Some(root_uri) = maybe_root_uri {
|
||||
let root_path = root_uri.to_file_path().unwrap();
|
||||
let mut checked = std::collections::HashSet::new();
|
||||
let maybe_config =
|
||||
crate::config_file::discover_from(&root_path, &mut checked)?;
|
||||
Ok(maybe_config.map(|c| {
|
||||
lsp_log!(" Auto-resolved configuration file: \"{}\"", c.specifier);
|
||||
c
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_diagnosable(&self, specifier: &ModuleSpecifier) -> bool {
|
||||
|
|
|
@ -207,12 +207,7 @@ impl ProcState {
|
|||
None
|
||||
};
|
||||
|
||||
let maybe_config_file =
|
||||
if let Some(config_path) = flags.config_path.as_ref() {
|
||||
Some(ConfigFile::read(config_path)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let maybe_config_file = crate::config_file::discover(&flags)?;
|
||||
|
||||
let maybe_import_map: Option<Arc<ImportMap>> =
|
||||
match flags.import_map_path.as_ref() {
|
||||
|
|
|
@ -177,13 +177,18 @@ itest!(fmt_stdin_check_not_formatted {
|
|||
});
|
||||
|
||||
itest!(fmt_with_config {
|
||||
args: "fmt --config fmt/deno.jsonc fmt/fmt_with_config/",
|
||||
args: "fmt --config fmt/with_config/deno.jsonc fmt/with_config/subdir",
|
||||
output: "fmt/fmt_with_config.out",
|
||||
});
|
||||
|
||||
itest!(fmt_with_config_default {
|
||||
args: "fmt fmt/with_config/subdir",
|
||||
output: "fmt/fmt_with_config.out",
|
||||
});
|
||||
|
||||
// Check if CLI flags take precedence
|
||||
itest!(fmt_with_config_and_flags {
|
||||
args: "fmt --config fmt/deno.jsonc --ignore=fmt/fmt_with_config/a.ts,fmt/fmt_with_config/b.ts",
|
||||
args: "fmt --config fmt/with_config/deno.jsonc --ignore=fmt/with_config/subdir/a.ts,fmt/with_config/subdir/b.ts",
|
||||
output: "fmt/fmt_with_config_and_flags.out",
|
||||
});
|
||||
|
||||
|
|
|
@ -55,12 +55,12 @@ where
|
|||
client
|
||||
.write_response(
|
||||
id,
|
||||
json!({
|
||||
json!([{
|
||||
"enable": true,
|
||||
"codeLens": {
|
||||
"test": true
|
||||
}
|
||||
}),
|
||||
}]),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -564,7 +564,7 @@ fn lsp_hover_disabled() {
|
|||
let (id, method, _) = client.read_request::<Value>().unwrap();
|
||||
assert_eq!(method, "workspace/configuration");
|
||||
client
|
||||
.write_response(id, json!({ "enable": false }))
|
||||
.write_response(id, json!([{ "enable": false }]))
|
||||
.unwrap();
|
||||
|
||||
let (maybe_res, maybe_err) = client
|
||||
|
@ -814,7 +814,7 @@ fn lsp_hover_closed_document() {
|
|||
let (id, method, _) = client.read_request::<Value>().unwrap();
|
||||
assert_eq!(method, "workspace/configuration");
|
||||
client
|
||||
.write_response(id, json!({ "enable": true }))
|
||||
.write_response(id, json!([{ "enable": true }]))
|
||||
.unwrap();
|
||||
|
||||
client
|
||||
|
@ -833,7 +833,7 @@ fn lsp_hover_closed_document() {
|
|||
let (id, method, _) = client.read_request::<Value>().unwrap();
|
||||
assert_eq!(method, "workspace/configuration");
|
||||
client
|
||||
.write_response(id, json!({ "enable": true }))
|
||||
.write_response(id, json!([{ "enable": true }]))
|
||||
.unwrap();
|
||||
|
||||
let (method, _) = client.read_notification::<Value>().unwrap();
|
||||
|
@ -1542,6 +1542,58 @@ fn lsp_format_exclude_with_config() {
|
|||
shutdown(&mut client);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lsp_format_exclude_default_config() {
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let workspace_root = temp_dir.path().canonicalize().unwrap();
|
||||
let mut params: lsp::InitializeParams =
|
||||
serde_json::from_value(load_fixture("initialize_params.json")).unwrap();
|
||||
let deno_jsonc =
|
||||
serde_json::to_vec_pretty(&load_fixture("deno.fmt.exclude.jsonc")).unwrap();
|
||||
fs::write(workspace_root.join("deno.jsonc"), deno_jsonc).unwrap();
|
||||
|
||||
params.root_uri = Some(Url::from_file_path(workspace_root.clone()).unwrap());
|
||||
|
||||
let deno_exe = deno_exe_path();
|
||||
let mut client = LspClient::new(&deno_exe).unwrap();
|
||||
client
|
||||
.write_request::<_, _, Value>("initialize", params)
|
||||
.unwrap();
|
||||
|
||||
let file_uri =
|
||||
ModuleSpecifier::from_file_path(workspace_root.join("ignored.ts"))
|
||||
.unwrap()
|
||||
.to_string();
|
||||
did_open(
|
||||
&mut client,
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": file_uri,
|
||||
"languageId": "typescript",
|
||||
"version": 1,
|
||||
"text": "function myFunc(){}"
|
||||
}
|
||||
}),
|
||||
);
|
||||
let (maybe_res, maybe_err) = client
|
||||
.write_request(
|
||||
"textDocument/formatting",
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": file_uri
|
||||
},
|
||||
"options": {
|
||||
"tabSize": 2,
|
||||
"insertSpaces": true
|
||||
}
|
||||
}),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(maybe_err.is_none());
|
||||
assert_eq!(maybe_res, Some(json!(null)));
|
||||
shutdown(&mut client);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lsp_large_doc_changes() {
|
||||
let mut client = init("initialize_params.json");
|
||||
|
@ -2085,12 +2137,12 @@ fn lsp_code_lens_test_disabled() {
|
|||
client
|
||||
.write_response(
|
||||
id,
|
||||
json!({
|
||||
json!([{
|
||||
"enable": true,
|
||||
"codeLens": {
|
||||
"test": false
|
||||
}
|
||||
}),
|
||||
}]),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -2467,7 +2519,7 @@ fn lsp_code_actions_deno_cache() {
|
|||
let (id, method, _) = client.read_request::<Value>().unwrap();
|
||||
assert_eq!(method, "workspace/configuration");
|
||||
client
|
||||
.write_response(id, json!({ "enable": true }))
|
||||
.write_response(id, json!([{ "enable": true }]))
|
||||
.unwrap();
|
||||
let (method, _) = client.read_notification::<Value>().unwrap();
|
||||
assert_eq!(method, "textDocument/publishDiagnostics");
|
||||
|
@ -2641,7 +2693,7 @@ fn lsp_code_actions_deadlock() {
|
|||
let (id, method, _) = client.read_request::<Value>().unwrap();
|
||||
assert_eq!(method, "workspace/configuration");
|
||||
client
|
||||
.write_response(id, json!({ "enable": true }))
|
||||
.write_response(id, json!([{ "enable": true }]))
|
||||
.unwrap();
|
||||
let (maybe_res, maybe_err) = client
|
||||
.write_request::<_, _, Value>(
|
||||
|
@ -3301,7 +3353,7 @@ fn lsp_diagnostics_deno_types() {
|
|||
let (id, method, _) = client.read_request::<Value>().unwrap();
|
||||
assert_eq!(method, "workspace/configuration");
|
||||
client
|
||||
.write_response(id, json!({ "enable": true }))
|
||||
.write_response(id, json!([{ "enable": true }]))
|
||||
.unwrap();
|
||||
let (maybe_res, maybe_err) = client
|
||||
.write_request::<_, _, Value>(
|
||||
|
@ -3354,34 +3406,20 @@ fn lsp_diagnostics_refresh_dependents() {
|
|||
},
|
||||
}),
|
||||
);
|
||||
client
|
||||
.write_notification(
|
||||
"textDocument/didOpen",
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": "file:///a/file_02.ts",
|
||||
"languageId": "typescript",
|
||||
"version": 1,
|
||||
"text": "import { a, b } from \"./file_01.ts\";\n\nconsole.log(a, b);\n"
|
||||
}
|
||||
}),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let (id, method, _) = client.read_request::<Value>().unwrap();
|
||||
assert_eq!(method, "workspace/configuration");
|
||||
client
|
||||
.write_response(id, json!({ "enable": false }))
|
||||
.unwrap();
|
||||
let (method, _) = client.read_notification::<Value>().unwrap();
|
||||
assert_eq!(method, "textDocument/publishDiagnostics");
|
||||
let (method, _) = client.read_notification::<Value>().unwrap();
|
||||
assert_eq!(method, "textDocument/publishDiagnostics");
|
||||
let (method, maybe_params) = client.read_notification::<Value>().unwrap();
|
||||
assert_eq!(method, "textDocument/publishDiagnostics");
|
||||
let diagnostics = did_open(
|
||||
&mut client,
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": "file:///a/file_02.ts",
|
||||
"languageId": "typescript",
|
||||
"version": 1,
|
||||
"text": "import { a, b } from \"./file_01.ts\";\n\nconsole.log(a, b);\n"
|
||||
}
|
||||
}),
|
||||
);
|
||||
assert_eq!(
|
||||
maybe_params,
|
||||
Some(json!({
|
||||
json!(diagnostics[2]),
|
||||
json!({
|
||||
"uri": "file:///a/file_02.ts",
|
||||
"diagnostics": [
|
||||
{
|
||||
|
@ -3402,7 +3440,7 @@ fn lsp_diagnostics_refresh_dependents() {
|
|||
}
|
||||
],
|
||||
"version": 1
|
||||
}))
|
||||
})
|
||||
);
|
||||
client
|
||||
.write_notification(
|
||||
|
|
15
cli/tests/testdata/fmt/deno.jsonc
vendored
15
cli/tests/testdata/fmt/deno.jsonc
vendored
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"fmt": {
|
||||
"files": {
|
||||
"include": ["fmt_with_config/"],
|
||||
"exclude": ["fmt_with_config/b.ts"]
|
||||
},
|
||||
"options": {
|
||||
"useTabs": true,
|
||||
"lineWidth": 40,
|
||||
"indentWidth": 8,
|
||||
"singleQuote": true,
|
||||
"proseWrap": "always"
|
||||
}
|
||||
}
|
||||
}
|
19
cli/tests/testdata/fmt/with_config/deno.jsonc
vendored
Normal file
19
cli/tests/testdata/fmt/with_config/deno.jsonc
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"fmt": {
|
||||
"files": {
|
||||
"include": [
|
||||
"./subdir/"
|
||||
],
|
||||
"exclude": [
|
||||
"./subdir/b.ts"
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"useTabs": true,
|
||||
"lineWidth": 40,
|
||||
"indentWidth": 8,
|
||||
"singleQuote": true,
|
||||
"proseWrap": "always"
|
||||
}
|
||||
}
|
||||
}
|
1
cli/tests/testdata/malformed_config/deno.json
vendored
Normal file
1
cli/tests/testdata/malformed_config/deno.json
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
not a json file
|
|
@ -16,7 +16,7 @@ use crate::file_watcher;
|
|||
use crate::file_watcher::ResolutionResult;
|
||||
use crate::flags::FmtFlags;
|
||||
use crate::fs_util::specifier_to_file_path;
|
||||
use crate::fs_util::{collect_files, get_extension, is_supported_ext_fmt};
|
||||
use crate::fs_util::{collect_files, get_extension};
|
||||
use crate::text_encoding;
|
||||
use deno_ast::ParsedSource;
|
||||
use deno_core::anyhow::bail;
|
||||
|
@ -591,3 +591,55 @@ where
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// This function is similar to is_supported_ext but adds additional extensions
|
||||
/// supported by `deno fmt`.
|
||||
fn is_supported_ext_fmt(path: &Path) -> bool {
|
||||
if let Some(ext) = get_extension(path) {
|
||||
matches!(
|
||||
ext.as_str(),
|
||||
"ts"
|
||||
| "tsx"
|
||||
| "js"
|
||||
| "jsx"
|
||||
| "mjs"
|
||||
| "json"
|
||||
| "jsonc"
|
||||
| "md"
|
||||
| "mkd"
|
||||
| "mkdn"
|
||||
| "mdwn"
|
||||
| "mdown"
|
||||
| "markdown"
|
||||
)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_supported_ext_fmt() {
|
||||
assert!(!is_supported_ext_fmt(Path::new("tests/subdir/redirects")));
|
||||
assert!(is_supported_ext_fmt(Path::new("README.md")));
|
||||
assert!(is_supported_ext_fmt(Path::new("readme.MD")));
|
||||
assert!(is_supported_ext_fmt(Path::new("readme.mkd")));
|
||||
assert!(is_supported_ext_fmt(Path::new("readme.mkdn")));
|
||||
assert!(is_supported_ext_fmt(Path::new("readme.mdwn")));
|
||||
assert!(is_supported_ext_fmt(Path::new("readme.mdown")));
|
||||
assert!(is_supported_ext_fmt(Path::new("readme.markdown")));
|
||||
assert!(is_supported_ext_fmt(Path::new("lib/typescript.d.ts")));
|
||||
assert!(is_supported_ext_fmt(Path::new("testdata/001_hello.js")));
|
||||
assert!(is_supported_ext_fmt(Path::new("testdata/002_hello.ts")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.jsx")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.tsx")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.TS")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.TSX")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.JS")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.JSX")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.mjs")));
|
||||
assert!(!is_supported_ext_fmt(Path::new("foo.mjsx")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.jsonc")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.JSONC")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.json")));
|
||||
assert!(is_supported_ext_fmt(Path::new("foo.JsON")));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue