mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
feat: add markdown support to deno fmt (#8887)
This commit adds support for formatting markdown files with "deno fmt". Additionally "--ext={js|jsx|ts|tsx|md}" flag was added to "deno fmt" that allows to specify file type when providing contents over stdio.
This commit is contained in:
parent
4c223d0521
commit
16036a8a51
14 changed files with 328 additions and 80 deletions
|
@ -22,6 +22,7 @@
|
|||
"cli/dts/typescript.d.ts",
|
||||
"cli/tests/encoding",
|
||||
"cli/tests/inline_js_source_map*",
|
||||
"cli/tests/badly_formatted.md",
|
||||
"cli/tsc/*typescript.js",
|
||||
"test_util/wpt",
|
||||
"gh-pages",
|
||||
|
|
107
Cargo.lock
generated
107
Cargo.lock
generated
|
@ -78,7 +78,7 @@ dependencies = [
|
|||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"swc_macros_common",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -113,7 +113,7 @@ checksum = "a3548b8efc9f8e8a5a0a2808c5bd8451a9031b9e5b879a79590304ae928b0a70"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -124,7 +124,7 @@ checksum = "8d3a45e77e34375a7923b1e8febb049bb011f064714a8e17a1a616fef01da13d"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -147,7 +147,7 @@ dependencies = [
|
|||
"proc-macro-error",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -373,7 +373,7 @@ dependencies = [
|
|||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"strsim 0.9.3",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -384,7 +384,7 @@ checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72"
|
|||
dependencies = [
|
||||
"darling_core",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -420,6 +420,7 @@ dependencies = [
|
|||
"deno_web",
|
||||
"deno_websocket",
|
||||
"dissimilar",
|
||||
"dprint-plugin-markdown",
|
||||
"dprint-plugin-typescript",
|
||||
"encoding_rs",
|
||||
"env_logger",
|
||||
|
@ -613,7 +614,7 @@ checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -656,9 +657,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "dprint-core"
|
||||
version = "0.34.0"
|
||||
version = "0.35.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7fc292281fc3ec69dfbd36c3c5c73886469a6630e1747ff452b46f5deed208d"
|
||||
checksum = "87368d637be4fedbddd60e41958e227af4d7d32127b9a5a6cb05b0053b525f94"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"fnv",
|
||||
|
@ -666,10 +667,22 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "dprint-plugin-typescript"
|
||||
version = "0.38.1"
|
||||
name = "dprint-plugin-markdown"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67bb41b131e30df80105eb6b4f183a4bf003ee7dfb20661ac15a2a6f329de5b1"
|
||||
checksum = "45dd3b8784047301e25e27ab168c79d86f883f65b83d26df31785cf4db144137"
|
||||
dependencies = [
|
||||
"dprint-core",
|
||||
"pulldown-cmark",
|
||||
"regex",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dprint-plugin-typescript"
|
||||
version = "0.38.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54feef4e4c831395dd5874500be4b37ce9ae175c1fe1a00e3ec97abd9287a6eb"
|
||||
dependencies = [
|
||||
"dprint-core",
|
||||
"dprint-swc-ecma-ast-view",
|
||||
|
@ -723,7 +736,7 @@ dependencies = [
|
|||
"heck",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -735,7 +748,7 @@ dependencies = [
|
|||
"pmutil",
|
||||
"proc-macro2 1.0.24",
|
||||
"swc_macros_common",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -848,7 +861,7 @@ dependencies = [
|
|||
"pmutil",
|
||||
"proc-macro2 1.0.24",
|
||||
"swc_macros_common",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -969,7 +982,7 @@ dependencies = [
|
|||
"proc-macro-hack",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1305,7 +1318,7 @@ dependencies = [
|
|||
"pmutil",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1436,7 +1449,7 @@ dependencies = [
|
|||
"heck",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1778,7 +1791,7 @@ dependencies = [
|
|||
"proc-macro-hack",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1816,7 +1829,7 @@ checksum = "2c0e815c3ee9a031fdf5af21c10aa17c573c9c6a566328d99e3936c34e36461f"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1827,7 +1840,7 @@ checksum = "caa25a6393f22ce819b0f50e0be89287292fda8d425be38ee0ca14c4931d9e71"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1850,7 +1863,7 @@ checksum = "3894e5d549cccbe44afecf72922f277f603cd4bb0219c8342631ef18fffbe004"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1874,7 +1887,7 @@ dependencies = [
|
|||
"proc-macro-error-attr",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
|
@ -1929,6 +1942,17 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"memchr",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "1.2.3"
|
||||
|
@ -2236,7 +2260,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "db9dfbf470021de34cfaf6983067f460ea19164934a7c2d4b92eec0968eb95f1"
|
||||
dependencies = [
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2317,7 +2341,7 @@ checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2340,7 +2364,7 @@ checksum = "2dc6b7951b17b051f3210b063f12cc17320e2fe30ae05b0fe2a3abb068551c76"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2477,7 +2501,7 @@ dependencies = [
|
|||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"swc_macros_common",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2593,7 +2617,7 @@ dependencies = [
|
|||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"swc_macros_common",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2796,7 +2820,7 @@ dependencies = [
|
|||
"pmutil",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2808,7 +2832,7 @@ dependencies = [
|
|||
"pmutil",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2832,7 +2856,7 @@ dependencies = [
|
|||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"swc_macros_common",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2848,9 +2872,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.56"
|
||||
version = "1.0.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9802ddde94170d186eeee5005b798d9c159fa970403f1be19976d0cfb939b72"
|
||||
checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
|
@ -2950,7 +2974,7 @@ checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3007,7 +3031,7 @@ checksum = "42517d2975ca3114b22a16192634e8241dc5cc1f130be194645970cc1c371494"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3263,6 +3287,15 @@ version = "0.1.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.4"
|
||||
|
@ -3413,7 +3446,7 @@ dependencies = [
|
|||
"log",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
@ -3447,7 +3480,7 @@ checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.56",
|
||||
"syn 1.0.58",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
|
|
@ -46,7 +46,8 @@ base64 = "0.13.0"
|
|||
byteorder = "1.4.2"
|
||||
clap = "2.33.3"
|
||||
dissimilar = "1.0.2"
|
||||
dprint-plugin-typescript = "0.38.1"
|
||||
dprint-plugin-typescript = "0.38.3"
|
||||
dprint-plugin-markdown = "0.5.1"
|
||||
encoding_rs = "0.8.26"
|
||||
env_logger = "0.8.2"
|
||||
filetime = "0.2.13"
|
||||
|
|
17
cli/flags.rs
17
cli/flags.rs
|
@ -50,6 +50,7 @@ pub enum DenoSubcommand {
|
|||
check: bool,
|
||||
files: Vec<PathBuf>,
|
||||
ignore: Vec<PathBuf>,
|
||||
ext: String,
|
||||
},
|
||||
Info {
|
||||
json: bool,
|
||||
|
@ -400,8 +401,11 @@ fn fmt_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
|||
Some(f) => f.map(PathBuf::from).collect(),
|
||||
None => vec![],
|
||||
};
|
||||
let ext = matches.value_of("ext").unwrap().to_string();
|
||||
|
||||
flags.subcommand = DenoSubcommand::Fmt {
|
||||
check: matches.is_present("check"),
|
||||
ext,
|
||||
files,
|
||||
ignore,
|
||||
}
|
||||
|
@ -809,6 +813,14 @@ Ignore formatting a file by adding an ignore comment at the top of the file:
|
|||
.help("Check if the source files are formatted")
|
||||
.takes_value(false),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("ext")
|
||||
.long("ext")
|
||||
.help("Set standard input (stdin) content type")
|
||||
.takes_value(true)
|
||||
.default_value("ts")
|
||||
.possible_values(&["ts", "tsx", "js", "jsx", "md"]),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("ignore")
|
||||
.long("ignore")
|
||||
|
@ -1991,6 +2003,7 @@ mod tests {
|
|||
PathBuf::from("script_1.ts"),
|
||||
PathBuf::from("script_2.ts")
|
||||
],
|
||||
ext: "ts".to_string()
|
||||
},
|
||||
..Flags::default()
|
||||
}
|
||||
|
@ -2004,6 +2017,7 @@ mod tests {
|
|||
ignore: vec![],
|
||||
check: true,
|
||||
files: vec![],
|
||||
ext: "ts".to_string(),
|
||||
},
|
||||
..Flags::default()
|
||||
}
|
||||
|
@ -2017,6 +2031,7 @@ mod tests {
|
|||
ignore: vec![],
|
||||
check: false,
|
||||
files: vec![],
|
||||
ext: "ts".to_string(),
|
||||
},
|
||||
..Flags::default()
|
||||
}
|
||||
|
@ -2030,6 +2045,7 @@ mod tests {
|
|||
ignore: vec![],
|
||||
check: false,
|
||||
files: vec![],
|
||||
ext: "ts".to_string(),
|
||||
},
|
||||
watch: true,
|
||||
unstable: true,
|
||||
|
@ -2053,6 +2069,7 @@ mod tests {
|
|||
ignore: vec![PathBuf::from("bar.js")],
|
||||
check: true,
|
||||
files: vec![PathBuf::from("foo.ts")],
|
||||
ext: "ts".to_string(),
|
||||
},
|
||||
watch: true,
|
||||
unstable: true,
|
||||
|
|
|
@ -90,17 +90,30 @@ pub fn resolve_from_cwd(path: &Path) -> Result<PathBuf, AnyError> {
|
|||
|
||||
/// Checks if the path has extension Deno supports.
|
||||
pub fn is_supported_ext(path: &Path) -> bool {
|
||||
let lowercase_ext = path
|
||||
.extension()
|
||||
.and_then(|e| e.to_str())
|
||||
.map(|e| e.to_lowercase());
|
||||
if let Some(ext) = lowercase_ext {
|
||||
ext == "ts" || ext == "tsx" || ext == "js" || ext == "jsx" || ext == "mjs"
|
||||
if let Some(ext) = get_extension(path) {
|
||||
matches!(ext.as_str(), "ts" | "tsx" | "js" | "jsx" | "mjs")
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// This function is similar to is_supported_ext but also allows .md extension.
|
||||
pub fn is_supported_ext_md(path: &Path) -> bool {
|
||||
if let Some(ext) = get_extension(path) {
|
||||
matches!(ext.as_str(), "ts" | "tsx" | "js" | "jsx" | "mjs" | "md")
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the extension of a file in lowercase.
|
||||
pub fn get_extension(file_path: &Path) -> Option<String> {
|
||||
return file_path
|
||||
.extension()
|
||||
.and_then(|e| e.to_str())
|
||||
.map(|e| e.to_lowercase());
|
||||
}
|
||||
|
||||
/// Collects file paths that satisfy the given predicate, by recursively walking `files`.
|
||||
/// If the walker visits a path that is listed in `ignore`, it skips descending into the directory.
|
||||
pub fn collect_files<P>(
|
||||
|
@ -207,6 +220,24 @@ mod tests {
|
|||
assert!(!is_supported_ext(Path::new("foo.mjsx")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_supported_ext_md() {
|
||||
assert!(!is_supported_ext_md(Path::new("tests/subdir/redirects")));
|
||||
assert!(is_supported_ext_md(Path::new("README.md")));
|
||||
assert!(is_supported_ext_md(Path::new("readme.MD")));
|
||||
assert!(is_supported_ext_md(Path::new("lib/typescript.d.ts")));
|
||||
assert!(is_supported_ext_md(Path::new("cli/tests/001_hello.js")));
|
||||
assert!(is_supported_ext_md(Path::new("cli/tests/002_hello.ts")));
|
||||
assert!(is_supported_ext_md(Path::new("foo.jsx")));
|
||||
assert!(is_supported_ext_md(Path::new("foo.tsx")));
|
||||
assert!(is_supported_ext_md(Path::new("foo.TS")));
|
||||
assert!(is_supported_ext_md(Path::new("foo.TSX")));
|
||||
assert!(is_supported_ext_md(Path::new("foo.JS")));
|
||||
assert!(is_supported_ext_md(Path::new("foo.JSX")));
|
||||
assert!(is_supported_ext_md(Path::new("foo.mjs")));
|
||||
assert!(!is_supported_ext_md(Path::new("foo.mjsx")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_collect_files() {
|
||||
fn create_files(dir_path: &PathBuf, files: &[&str]) {
|
||||
|
|
|
@ -807,9 +807,10 @@ async fn format_command(
|
|||
args: Vec<PathBuf>,
|
||||
ignore: Vec<PathBuf>,
|
||||
check: bool,
|
||||
ext: String,
|
||||
) -> Result<(), AnyError> {
|
||||
if args.len() == 1 && args[0].to_string_lossy() == "-" {
|
||||
return tools::fmt::format_stdin(check);
|
||||
return tools::fmt::format_stdin(check, ext);
|
||||
}
|
||||
|
||||
tools::fmt::format(args, ignore, check, flags.watch).await?;
|
||||
|
@ -1179,7 +1180,8 @@ fn get_subcommand(
|
|||
check,
|
||||
files,
|
||||
ignore,
|
||||
} => format_command(flags, files, ignore, check).boxed_local(),
|
||||
ext,
|
||||
} => format_command(flags, files, ignore, check, ext).boxed_local(),
|
||||
DenoSubcommand::Info { file, json } => {
|
||||
info_command(flags, file, json).boxed_local()
|
||||
}
|
||||
|
|
28
cli/tests/badly_formatted.md
Normal file
28
cli/tests/badly_formatted.md
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Hello Markdown
|
||||
|
||||
```js
|
||||
console.log("Hello World"
|
||||
|
||||
)
|
||||
```
|
||||
|
||||
```javascript
|
||||
console.log("Hello World2"
|
||||
|
||||
)
|
||||
```
|
||||
|
||||
```ts
|
||||
|
||||
function hello(name: string ) {
|
||||
console.log(name);
|
||||
};
|
||||
|
||||
hello( "alice");
|
||||
```
|
||||
|
||||
```typescript
|
||||
function foo(): number {
|
||||
return 2;
|
||||
}
|
||||
```
|
23
cli/tests/badly_formatted_fixed.md
Normal file
23
cli/tests/badly_formatted_fixed.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Hello Markdown
|
||||
|
||||
```js
|
||||
console.log("Hello World");
|
||||
```
|
||||
|
||||
```javascript
|
||||
console.log("Hello World2");
|
||||
```
|
||||
|
||||
```ts
|
||||
function hello(name: string) {
|
||||
console.log(name);
|
||||
}
|
||||
|
||||
hello("alice");
|
||||
```
|
||||
|
||||
```typescript
|
||||
function foo(): number {
|
||||
return 2;
|
||||
}
|
||||
```
|
|
@ -1 +1 @@
|
|||
Checked 2 files
|
||||
Checked 3 files
|
||||
|
|
|
@ -1 +1 @@
|
|||
Checked 1 file
|
||||
Checked 2 files
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[WILDCARD]
|
||||
error: Found 5 not formatted files in [WILDCARD] files
|
||||
error: Found 6 not formatted files in [WILDCARD] files
|
||||
|
|
17
cli/tests/fmt/formatted3.md
Normal file
17
cli/tests/fmt/formatted3.md
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Hello
|
||||
|
||||
```js
|
||||
function foo() {
|
||||
return 42;
|
||||
}
|
||||
|
||||
foo();
|
||||
```
|
||||
|
||||
```ts
|
||||
function bar(): number {
|
||||
return 42;
|
||||
}
|
||||
|
||||
bar();
|
||||
```
|
|
@ -511,20 +511,31 @@ fn cache_invalidation_test_no_check() {
|
|||
#[test]
|
||||
fn fmt_test() {
|
||||
let t = TempDir::new().expect("tempdir fail");
|
||||
let fixed = util::root_path().join("cli/tests/badly_formatted_fixed.js");
|
||||
let badly_formatted_original =
|
||||
let fixed_js = util::root_path().join("cli/tests/badly_formatted_fixed.js");
|
||||
let fixed_md = util::root_path().join("cli/tests/badly_formatted_fixed.md");
|
||||
let badly_formatted_original_js =
|
||||
util::root_path().join("cli/tests/badly_formatted.mjs");
|
||||
let badly_formatted = t.path().join("badly_formatted.js");
|
||||
let badly_formatted_str = badly_formatted.to_str().unwrap();
|
||||
std::fs::copy(&badly_formatted_original, &badly_formatted)
|
||||
let badly_formatted_original_md =
|
||||
util::root_path().join("cli/tests/badly_formatted.md");
|
||||
let badly_formatted_js = t.path().join("badly_formatted.js");
|
||||
let badly_formatted_md = t.path().join("badly_formatted.md");
|
||||
let badly_formatted_js_str = badly_formatted_js.to_str().unwrap();
|
||||
let badly_formatted_md_str = badly_formatted_md.to_str().unwrap();
|
||||
std::fs::copy(&badly_formatted_original_js, &badly_formatted_js)
|
||||
.expect("Failed to copy file");
|
||||
std::fs::copy(&badly_formatted_original_md, &badly_formatted_md)
|
||||
.expect("Failed to copy file");
|
||||
// First, check formatting by ignoring the badly formatted file.
|
||||
let status = util::deno_cmd()
|
||||
.current_dir(util::root_path())
|
||||
.arg("fmt")
|
||||
.arg(format!("--ignore={}", badly_formatted_str))
|
||||
.arg(format!(
|
||||
"--ignore={},{}",
|
||||
badly_formatted_js_str, badly_formatted_md_str
|
||||
))
|
||||
.arg("--check")
|
||||
.arg(badly_formatted_str)
|
||||
.arg(badly_formatted_js_str)
|
||||
.arg(badly_formatted_md_str)
|
||||
.spawn()
|
||||
.expect("Failed to spawn script")
|
||||
.wait()
|
||||
|
@ -535,7 +546,8 @@ fn fmt_test() {
|
|||
.current_dir(util::root_path())
|
||||
.arg("fmt")
|
||||
.arg("--check")
|
||||
.arg(badly_formatted_str)
|
||||
.arg(badly_formatted_js_str)
|
||||
.arg(badly_formatted_md_str)
|
||||
.spawn()
|
||||
.expect("Failed to spawn script")
|
||||
.wait()
|
||||
|
@ -545,15 +557,19 @@ fn fmt_test() {
|
|||
let status = util::deno_cmd()
|
||||
.current_dir(util::root_path())
|
||||
.arg("fmt")
|
||||
.arg(badly_formatted_str)
|
||||
.arg(badly_formatted_js_str)
|
||||
.arg(badly_formatted_md_str)
|
||||
.spawn()
|
||||
.expect("Failed to spawn script")
|
||||
.wait()
|
||||
.expect("Failed to wait for child process");
|
||||
assert!(status.success());
|
||||
let expected = std::fs::read_to_string(fixed).unwrap();
|
||||
let actual = std::fs::read_to_string(badly_formatted).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
let expected_js = std::fs::read_to_string(fixed_js).unwrap();
|
||||
let expected_md = std::fs::read_to_string(fixed_md).unwrap();
|
||||
let actual_js = std::fs::read_to_string(badly_formatted_js).unwrap();
|
||||
let actual_md = std::fs::read_to_string(badly_formatted_md).unwrap();
|
||||
assert_eq!(expected_js, actual_js);
|
||||
assert_eq!(expected_md, actual_md);
|
||||
}
|
||||
|
||||
// Helper function to skip watcher output that contains "Restarting"
|
||||
|
@ -2751,7 +2767,7 @@ itest!(fmt_quiet_check_fmt_dir {
|
|||
});
|
||||
|
||||
itest!(fmt_check_formatted_files {
|
||||
args: "fmt --check fmt/formatted1.js fmt/formatted2.ts",
|
||||
args: "fmt --check fmt/formatted1.js fmt/formatted2.ts fmt/formatted3.md",
|
||||
output: "fmt/expected_fmt_check_formatted_files.out",
|
||||
exit_code: 0,
|
||||
});
|
||||
|
@ -2768,6 +2784,12 @@ itest!(fmt_stdin {
|
|||
output_str: Some("const a = 1;\n"),
|
||||
});
|
||||
|
||||
itest!(fmt_stdin_markdown {
|
||||
args: "fmt --ext=md -",
|
||||
input: Some("# Hello Markdown\n```ts\nconsole.log( \"text\")\n```\n"),
|
||||
output_str: Some("# Hello Markdown\n\n```ts\nconsole.log(\"text\");\n```\n"),
|
||||
});
|
||||
|
||||
itest!(fmt_stdin_check_formatted {
|
||||
args: "fmt --check -",
|
||||
input: Some("const a = 1;\n"),
|
||||
|
|
109
cli/tools/fmt.rs
109
cli/tools/fmt.rs
|
@ -10,13 +10,12 @@
|
|||
use crate::colors;
|
||||
use crate::diff::diff;
|
||||
use crate::file_watcher;
|
||||
use crate::fs_util::{collect_files, is_supported_ext};
|
||||
use crate::fs_util::{collect_files, get_extension, is_supported_ext_md};
|
||||
use crate::text_encoding;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures;
|
||||
use deno_core::futures::FutureExt;
|
||||
use dprint_plugin_typescript as dprint;
|
||||
use std::fs;
|
||||
use std::io::stdin;
|
||||
use std::io::stdout;
|
||||
|
@ -38,11 +37,10 @@ pub async fn format(
|
|||
) -> Result<(), AnyError> {
|
||||
let target_file_resolver = || {
|
||||
// collect the files that are to be formatted
|
||||
collect_files(&args, &ignore, is_supported_ext)
|
||||
collect_files(&args, &ignore, is_supported_ext_md)
|
||||
};
|
||||
|
||||
let operation = |paths: Vec<PathBuf>| {
|
||||
let config = get_config();
|
||||
let config = get_typescript_config();
|
||||
async move {
|
||||
if check {
|
||||
check_source_files(config, paths).await?;
|
||||
|
@ -63,8 +61,48 @@ pub async fn format(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Formats markdown (using https://github.com/dprint/dprint-plugin-markdown) and its code blocks
|
||||
/// (ts/tsx, js/jsx).
|
||||
fn format_markdown(
|
||||
file_text: &str,
|
||||
ts_config: dprint_plugin_typescript::configuration::Configuration,
|
||||
) -> Result<String, String> {
|
||||
let md_config = get_markdown_config();
|
||||
dprint_plugin_markdown::format_text(
|
||||
&file_text,
|
||||
&md_config,
|
||||
Box::new(move |tag, text, line_width| {
|
||||
let tag = tag.to_lowercase();
|
||||
if matches!(
|
||||
tag.as_str(),
|
||||
"ts" | "tsx" | "js" | "jsx" | "javascript" | "typescript"
|
||||
) {
|
||||
// It's important to tell dprint proper file extension, otherwise
|
||||
// it might parse the file twice.
|
||||
let extension = match tag.as_str() {
|
||||
"javascript" => "js",
|
||||
"typescript" => "ts",
|
||||
rest => rest,
|
||||
};
|
||||
let fake_filename =
|
||||
PathBuf::from(format!("deno_fmt_stdin.{}", extension));
|
||||
|
||||
let mut codeblock_config = ts_config.clone();
|
||||
codeblock_config.line_width = line_width;
|
||||
dprint_plugin_typescript::format_text(
|
||||
&fake_filename,
|
||||
&text,
|
||||
&codeblock_config,
|
||||
)
|
||||
} else {
|
||||
Ok(text.to_string())
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
async fn check_source_files(
|
||||
config: dprint::configuration::Configuration,
|
||||
config: dprint_plugin_typescript::configuration::Configuration,
|
||||
paths: Vec<PathBuf>,
|
||||
) -> Result<(), AnyError> {
|
||||
let not_formatted_files_count = Arc::new(AtomicUsize::new(0));
|
||||
|
@ -79,7 +117,12 @@ async fn check_source_files(
|
|||
move |file_path| {
|
||||
checked_files_count.fetch_add(1, Ordering::Relaxed);
|
||||
let file_text = read_file_contents(&file_path)?.text;
|
||||
let r = dprint::format_text(&file_path, &file_text, &config);
|
||||
let ext = get_extension(&file_path).unwrap_or_else(String::new);
|
||||
let r = if ext == "md" {
|
||||
format_markdown(&file_text, config.clone())
|
||||
} else {
|
||||
dprint_plugin_typescript::format_text(&file_path, &file_text, &config)
|
||||
};
|
||||
match r {
|
||||
Ok(formatted_text) => {
|
||||
if formatted_text != file_text {
|
||||
|
@ -120,7 +163,7 @@ async fn check_source_files(
|
|||
}
|
||||
|
||||
async fn format_source_files(
|
||||
config: dprint::configuration::Configuration,
|
||||
config: dprint_plugin_typescript::configuration::Configuration,
|
||||
paths: Vec<PathBuf>,
|
||||
) -> Result<(), AnyError> {
|
||||
let formatted_files_count = Arc::new(AtomicUsize::new(0));
|
||||
|
@ -133,7 +176,16 @@ async fn format_source_files(
|
|||
move |file_path| {
|
||||
checked_files_count.fetch_add(1, Ordering::Relaxed);
|
||||
let file_contents = read_file_contents(&file_path)?;
|
||||
let r = dprint::format_text(&file_path, &file_contents.text, &config);
|
||||
let ext = get_extension(&file_path).unwrap_or_else(String::new);
|
||||
let r = if ext == "md" {
|
||||
format_markdown(&file_contents.text, config.clone())
|
||||
} else {
|
||||
dprint_plugin_typescript::format_text(
|
||||
&file_path,
|
||||
&file_contents.text,
|
||||
&config,
|
||||
)
|
||||
};
|
||||
match r {
|
||||
Ok(formatted_text) => {
|
||||
if formatted_text != file_contents.text {
|
||||
|
@ -178,17 +230,25 @@ async fn format_source_files(
|
|||
}
|
||||
|
||||
/// Format stdin and write result to stdout.
|
||||
/// Treats input as TypeScript.
|
||||
/// Treats input as TypeScript or as set by `--ext` flag.
|
||||
/// Compatible with `--check` flag.
|
||||
pub fn format_stdin(check: bool) -> Result<(), AnyError> {
|
||||
pub fn format_stdin(check: bool, ext: String) -> Result<(), AnyError> {
|
||||
let mut source = String::new();
|
||||
if stdin().read_to_string(&mut source).is_err() {
|
||||
return Err(generic_error("Failed to read from stdin"));
|
||||
}
|
||||
let config = get_config();
|
||||
|
||||
// dprint will fallback to jsx parsing if parsing this as a .ts file doesn't work
|
||||
match dprint::format_text(&PathBuf::from("_stdin.ts"), &source, &config) {
|
||||
let config = get_typescript_config();
|
||||
let r = if ext.as_str() == "md" {
|
||||
format_markdown(&source, config)
|
||||
} else {
|
||||
// dprint will fallback to jsx parsing if parsing this as a .ts file doesn't work
|
||||
dprint_plugin_typescript::format_text(
|
||||
&PathBuf::from("_stdin.ts"),
|
||||
&source,
|
||||
&config,
|
||||
)
|
||||
};
|
||||
match r {
|
||||
Ok(formatted_text) => {
|
||||
if check {
|
||||
if formatted_text != source {
|
||||
|
@ -213,9 +273,22 @@ fn files_str(len: usize) -> &'static str {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_config() -> dprint::configuration::Configuration {
|
||||
use dprint::configuration::*;
|
||||
ConfigurationBuilder::new().deno().build()
|
||||
fn get_typescript_config(
|
||||
) -> dprint_plugin_typescript::configuration::Configuration {
|
||||
dprint_plugin_typescript::configuration::ConfigurationBuilder::new()
|
||||
.deno()
|
||||
.build()
|
||||
}
|
||||
|
||||
fn get_markdown_config() -> dprint_plugin_markdown::configuration::Configuration
|
||||
{
|
||||
dprint_plugin_markdown::configuration::ConfigurationBuilder::new()
|
||||
// Matches `.dprintrc.json` in the repository
|
||||
.text_wrap(dprint_plugin_markdown::configuration::TextWrap::Always)
|
||||
.ignore_directive("deno-fmt-ignore")
|
||||
.ignore_start_directive("deno-fmt-ignore-start")
|
||||
.ignore_end_directive("deno-fmt-ignore-end")
|
||||
.build()
|
||||
}
|
||||
|
||||
struct FileContents {
|
||||
|
|
Loading…
Reference in a new issue