From d9e2710d0c41a141c704aa1f00b2c083c17e5ee4 Mon Sep 17 00:00:00 2001 From: Sandipsinh Rathod Date: Mon, 15 Apr 2024 14:50:13 +0530 Subject: [PATCH 01/14] feat: tailcall prettier --- Cargo.lock | 9 ++++ Cargo.toml | 3 +- tailcall-prettier/Cargo.toml | 12 ++++++ tailcall-prettier/src/lib.rs | 80 ++++++++++++++++++++++++++++++++++++ tests/execution_spec.rs | 14 ++++++- 5 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 tailcall-prettier/Cargo.toml create mode 100644 tailcall-prettier/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 1b5d6e8a84..a4ead76ab0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5140,6 +5140,7 @@ dependencies = [ "serde_yaml", "stripmargin", "strum_macros 0.26.2", + "tailcall-prettier", "temp-env", "tempfile", "thiserror", @@ -5209,6 +5210,14 @@ dependencies = [ "worker", ] +[[package]] +name = "tailcall-prettier" +version = "0.1.0" +dependencies = [ + "anyhow", + "insta", +] + [[package]] name = "tailcall_query_plan" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index cd9b7ffada..ff7de49a3e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -148,6 +148,7 @@ tonic-types = "0.11.0" [dev-dependencies] +tailcall-prettier = {path = "tailcall-prettier"} criterion = "0.5.1" httpmock = "0.7.0" pretty_assertions = "1.4.0" @@ -195,7 +196,7 @@ members = [ ".", "tailcall-autogen", "tailcall-aws-lambda", - "tailcall-cloudflare", + "tailcall-cloudflare", "tailcall-prettier", "tailcall-query-plan", ] diff --git a/tailcall-prettier/Cargo.toml b/tailcall-prettier/Cargo.toml new file mode 100644 index 0000000000..904cbdffb3 --- /dev/null +++ b/tailcall-prettier/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "tailcall-prettier" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.82" + +[dev-dependencies] +insta = "1.38.0" \ No newline at end of file diff --git a/tailcall-prettier/src/lib.rs b/tailcall-prettier/src/lib.rs new file mode 100644 index 0000000000..c8d6a39f8d --- /dev/null +++ b/tailcall-prettier/src/lib.rs @@ -0,0 +1,80 @@ +use std::fmt::{Display, Formatter}; +use std::io::Write; +use std::process::{Command, Stdio}; + +use anyhow::{anyhow, Result}; + +enum FileTypes { + Gql, + Yml, + Json, + Md, + Ts, + Js, +} + +impl Display for FileTypes { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + FileTypes::Gql => write!(f, "graphql"), + FileTypes::Yml => write!(f, "yml"), + FileTypes::Json => write!(f, "json"), + FileTypes::Md => write!(f, "md"), + FileTypes::Ts => write!(f, "ts"), + FileTypes::Js => write!(f, "js"), + } + } +} + +impl FileTypes { + fn detect(path: &str) -> Result { + let ext = path + .split('.') + .last() + .ok_or(anyhow!("No file extension found"))? + .to_lowercase(); + match ext.as_str() { + "gql" | "graphql" => Ok(FileTypes::Gql), + "yml" | "yaml" => Ok(FileTypes::Yml), + "json" => Ok(FileTypes::Json), + "md" => Ok(FileTypes::Md), + "ts" => Ok(FileTypes::Ts), + "js" => Ok(FileTypes::Js), + _ => Err(anyhow!("Unsupported file type")), + } + } +} + +pub fn format_with_prettier>(code: T, file_ty: T) -> Result { + let file_ty = FileTypes::detect(file_ty.as_ref())?; + + let mut child = Command::new("prettier") + .arg("--stdin-filepath") + .arg(format!("file.{}", file_ty)) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn()?; + + if let Some(ref mut stdin) = child.stdin { + stdin.write_all(code.as_ref().as_bytes())?; + } + + let output = child.wait_with_output()?; + if output.status.success() { + Ok(String::from_utf8(output.stdout)?) + } else { + Err(anyhow!("Prettier formatting failed")) + } +} + +#[cfg(test)] +mod tests { + use crate::format_with_prettier; + + #[test] + fn test_js() -> anyhow::Result<()> { + let prettier = format_with_prettier("const x={a:3};", "file.ts")?; + insta::assert_snapshot!(prettier); + Ok(()) + } +} diff --git a/tests/execution_spec.rs b/tests/execution_spec.rs index 3c542f2c5a..53b022665c 100644 --- a/tests/execution_spec.rs +++ b/tests/execution_spec.rs @@ -889,9 +889,21 @@ async fn assert_spec(spec: ExecutionSpec, opentelemetry: &InMemoryTelemetry) { // \r is added automatically in windows, it's safe to replace it with \n let content = content.replace("\r\n", "\n"); + let identity = tailcall_prettier::format_with_prettier( + identity, + spec.path.display().to_string(), + ) + .unwrap(); + + let content = tailcall_prettier::format_with_prettier( + content, + spec.path.display().to_string(), + ) + .unwrap(); + pretty_assertions::assert_eq!( identity, - content.as_ref(), + content, "Identity check failed for {:#?}", spec.path, ); From a4b42866b5539d933aa38784c871c5c7e91203e6 Mon Sep 17 00:00:00 2001 From: Sandipsinh Rathod Date: Mon, 15 Apr 2024 14:54:13 +0530 Subject: [PATCH 02/14] add snapshot --- .../src/snapshots/tailcall_prettier__tests__js.snap | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 tailcall-prettier/src/snapshots/tailcall_prettier__tests__js.snap diff --git a/tailcall-prettier/src/snapshots/tailcall_prettier__tests__js.snap b/tailcall-prettier/src/snapshots/tailcall_prettier__tests__js.snap new file mode 100644 index 0000000000..f0c3f256af --- /dev/null +++ b/tailcall-prettier/src/snapshots/tailcall_prettier__tests__js.snap @@ -0,0 +1,5 @@ +--- +source: tailcall-prettier/src/lib.rs +expression: prettier +--- +const x = {a: 3} From 59e90a9d0deaecf5b6a0cc245f6ebb2824045bd2 Mon Sep 17 00:00:00 2001 From: Sandipsinh Rathod Date: Mon, 15 Apr 2024 15:51:11 +0530 Subject: [PATCH 03/14] drop `FileTypes` --- tailcall-prettier/src/lib.rs | 47 ++---------------------------------- 1 file changed, 2 insertions(+), 45 deletions(-) diff --git a/tailcall-prettier/src/lib.rs b/tailcall-prettier/src/lib.rs index c8d6a39f8d..afdd11d050 100644 --- a/tailcall-prettier/src/lib.rs +++ b/tailcall-prettier/src/lib.rs @@ -1,56 +1,13 @@ -use std::fmt::{Display, Formatter}; + use std::io::Write; use std::process::{Command, Stdio}; use anyhow::{anyhow, Result}; -enum FileTypes { - Gql, - Yml, - Json, - Md, - Ts, - Js, -} - -impl Display for FileTypes { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - FileTypes::Gql => write!(f, "graphql"), - FileTypes::Yml => write!(f, "yml"), - FileTypes::Json => write!(f, "json"), - FileTypes::Md => write!(f, "md"), - FileTypes::Ts => write!(f, "ts"), - FileTypes::Js => write!(f, "js"), - } - } -} - -impl FileTypes { - fn detect(path: &str) -> Result { - let ext = path - .split('.') - .last() - .ok_or(anyhow!("No file extension found"))? - .to_lowercase(); - match ext.as_str() { - "gql" | "graphql" => Ok(FileTypes::Gql), - "yml" | "yaml" => Ok(FileTypes::Yml), - "json" => Ok(FileTypes::Json), - "md" => Ok(FileTypes::Md), - "ts" => Ok(FileTypes::Ts), - "js" => Ok(FileTypes::Js), - _ => Err(anyhow!("Unsupported file type")), - } - } -} - pub fn format_with_prettier>(code: T, file_ty: T) -> Result { - let file_ty = FileTypes::detect(file_ty.as_ref())?; - let mut child = Command::new("prettier") .arg("--stdin-filepath") - .arg(format!("file.{}", file_ty)) + .arg(file_ty.as_ref()) .stdin(Stdio::piped()) .stdout(Stdio::piped()) .spawn()?; From 73fabe82d7f796fa27777774cf4356bf8b3fdd2b Mon Sep 17 00:00:00 2001 From: Sandipsinh Rathod Date: Mon, 15 Apr 2024 15:58:29 +0530 Subject: [PATCH 04/14] rename FileTypes to Parser --- Cargo.lock | 1 + tailcall-prettier/Cargo.toml | 1 + tailcall-prettier/src/lib.rs | 39 +++++++++++++++++++++++++++++++----- tests/execution_spec.rs | 6 ++++-- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a4ead76ab0..1b89fd8b97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5216,6 +5216,7 @@ version = "0.1.0" dependencies = [ "anyhow", "insta", + "strum_macros 0.26.2", ] [[package]] diff --git a/tailcall-prettier/Cargo.toml b/tailcall-prettier/Cargo.toml index 904cbdffb3..75ea1ff7f2 100644 --- a/tailcall-prettier/Cargo.toml +++ b/tailcall-prettier/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] anyhow = "1.0.82" +strum_macros = "0.26.2" [dev-dependencies] insta = "1.38.0" \ No newline at end of file diff --git a/tailcall-prettier/src/lib.rs b/tailcall-prettier/src/lib.rs index afdd11d050..6d4965a252 100644 --- a/tailcall-prettier/src/lib.rs +++ b/tailcall-prettier/src/lib.rs @@ -1,13 +1,42 @@ - use std::io::Write; use std::process::{Command, Stdio}; use anyhow::{anyhow, Result}; -pub fn format_with_prettier>(code: T, file_ty: T) -> Result { +#[derive(strum_macros::Display)] +pub enum Parser { + Gql, + Yml, + Json, + Md, + Ts, + Js, +} + +impl Parser { + pub fn detect(path: &str) -> Result { + let ext = path + .split('.') + .last() + .ok_or(anyhow!("No file extension found"))? + .to_lowercase(); + match ext.as_str() { + "gql" | "graphql" => Ok(Parser::Gql), + "yml" | "yaml" => Ok(Parser::Yml), + "json" => Ok(Parser::Json), + "md" => Ok(Parser::Md), + "ts" => Ok(Parser::Ts), + "js" => Ok(Parser::Js), + _ => Err(anyhow!("Unsupported file type")), + } + } +} + +pub fn format_with_prettier>(code: T, file_ty: Parser) -> Result { + let mut child = Command::new("prettier") .arg("--stdin-filepath") - .arg(file_ty.as_ref()) + .arg(format!("file.{}", file_ty.to_string())) .stdin(Stdio::piped()) .stdout(Stdio::piped()) .spawn()?; @@ -26,11 +55,11 @@ pub fn format_with_prettier>(code: T, file_ty: T) -> Result anyhow::Result<()> { - let prettier = format_with_prettier("const x={a:3};", "file.ts")?; + let prettier = format_with_prettier("const x={a:3};", Parser::Js)?; insta::assert_snapshot!(prettier); Ok(()) } diff --git a/tests/execution_spec.rs b/tests/execution_spec.rs index 53b022665c..c007cc35c0 100644 --- a/tests/execution_spec.rs +++ b/tests/execution_spec.rs @@ -889,15 +889,17 @@ async fn assert_spec(spec: ExecutionSpec, opentelemetry: &InMemoryTelemetry) { // \r is added automatically in windows, it's safe to replace it with \n let content = content.replace("\r\n", "\n"); + let path_str = spec.path.display().to_string(); + let identity = tailcall_prettier::format_with_prettier( identity, - spec.path.display().to_string(), + tailcall_prettier::Parser::detect(path_str.as_str()).unwrap(), ) .unwrap(); let content = tailcall_prettier::format_with_prettier( content, - spec.path.display().to_string(), + tailcall_prettier::Parser::detect(path_str.as_str()).unwrap(), ) .unwrap(); From 97e2c9d8f1135be6bc378a3c46cd5fa879ea2523 Mon Sep 17 00:00:00 2001 From: Sandipsinh Rathod Date: Mon, 15 Apr 2024 16:37:47 +0530 Subject: [PATCH 05/14] lint fixes --- tailcall-prettier/src/lib.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tailcall-prettier/src/lib.rs b/tailcall-prettier/src/lib.rs index 6d4965a252..a0c5b7fcaa 100644 --- a/tailcall-prettier/src/lib.rs +++ b/tailcall-prettier/src/lib.rs @@ -33,10 +33,9 @@ impl Parser { } pub fn format_with_prettier>(code: T, file_ty: Parser) -> Result { - let mut child = Command::new("prettier") .arg("--stdin-filepath") - .arg(format!("file.{}", file_ty.to_string())) + .arg(format!("file.{}", file_ty)) .stdin(Stdio::piped()) .stdout(Stdio::piped()) .spawn()?; @@ -55,7 +54,7 @@ pub fn format_with_prettier>(code: T, file_ty: Parser) -> Result anyhow::Result<()> { From febe4999ab88eb6336fdb65bf9c1b95f21080b48 Mon Sep 17 00:00:00 2001 From: Sandipsinh Rathod Date: Mon, 15 Apr 2024 16:42:03 +0530 Subject: [PATCH 06/14] drop unwanted snapshots --- tailcall-prettier/src/lib.rs | 2 +- .../src/snapshots/tailcall_prettier__tests__js.snap | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 tailcall-prettier/src/snapshots/tailcall_prettier__tests__js.snap diff --git a/tailcall-prettier/src/lib.rs b/tailcall-prettier/src/lib.rs index a0c5b7fcaa..28ea4169fe 100644 --- a/tailcall-prettier/src/lib.rs +++ b/tailcall-prettier/src/lib.rs @@ -59,7 +59,7 @@ mod tests { #[test] fn test_js() -> anyhow::Result<()> { let prettier = format_with_prettier("const x={a:3};", Parser::Js)?; - insta::assert_snapshot!(prettier); + assert_eq!("const x = {a: 3}\n",prettier); Ok(()) } } diff --git a/tailcall-prettier/src/snapshots/tailcall_prettier__tests__js.snap b/tailcall-prettier/src/snapshots/tailcall_prettier__tests__js.snap deleted file mode 100644 index f0c3f256af..0000000000 --- a/tailcall-prettier/src/snapshots/tailcall_prettier__tests__js.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: tailcall-prettier/src/lib.rs -expression: prettier ---- -const x = {a: 3} From ee90aec24f179da8985a14369f14e9cc1801f569 Mon Sep 17 00:00:00 2001 From: Sandipsinh Rathod Date: Mon, 15 Apr 2024 16:43:44 +0530 Subject: [PATCH 07/14] add graphql-dataloader-batch snapshot --- ...aphql-dataloader-batch-keys.md_merged.snap | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tests/snapshots/execution_spec__graphql-dataloader-batch-keys.md_merged.snap diff --git a/tests/snapshots/execution_spec__graphql-dataloader-batch-keys.md_merged.snap b/tests/snapshots/execution_spec__graphql-dataloader-batch-keys.md_merged.snap new file mode 100644 index 0000000000..5adf7935a7 --- /dev/null +++ b/tests/snapshots/execution_spec__graphql-dataloader-batch-keys.md_merged.snap @@ -0,0 +1,29 @@ +--- +source: tests/execution_spec.rs +expression: merged +--- +schema @server(hostname: "0.0.0.0", port: 8001, queryValidation: false) @upstream(baseURL: "http://upstream/graphql", batch: {delay: 1, headers: [], maxSize: 100}, httpCache: true) { + query: Query +} + +type A { + b: B @graphQL(args: [{key: "id", value: "{{value.bid}}"}], batch: true, name: "b") + bid: Int! + c: C @graphQL(args: [{key: "id", value: "{{value.cid}}"}], batch: true, name: "c") + cid: Int! + id: Int! +} + +type B { + id: Int! + y: String! +} + +type C { + id: Int! + x: String! +} + +type Query { + a: [A] @graphQL(name: "posts") +} From c1b135674a4439445a8d4627f570b1b986339a0a Mon Sep 17 00:00:00 2001 From: Sandipsinh Rathod Date: Mon, 15 Apr 2024 16:46:21 +0530 Subject: [PATCH 08/14] lint fixes --- Cargo.lock | 1 - tailcall-prettier/Cargo.toml | 5 +---- tailcall-prettier/src/lib.rs | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b89fd8b97..5498332f31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5215,7 +5215,6 @@ name = "tailcall-prettier" version = "0.1.0" dependencies = [ "anyhow", - "insta", "strum_macros 0.26.2", ] diff --git a/tailcall-prettier/Cargo.toml b/tailcall-prettier/Cargo.toml index 75ea1ff7f2..a611ff0a63 100644 --- a/tailcall-prettier/Cargo.toml +++ b/tailcall-prettier/Cargo.toml @@ -7,7 +7,4 @@ edition = "2021" [dependencies] anyhow = "1.0.82" -strum_macros = "0.26.2" - -[dev-dependencies] -insta = "1.38.0" \ No newline at end of file +strum_macros = "0.26.2" \ No newline at end of file diff --git a/tailcall-prettier/src/lib.rs b/tailcall-prettier/src/lib.rs index 28ea4169fe..0662788b56 100644 --- a/tailcall-prettier/src/lib.rs +++ b/tailcall-prettier/src/lib.rs @@ -59,7 +59,7 @@ mod tests { #[test] fn test_js() -> anyhow::Result<()> { let prettier = format_with_prettier("const x={a:3};", Parser::Js)?; - assert_eq!("const x = {a: 3}\n",prettier); + assert_eq!("const x = {a: 3}\n", prettier); Ok(()) } } From 978c585850605765f6ced844ed87e2c3cc7c021d Mon Sep 17 00:00:00 2001 From: Sandipsinh Rathod Date: Mon, 15 Apr 2024 16:50:12 +0530 Subject: [PATCH 09/14] update ci --- .github/workflows/ci.yml | 7 +++++ ...aphql-dataloader-batch-keys.md_merged.snap | 29 ------------------- 2 files changed, 7 insertions(+), 29 deletions(-) delete mode 100644 tests/snapshots/execution_spec__graphql-dataloader-batch-keys.md_merged.snap diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4acde149ca..4d5b3a296b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -152,6 +152,13 @@ jobs: - uses: actions/checkout@v4 - uses: taiki-e/install-action@cargo-llvm-cov + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: "20.11.0" + - name: Install Prettier + run: npm install --global prettier + - name: Install Stable Toolchain uses: actions-rust-lang/setup-rust-toolchain@v1 with: diff --git a/tests/snapshots/execution_spec__graphql-dataloader-batch-keys.md_merged.snap b/tests/snapshots/execution_spec__graphql-dataloader-batch-keys.md_merged.snap deleted file mode 100644 index 5adf7935a7..0000000000 --- a/tests/snapshots/execution_spec__graphql-dataloader-batch-keys.md_merged.snap +++ /dev/null @@ -1,29 +0,0 @@ ---- -source: tests/execution_spec.rs -expression: merged ---- -schema @server(hostname: "0.0.0.0", port: 8001, queryValidation: false) @upstream(baseURL: "http://upstream/graphql", batch: {delay: 1, headers: [], maxSize: 100}, httpCache: true) { - query: Query -} - -type A { - b: B @graphQL(args: [{key: "id", value: "{{value.bid}}"}], batch: true, name: "b") - bid: Int! - c: C @graphQL(args: [{key: "id", value: "{{value.cid}}"}], batch: true, name: "c") - cid: Int! - id: Int! -} - -type B { - id: Int! - y: String! -} - -type C { - id: Int! - x: String! -} - -type Query { - a: [A] @graphQL(name: "posts") -} From 3f1c21a6e400ae3506da4b210d22f1b46a784bf1 Mon Sep 17 00:00:00 2001 From: Sandipsinh Rathod Date: Mon, 15 Apr 2024 17:11:50 +0530 Subject: [PATCH 10/14] tmp --- .github/workflows/ci.yml | 7 +++++++ Cargo.toml | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4d5b3a296b..53646abdf0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -159,6 +159,13 @@ jobs: - name: Install Prettier run: npm install --global prettier + - name: Add npm global path to PATH + if: startsWith(runner.os, 'Windows') + run: | + $npm_global = npm config get prefix + echo "Adding npm global path to PATH: $npm_global" + echo "$npm_global" | Out-File -Append -Encoding utf8 $env:GITHUB_PATH + - name: Install Stable Toolchain uses: actions-rust-lang/setup-rust-toolchain@v1 with: diff --git a/Cargo.toml b/Cargo.toml index ff7de49a3e..16108c2d8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -196,7 +196,8 @@ members = [ ".", "tailcall-autogen", "tailcall-aws-lambda", - "tailcall-cloudflare", "tailcall-prettier", + "tailcall-cloudflare", + "tailcall-prettier", "tailcall-query-plan", ] From dd37125bfb7948454ed91b92641d73cedc51dc20 Mon Sep 17 00:00:00 2001 From: Sandipsinh Rathod Date: Mon, 15 Apr 2024 17:27:25 +0530 Subject: [PATCH 11/14] removed unwanted code --- .github/workflows/ci.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 53646abdf0..ceb2570a33 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -157,14 +157,7 @@ jobs: with: node-version: "20.11.0" - name: Install Prettier - run: npm install --global prettier - - - name: Add npm global path to PATH - if: startsWith(runner.os, 'Windows') - run: | - $npm_global = npm config get prefix - echo "Adding npm global path to PATH: $npm_global" - echo "$npm_global" | Out-File -Append -Encoding utf8 $env:GITHUB_PATH + run: npm i -g prettier - name: Install Stable Toolchain uses: actions-rust-lang/setup-rust-toolchain@v1 From 18397f2819d963ba17713aaeafd4c7bef3cb0ddd Mon Sep 17 00:00:00 2001 From: Sandipsinh Rathod Date: Mon, 15 Apr 2024 14:25:27 +0530 Subject: [PATCH 12/14] fix windows test --- tailcall-prettier/src/lib.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tailcall-prettier/src/lib.rs b/tailcall-prettier/src/lib.rs index 0662788b56..acac7c669b 100644 --- a/tailcall-prettier/src/lib.rs +++ b/tailcall-prettier/src/lib.rs @@ -32,8 +32,16 @@ impl Parser { } } +fn get_command() -> Command { + if cfg!(target_os = "windows") { + Command::new("prettier.cmd") + } else { + Command::new("prettier") + } +} + pub fn format_with_prettier>(code: T, file_ty: Parser) -> Result { - let mut child = Command::new("prettier") + let mut child = get_command() .arg("--stdin-filepath") .arg(format!("file.{}", file_ty)) .stdin(Stdio::piped()) From c6a30adb80426f04367bc994b4234bb8007397cc Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Tue, 16 Apr 2024 10:50:28 +0530 Subject: [PATCH 13/14] rename tokens --- tailcall-prettier/src/lib.rs | 10 +++++----- tests/execution_spec.rs | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tailcall-prettier/src/lib.rs b/tailcall-prettier/src/lib.rs index acac7c669b..463f930f70 100644 --- a/tailcall-prettier/src/lib.rs +++ b/tailcall-prettier/src/lib.rs @@ -40,16 +40,16 @@ fn get_command() -> Command { } } -pub fn format_with_prettier>(code: T, file_ty: Parser) -> Result { +pub fn format>(source: T, parser: Parser) -> Result { let mut child = get_command() .arg("--stdin-filepath") - .arg(format!("file.{}", file_ty)) + .arg(format!("file.{}", parser)) .stdin(Stdio::piped()) .stdout(Stdio::piped()) .spawn()?; if let Some(ref mut stdin) = child.stdin { - stdin.write_all(code.as_ref().as_bytes())?; + stdin.write_all(source.as_ref().as_bytes())?; } let output = child.wait_with_output()?; @@ -62,11 +62,11 @@ pub fn format_with_prettier>(code: T, file_ty: Parser) -> Result anyhow::Result<()> { - let prettier = format_with_prettier("const x={a:3};", Parser::Js)?; + let prettier = format("const x={a:3};", Parser::Js)?; assert_eq!("const x = {a: 3}\n", prettier); Ok(()) } diff --git a/tests/execution_spec.rs b/tests/execution_spec.rs index c007cc35c0..ba44ce1e7e 100644 --- a/tests/execution_spec.rs +++ b/tests/execution_spec.rs @@ -891,13 +891,13 @@ async fn assert_spec(spec: ExecutionSpec, opentelemetry: &InMemoryTelemetry) { let path_str = spec.path.display().to_string(); - let identity = tailcall_prettier::format_with_prettier( + let identity = tailcall_prettier::format( identity, tailcall_prettier::Parser::detect(path_str.as_str()).unwrap(), ) .unwrap(); - let content = tailcall_prettier::format_with_prettier( + let content = tailcall_prettier::format( content, tailcall_prettier::Parser::detect(path_str.as_str()).unwrap(), ) From 79aef83119df0e3f63f82bb0cdb5941519409f3c Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Tue, 16 Apr 2024 11:09:29 +0530 Subject: [PATCH 14/14] restructure code --- Cargo.lock | 2 + tailcall-prettier/Cargo.toml | 4 +- tailcall-prettier/src/lib.rs | 75 ++++++------------------------- tailcall-prettier/src/parser.rs | 30 +++++++++++++ tailcall-prettier/src/prettier.rs | 54 ++++++++++++++++++++++ tests/execution_spec.rs | 2 + 6 files changed, 105 insertions(+), 62 deletions(-) create mode 100644 tailcall-prettier/src/parser.rs create mode 100644 tailcall-prettier/src/prettier.rs diff --git a/Cargo.lock b/Cargo.lock index 5498332f31..34ffb82b77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5215,7 +5215,9 @@ name = "tailcall-prettier" version = "0.1.0" dependencies = [ "anyhow", + "lazy_static", "strum_macros 0.26.2", + "tokio", ] [[package]] diff --git a/tailcall-prettier/Cargo.toml b/tailcall-prettier/Cargo.toml index a611ff0a63..8916f0eaac 100644 --- a/tailcall-prettier/Cargo.toml +++ b/tailcall-prettier/Cargo.toml @@ -7,4 +7,6 @@ edition = "2021" [dependencies] anyhow = "1.0.82" -strum_macros = "0.26.2" \ No newline at end of file +lazy_static = "1.4.0" +strum_macros = "0.26.2" +tokio.workspace = true diff --git a/tailcall-prettier/src/lib.rs b/tailcall-prettier/src/lib.rs index 463f930f70..13b706a359 100644 --- a/tailcall-prettier/src/lib.rs +++ b/tailcall-prettier/src/lib.rs @@ -1,72 +1,25 @@ -use std::io::Write; -use std::process::{Command, Stdio}; - -use anyhow::{anyhow, Result}; - -#[derive(strum_macros::Display)] -pub enum Parser { - Gql, - Yml, - Json, - Md, - Ts, - Js, -} - -impl Parser { - pub fn detect(path: &str) -> Result { - let ext = path - .split('.') - .last() - .ok_or(anyhow!("No file extension found"))? - .to_lowercase(); - match ext.as_str() { - "gql" | "graphql" => Ok(Parser::Gql), - "yml" | "yaml" => Ok(Parser::Yml), - "json" => Ok(Parser::Json), - "md" => Ok(Parser::Md), - "ts" => Ok(Parser::Ts), - "js" => Ok(Parser::Js), - _ => Err(anyhow!("Unsupported file type")), - } - } -} - -fn get_command() -> Command { - if cfg!(target_os = "windows") { - Command::new("prettier.cmd") - } else { - Command::new("prettier") - } +use std::sync::Arc; +mod parser; +mod prettier; +use anyhow::Result; +pub use parser::Parser; +use prettier::Prettier; + +lazy_static::lazy_static! { + static ref PRETTIER: Arc = Arc::new(Prettier::new()); } -pub fn format>(source: T, parser: Parser) -> Result { - let mut child = get_command() - .arg("--stdin-filepath") - .arg(format!("file.{}", parser)) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn()?; - - if let Some(ref mut stdin) = child.stdin { - stdin.write_all(source.as_ref().as_bytes())?; - } - - let output = child.wait_with_output()?; - if output.status.success() { - Ok(String::from_utf8(output.stdout)?) - } else { - Err(anyhow!("Prettier formatting failed")) - } +pub async fn format>(source: T, parser: Parser) -> Result { + PRETTIER.format(source.as_ref().to_string(), parser).await } #[cfg(test)] mod tests { use crate::{format, Parser}; - #[test] - fn test_js() -> anyhow::Result<()> { - let prettier = format("const x={a:3};", Parser::Js)?; + #[tokio::test] + async fn test_js() -> anyhow::Result<()> { + let prettier = format("const x={a:3};", Parser::Js).await?; assert_eq!("const x = {a: 3}\n", prettier); Ok(()) } diff --git a/tailcall-prettier/src/parser.rs b/tailcall-prettier/src/parser.rs new file mode 100644 index 0000000000..1a0484983f --- /dev/null +++ b/tailcall-prettier/src/parser.rs @@ -0,0 +1,30 @@ +use anyhow::{anyhow, Result}; + +#[derive(strum_macros::Display)] +pub enum Parser { + Gql, + Yml, + Json, + Md, + Ts, + Js, +} + +impl Parser { + pub fn detect(path: &str) -> Result { + let ext = path + .split('.') + .last() + .ok_or(anyhow!("No file extension found"))? + .to_lowercase(); + match ext.as_str() { + "gql" | "graphql" => Ok(Parser::Gql), + "yml" | "yaml" => Ok(Parser::Yml), + "json" => Ok(Parser::Json), + "md" => Ok(Parser::Md), + "ts" => Ok(Parser::Ts), + "js" => Ok(Parser::Js), + _ => Err(anyhow!("Unsupported file type")), + } + } +} diff --git a/tailcall-prettier/src/prettier.rs b/tailcall-prettier/src/prettier.rs new file mode 100644 index 0000000000..0693ae6b67 --- /dev/null +++ b/tailcall-prettier/src/prettier.rs @@ -0,0 +1,54 @@ +use std::io::Write; +use std::process::{Command, Stdio}; + +use anyhow::{anyhow, Result}; + +pub use super::Parser; + +pub struct Prettier { + runtime: tokio::runtime::Runtime, +} + +impl Prettier { + pub fn new() -> Prettier { + let runtime = tokio::runtime::Builder::new_multi_thread() + .max_blocking_threads(1024) + .build() + .unwrap(); + + Self { runtime } + } + + pub async fn format(&self, source: String, parser: Parser) -> Result { + self.runtime + .spawn_blocking(move || { + let mut command = command(); + let mut child = command + .arg("--stdin-filepath") + .arg(format!("file.{}", parser)) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn()?; + + if let Some(ref mut stdin) = child.stdin { + stdin.write_all(source.as_bytes())?; + } + + let output = child.wait_with_output()?; + if output.status.success() { + Ok(String::from_utf8(output.stdout)?) + } else { + Err(anyhow!("Prettier formatting failed")) + } + }) + .await? + } +} + +fn command() -> Command { + if cfg!(target_os = "windows") { + Command::new("prettier.cmd") + } else { + Command::new("prettier") + } +} diff --git a/tests/execution_spec.rs b/tests/execution_spec.rs index ba44ce1e7e..ef2edccd52 100644 --- a/tests/execution_spec.rs +++ b/tests/execution_spec.rs @@ -895,12 +895,14 @@ async fn assert_spec(spec: ExecutionSpec, opentelemetry: &InMemoryTelemetry) { identity, tailcall_prettier::Parser::detect(path_str.as_str()).unwrap(), ) + .await .unwrap(); let content = tailcall_prettier::format( content, tailcall_prettier::Parser::detect(path_str.as_str()).unwrap(), ) + .await .unwrap(); pretty_assertions::assert_eq!(