summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--prettier/README.md15
-rwxr-xr-xprettier/main.ts73
-rw-r--r--prettier/main_test.ts127
-rw-r--r--prettier/testdata/echox.ts8
4 files changed, 213 insertions, 10 deletions
diff --git a/prettier/README.md b/prettier/README.md
index 3a8d5a0c2..6485d2da2 100644
--- a/prettier/README.md
+++ b/prettier/README.md
@@ -6,22 +6,31 @@ Prettier APIs and tools for deno
To formats the source files, run:
-```console
+```bash
deno --allow-read --allow-write https://deno.land/std/prettier/main.ts
```
You can format only specific files by passing the arguments.
-```console
+```bash
deno --allow-read --allow-write https://deno.land/std/prettier/main.ts path/to/script.ts
```
You can format files on specific directory by passing the directory's path.
-```console
+```bash
deno --allow-read --allow-write https://deno.land/std/prettier/main.ts path/to/script.ts
```
+You can format the input plain text stream. default parse it as typescript code.
+
+```bash
+cat path/to/script.ts | deno https://deno.land/std/prettier/main.ts
+cat path/to/script.js | deno https://deno.land/std/prettier/main.ts --stdin-parser=babel
+cat path/to/config.json | deno https://deno.land/std/prettier/main.ts --stdin-parser=json
+cat path/to/README.md | deno https://deno.land/std/prettier/main.ts --stdin-parser=markdown
+```
+
## Use API
You can use APIs of prettier as the following:
diff --git a/prettier/main.ts b/prettier/main.ts
index 82a213d41..03fe4605c 100755
--- a/prettier/main.ts
+++ b/prettier/main.ts
@@ -23,7 +23,7 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
// This script formats the given source files. If the files are omitted, it
// formats the all files in the repository.
-const { args, exit, readFile, writeFile, stdout } = Deno;
+const { args, exit, readFile, writeFile, stdout, stdin, readAll } = Deno;
import { glob, isGlob, GlobOptions } from "../fs/glob.ts";
import { walk, WalkInfo } from "../fs/walk.ts";
import { parse } from "../flags/mod.ts";
@@ -41,6 +41,15 @@ Options:
it will output to stdout, Defaults to
false.
--ignore <path> Ignore the given path(s).
+ --stdin Specifies to read the code from stdin.
+ If run the command in a pipe, you do not
+ need to specify this flag.
+ Defaults to false.
+ --stdin-parser <typescript|babel|markdown|json>
+ If set --stdin flag, then need specify a
+ parser for stdin. available parser:
+ typescript/babel/markdown/json. Defaults
+ to typescript.
JS/TS Styling Options:
--print-width <int> The line length where Prettier will try
@@ -76,6 +85,14 @@ Example:
deno run prettier/main.ts script1.ts
Print the formatted code to stdout
+
+ cat script1.ts | deno run prettier/main.ts
+ Read the typescript code from stdin and
+ output formatted code to stdout.
+
+ cat config.json | deno run prettier/main.ts --stdin-parser=json
+ Read the JSON string from stdin and
+ output formatted code to stdout.
`;
// Available parsers
@@ -238,6 +255,39 @@ async function formatSourceFiles(
}
/**
+ * Format source code
+ */
+function format(
+ text: string,
+ parser: ParserLabel,
+ prettierOpts: PrettierOptions
+): string {
+ const formatted: string = prettier.format(text, {
+ ...prettierOpts,
+ parser: parser,
+ plugins: prettierPlugins
+ });
+
+ return formatted;
+}
+
+/**
+ * Format code from stdin and output to stdout
+ */
+async function formatFromStdin(
+ parser: ParserLabel,
+ prettierOpts: PrettierOptions
+): Promise<void> {
+ const byte = await readAll(stdin);
+ const formattedCode = format(
+ new TextDecoder().decode(byte),
+ parser,
+ prettierOpts
+ );
+ await stdout.write(new TextEncoder().encode(formattedCode));
+}
+
+/**
* Get the files to format.
* @param selectors The glob patterns to select the files.
* eg `cmd/*.ts` to select all the typescript files in cmd
@@ -329,14 +379,21 @@ async function main(opts): Promise<void> {
options
);
+ const tty = Deno.isTTY();
+
+ const shouldReadFromStdin =
+ (!tty.stdin && (tty.stdout || tty.stderr)) || !!opts["stdin"];
+
try {
- if (check) {
+ if (shouldReadFromStdin) {
+ await formatFromStdin(opts["stdin-parser"], prettierOpts);
+ } else if (check) {
await checkSourceFiles(files, prettierOpts);
} else {
await formatSourceFiles(files, prettierOpts);
}
} catch (e) {
- console.log(e);
+ console.error(e);
exit(1);
}
}
@@ -350,7 +407,8 @@ main(
"trailing-comma",
"arrow-parens",
"prose-wrap",
- "end-of-line"
+ "end-of-line",
+ "stdin-parser"
],
boolean: [
"check",
@@ -359,7 +417,8 @@ main(
"use-tabs",
"single-quote",
"bracket-spacing",
- "write"
+ "write",
+ "stdin"
],
default: {
ignore: [],
@@ -373,7 +432,9 @@ main(
"arrow-parens": "avoid",
"prose-wrap": "preserve",
"end-of-line": "auto",
- write: false
+ write: false,
+ stdin: false,
+ "stdin-parser": "typescript"
},
alias: {
H: "help"
diff --git a/prettier/main_test.ts b/prettier/main_test.ts
index a2bc25702..cb23079d2 100644
--- a/prettier/main_test.ts
+++ b/prettier/main_test.ts
@@ -2,7 +2,7 @@
import { join } from "../fs/path.ts";
import { EOL } from "../fs/path/constants.ts";
import { assertEquals } from "../testing/asserts.ts";
-import { test } from "../testing/mod.ts";
+import { test, runIfMain } from "../testing/mod.ts";
import { xrun } from "./util.ts";
import { copy, emptyDir } from "../fs/mod.ts";
const { readAll, execPath } = Deno;
@@ -233,3 +233,128 @@ test(async function testPrettierPrintToStdout(): Promise<void> {
emptyDir(tempDir);
});
+
+test(async function testPrettierReadFromStdin(): Promise<void> {
+ interface TestCase {
+ stdin: string;
+ stdout: string;
+ stderr: string;
+ code: number;
+ success: boolean;
+ parser?: string;
+ }
+
+ async function readFromStdinAssertion(
+ stdin: string,
+ expectedStdout: string,
+ expectedStderr: string,
+ expectedCode: number,
+ expectedSuccess: boolean,
+ parser?: string
+ ): Promise<void> {
+ const inputCode = stdin;
+ const p1 = Deno.run({
+ args: [execPath, "./prettier/testdata/echox.ts", `${inputCode}`],
+ stdout: "piped"
+ });
+
+ const p2 = Deno.run({
+ args: [
+ execPath,
+ "run",
+ "./prettier/main.ts",
+ "--stdin",
+ ...(parser ? ["--stdin-parser", parser] : [])
+ ],
+ stdin: "piped",
+ stdout: "piped",
+ stderr: "piped"
+ });
+
+ const n = await Deno.copy(p2.stdin!, p1.stdout!);
+ assertEquals(n, new TextEncoder().encode(stdin).length);
+
+ const status1 = await p1.status();
+ assertEquals(status1.code, 0);
+ assertEquals(status1.success, true);
+ p2.stdin!.close();
+ const status2 = await p2.status();
+ assertEquals(status2.code, expectedCode);
+ assertEquals(status2.success, expectedSuccess);
+ const decoder = new TextDecoder("utf-8");
+ assertEquals(
+ decoder.decode(await Deno.readAll(p2.stdout!)),
+ expectedStdout
+ );
+ assertEquals(
+ decoder.decode(await Deno.readAll(p2.stderr!)).split(EOL)[0],
+ expectedStderr
+ );
+ p2.close();
+ p1.close();
+ }
+
+ const testCases: TestCase[] = [
+ {
+ stdin: `console.log("abc" )`,
+ stdout: `console.log("abc");\n`,
+ stderr: ``,
+ code: 0,
+ success: true
+ },
+ {
+ stdin: `console.log("abc" )`,
+ stdout: `console.log("abc");\n`,
+ stderr: ``,
+ code: 0,
+ success: true,
+ parser: "babel"
+ },
+ {
+ stdin: `{\"a\":\"b\"}`,
+ stdout: `{ "a": "b" }\n`,
+ stderr: ``,
+ code: 0,
+ success: true,
+ parser: "json"
+ },
+ {
+ stdin: `## test`,
+ stdout: `## test\n`,
+ stderr: ``,
+ code: 0,
+ success: true,
+ parser: "markdown"
+ },
+ {
+ stdin: `invalid typescript code##!!@@`,
+ stdout: ``,
+ stderr: `SyntaxError: ';' expected. (1:9)`,
+ code: 1,
+ success: false
+ },
+ {
+ stdin: `console.log("foo");`,
+ stdout: ``,
+ stderr:
+ 'Error: Couldn\'t resolve parser "invalid_parser". ' +
+ "Parsers must be explicitly added to the standalone bundle.",
+ code: 1,
+ success: false,
+ parser: "invalid_parser"
+ }
+ ];
+
+ for (const t of testCases) {
+ await readFromStdinAssertion(
+ t.stdin,
+ t.stdout,
+ t.stderr,
+ t.code,
+ t.success,
+ t.parser
+ );
+ }
+});
+
+runIfMain(import.meta);
diff --git a/prettier/testdata/echox.ts b/prettier/testdata/echox.ts
new file mode 100644
index 000000000..68c54b999
--- /dev/null
+++ b/prettier/testdata/echox.ts
@@ -0,0 +1,8 @@
+async function echox(args: string[]) {
+ for (const arg of args) {
+ await Deno.stdout.write(new TextEncoder().encode(arg));
+ }
+ Deno.exit(0);
+}
+
+echox(Deno.args.slice(1));