Repository: prettier/prettier (JavaScript)
Date: 2020-10-12 01:57:02+00:00
Task type: Bug Fix

Issue:
JSON Lines files cause parse error
**Environments:**

- Prettier Version: 2.1.2
- Running Prettier via: CLI
- Runtime: Installed via Homebrew, uses NodeJS 14.13.1
- Operating System: macOS 10.15.7

**Steps to reproduce:**

Run the following in an empty directory:

```bash
echo "Lorem ipsum" >good.txt
echo '{"type": "t/f", "head": "England", "relation": "invaded", "tail": "United States"}' >bad.jsonl
echo '{"type": "t/f", "head": "England", "relation": "attacked", "tail": "Baltimore"}' >>bad.jsonl
prettier --check .
```

**Expected behavior:**

Both `good.txt` and `bad.jsonl` should be ignored by Prettier because they are not supported formats.

**Actual behavior:**

`good.txt` is ignored as it is supposed to be, but `bad.jsonl` causes the following error:

```console
[error] bad.jsonl: SyntaxError: Unexpected token (2:1)
[error]   1 | {"type": "t/f", "head": "England", "relation": "invaded", "tail": "United States"}
[error] > 2 | {"type": "t/f", "head": "England", "relation": "attacked", "tail": "Baltimore"}
[error]     | ^
[error]   3 | 
```

I see two possible resolutions to this issue:

1. Ignore [JSON Lines](https://jsonlines.org/) files the same way Prettier ignores plaintext, Python, and other files. These files are not valid JSON, so they should not be parsed as JSON.
1. Support JSON Lines files, but I'm not going to ask Prettier to support an additional file format.



Issue discussion:
We need  exclude `.jsonl` from  https://github.com/prettier/prettier/blob/53008ffefb5f2d8a3de286cc123bca3ad6d6c57f/src/language-js/index.js#L55-L60

Solution patch:
diff --git a/changelog_unreleased/api/pr-9371.md b/changelog_unreleased/api/pr-9371.md
new file mode 100644
index 000000000000..22af5459ed4a
--- /dev/null
+++ b/changelog_unreleased/api/pr-9371.md
@@ -0,0 +1,19 @@
+#### Stop inferring the parser to be `json` for `.jsonl` files (#9371 by @fisker)
+
+<!-- prettier-ignore -->
+```console
+// Prettier stable
+$ prettier --check .
+Checking formatting...
+[error] bad.jsonl: SyntaxError: Unexpected token (2:1)
+[error]   1 | '{"type": "t/f", "head": "England", "relation": "invaded", "tail": "United States"}'
+[error] > 2 | '{"type": "t/f", "head": "England", "relation": "attacked", "tail": "Baltimore"}'
+[error]     | ^
+[error]   3 |
+All matched files use Prettier code style!
+
+// Prettier master
+$ prettier --check .
+Checking formatting...
+All matched files use Prettier code style!
+```
diff --git a/cspell.json b/cspell.json
index 72645b9a4b5a..23db5557566e 100644
--- a/cspell.json
+++ b/cspell.json
@@ -2,6 +2,7 @@
     "version": "0.1",
     "words": [
         "ACMR",
+        "Alexa",
         "algolia",
         "Amjad",
         "Andrey",
@@ -75,6 +76,7 @@
         "declarators",
         "dedent",
         "defun",
+        "Deloise",
         "deltice",
         "deopt",
         "dependabot",
@@ -178,8 +180,9 @@
         "josephfrazier",
         "jsesc",
         "jsfmt",
-        "judgements",
+        "jsonl",
         "JSXs",
+        "judgements",
         "kalmanb",
         "Karimov",
         "Kassens",
diff --git a/src/language-js/index.js b/src/language-js/index.js
index cf9a38099b1c..8feed4f5aa35 100644
--- a/src/language-js/index.js
+++ b/src/language-js/index.js
@@ -57,6 +57,7 @@ const languages = [
     parsers: ["json"],
     vscodeLanguageIds: ["json"],
     filenames: [...data.filenames, ".prettierrc"],
+    extensions: data.extensions.filter((extension) => extension !== ".jsonl"),
   })),
   createLanguage(
     require("linguist-languages/data/JSON with Comments.json"),


Test patch:
diff --git a/tests_integration/__tests__/__snapshots__/infer-parser.js.snap b/tests_integration/__tests__/__snapshots__/infer-parser.js.snap
index 10220ca0a86c..52b58ad432b1 100644
--- a/tests_integration/__tests__/__snapshots__/infer-parser.js.snap
+++ b/tests_integration/__tests__/__snapshots__/infer-parser.js.snap
@@ -128,6 +128,11 @@ Array [
 ]
 `;
 
+exports[`Known/Unknown (stdout) 1`] = `
+"known.js
+"
+`;
+
 exports[`stdin no path and no parser --check logs error but exits with 0 (stderr) 1`] = `
 "[error] No parser and no file path given, couldn't infer a parser.
 "
diff --git a/tests_integration/__tests__/__snapshots__/support-info.js.snap b/tests_integration/__tests__/__snapshots__/support-info.js.snap
index c137eb3dc6ef..1560a70c8726 100644
--- a/tests_integration/__tests__/__snapshots__/support-info.js.snap
+++ b/tests_integration/__tests__/__snapshots__/support-info.js.snap
@@ -418,7 +418,6 @@ exports[`CLI --support-info (stdout) 1`] = `
         \\".har\\",
         \\".ice\\",
         \\".JSON-tmLanguage\\",
-        \\".jsonl\\",
         \\".mcmeta\\",
         \\".tfstate\\",
         \\".tfstate.backup\\",
diff --git a/tests_integration/__tests__/infer-parser.js b/tests_integration/__tests__/infer-parser.js
index 3c5c73e38b13..5e27a6b09f84 100644
--- a/tests_integration/__tests__/infer-parser.js
+++ b/tests_integration/__tests__/infer-parser.js
@@ -194,3 +194,16 @@ describe("API with no path and no parser", () => {
     expect(global.console.warn.mock.calls[0]).toMatchSnapshot();
   });
 });
+
+describe("Known/Unknown", () => {
+  runPrettier("cli/infer-parser/known-unknown", [
+    "--end-of-line",
+    "lf",
+    "--list-different",
+    ".",
+  ]).test({
+    status: 1,
+    stderr: "",
+    write: [],
+  });
+});
diff --git a/tests_integration/cli/infer-parser/known-unknown/known.js b/tests_integration/cli/infer-parser/known-unknown/known.js
new file mode 100644
index 000000000000..a77f53edbecb
--- /dev/null
+++ b/tests_integration/cli/infer-parser/known-unknown/known.js
@@ -0,0 +1,2 @@
+hello( 'world'
+)
diff --git a/tests_integration/cli/infer-parser/known-unknown/unknown.jsonl b/tests_integration/cli/infer-parser/known-unknown/unknown.jsonl
new file mode 100644
index 000000000000..9720dd6298e3
--- /dev/null
+++ b/tests_integration/cli/infer-parser/known-unknown/unknown.jsonl
@@ -0,0 +1,4 @@
+{"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]}
+{"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]}
+{"name": "May", "wins": []}
+{"name": "Deloise", "wins": [["three of a kind", "5♣"]]}