Remove prettier-plugin-astro
to fix Prettier CI (#614)
* Disable embedded languages formatting so that Astro code blocks don't make prettier hang * chore: remove prettier-plugin-astro * chore: enable embedded languages * chore: update yarn lock Co-authored-by: Nate Moore <nate@skypack.dev>
This commit is contained in:
parent
20b4a600f5
commit
53fcae1a9a
15 changed files with 0 additions and 404 deletions
|
@ -1,35 +0,0 @@
|
|||
# prettier-plugin-astro
|
||||
|
||||
## 0.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [47ac2cc]
|
||||
- @astrojs/parser@0.15.0
|
||||
|
||||
## 0.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ff7ec2f: Add @types/prettier for type support
|
||||
|
||||
## 0.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ab2972b]
|
||||
- @astrojs/parser@0.13.3
|
||||
|
||||
## 0.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [9cdada0]
|
||||
- astro-parser@0.11.0
|
||||
|
||||
## 0.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b3886c2]
|
||||
- astro-parser@0.1.0
|
|
@ -1,157 +0,0 @@
|
|||
const {
|
||||
doc: {
|
||||
builders: { concat, hardline },
|
||||
},
|
||||
} = require('prettier');
|
||||
const { parse } = require('@astrojs/parser');
|
||||
|
||||
/** @type {Partial<import('prettier').SupportLanguage>[]} */
|
||||
module.exports.languages = [
|
||||
{
|
||||
name: 'astro',
|
||||
parsers: ['astro'],
|
||||
extensions: ['.astro'],
|
||||
vscodeLanguageIds: ['astro'],
|
||||
},
|
||||
];
|
||||
|
||||
/** @type {Record<string, import('prettier').Parser>} */
|
||||
module.exports.parsers = {
|
||||
astro: {
|
||||
parse: (text) => {
|
||||
let { html, css, module: frontmatter } = parse(text);
|
||||
html = html ? { ...html, text: text.slice(html.start, html.end), isRoot: true } : null;
|
||||
return [frontmatter, html, css].filter((v) => v);
|
||||
},
|
||||
locStart(node) {
|
||||
return node.start;
|
||||
},
|
||||
locEnd(node) {
|
||||
return node.end;
|
||||
},
|
||||
astFormat: 'astro-ast',
|
||||
},
|
||||
'astro-expression': {
|
||||
parse: (text, parsers) => {
|
||||
return { text };
|
||||
},
|
||||
locStart(node) {
|
||||
return node.start;
|
||||
},
|
||||
locEnd(node) {
|
||||
return node.end;
|
||||
},
|
||||
astFormat: 'astro-expression',
|
||||
},
|
||||
};
|
||||
|
||||
const findExpressionsInAST = (node, collect = []) => {
|
||||
if (node.type === 'MustacheTag') {
|
||||
return collect.concat(node);
|
||||
}
|
||||
if (node.children) {
|
||||
collect.push(...[].concat(...node.children.map((child) => findExpressionsInAST(child))));
|
||||
}
|
||||
return collect;
|
||||
};
|
||||
|
||||
const formatExpression = ({ expression: { codeChunks, children } }, text, options) => {
|
||||
if (children.length === 0) {
|
||||
const codeStart = codeChunks[0]; // If no children, there should only exist a single chunk.
|
||||
if (codeStart && [`'`, `"`].includes(codeStart[0])) {
|
||||
return `<script $ lang="ts">${codeChunks.join('')}</script>`;
|
||||
}
|
||||
return `{${codeChunks.join('')}}`;
|
||||
}
|
||||
|
||||
return `<script $ lang="ts">${text}</script>`;
|
||||
};
|
||||
|
||||
const isAstroScript = (node) => node.type === 'concat' && node.parts[0] === '<script' && node.parts[1].type === 'indent' && node.parts[1].contents.parts.find((v) => v === '$');
|
||||
|
||||
const walkDoc = (doc) => {
|
||||
let inAstroScript = false;
|
||||
const recurse = (node, { parent }) => {
|
||||
if (node.type === 'concat') {
|
||||
if (isAstroScript(node)) {
|
||||
inAstroScript = true;
|
||||
parent.contents = { type: 'concat', parts: ['{'] };
|
||||
}
|
||||
return node.parts.map((part) => recurse(part, { parent: node }));
|
||||
}
|
||||
if (inAstroScript) {
|
||||
if (node.type === 'break-parent') {
|
||||
parent.parts = parent.parts.filter((part) => !['break-parent', 'line'].includes(part.type));
|
||||
}
|
||||
if (node.type === 'indent') {
|
||||
parent.parts = parent.parts.map((part) => {
|
||||
if (part.type !== 'indent') return part;
|
||||
return {
|
||||
type: 'concat',
|
||||
parts: [part.contents],
|
||||
};
|
||||
});
|
||||
}
|
||||
if (typeof node === 'string' && node.endsWith(';')) {
|
||||
parent.parts = parent.parts.map((part) => {
|
||||
if (typeof part === 'string' && part.endsWith(';')) return part.slice(0, -1);
|
||||
return part;
|
||||
});
|
||||
}
|
||||
if (node === '</script>') {
|
||||
parent.parts = parent.parts.map((part) => (part === '</script>' ? '}' : part));
|
||||
inAstroScript = false;
|
||||
}
|
||||
}
|
||||
if (['group', 'indent'].includes(node.type)) {
|
||||
return recurse(node.contents, { parent: node });
|
||||
}
|
||||
};
|
||||
recurse(doc, { parent: null });
|
||||
};
|
||||
|
||||
/** @type {Record<string, import('prettier').Printer>} */
|
||||
module.exports.printers = {
|
||||
'astro-ast': {
|
||||
print(path, opts, print) {
|
||||
const node = path.getValue();
|
||||
|
||||
if (Array.isArray(node)) return concat(path.map(print));
|
||||
if (node.type === 'Fragment') return concat(path.map(print, 'children'));
|
||||
|
||||
return node;
|
||||
},
|
||||
embed(path, print, textToDoc, options) {
|
||||
const node = path.getValue();
|
||||
if (node.type === 'Script' && node.context === 'setup') {
|
||||
return concat(['---', hardline, textToDoc(node.content, { ...options, parser: 'typescript' }), '---', hardline, hardline]);
|
||||
}
|
||||
if (node.type === 'Fragment' && node.isRoot) {
|
||||
const expressions = findExpressionsInAST(node);
|
||||
if (expressions.length > 0) {
|
||||
const parts = [].concat(
|
||||
...expressions.map((expr, i, all) => {
|
||||
const prev = all[i - 1];
|
||||
const start = node.text.slice((prev?.end ?? node.start) - node.start, expr.start - node.start);
|
||||
const exprText = formatExpression(expr, node.text.slice(expr.start - node.start + 1, expr.end - node.start - 1), options);
|
||||
|
||||
if (i === all.length - 1) {
|
||||
const end = node.text.slice(expr.end - node.start);
|
||||
return [start, exprText, end];
|
||||
}
|
||||
|
||||
return [start, exprText];
|
||||
})
|
||||
);
|
||||
const html = parts.join('\n');
|
||||
const doc = textToDoc(html, { parser: 'html' });
|
||||
walkDoc(doc);
|
||||
return doc;
|
||||
}
|
||||
return textToDoc(node.text, { parser: 'html' });
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
},
|
||||
};
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"name": "prettier-plugin-astro",
|
||||
"version": "0.0.6",
|
||||
"main": "index.js",
|
||||
"type": "commonjs",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"test": "uvu test -i fixtures -i package.json",
|
||||
"build": "echo 'build'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/parser": "^0.15.0",
|
||||
"prettier": "^2.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/prettier": "^2.2.1"
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
import { suite } from 'uvu';
|
||||
import * as assert from 'uvu/assert';
|
||||
import { format } from './test-utils.js';
|
||||
import { promises as fs } from 'fs';
|
||||
import { fileURLToPath } from 'url';
|
||||
const Prettier = suite('Prettier formatting');
|
||||
|
||||
const readFile = (path) => fs.readFile(fileURLToPath(new URL(`./fixtures${path}`, import.meta.url))).then((res) => res.toString().replace(/\r\n/g, '\n'));
|
||||
|
||||
/**
|
||||
* Utility to get `[src, out]` files
|
||||
* @param name {string}
|
||||
* @param ctx {any}
|
||||
*/
|
||||
const getFiles = async (name) => {
|
||||
const [src, out] = await Promise.all([readFile(`/in/${name}.astro`), readFile(`/out/${name}.astro`)]);
|
||||
return [src, out];
|
||||
};
|
||||
|
||||
Prettier('can format a basic Astro file', async () => {
|
||||
const [src, out] = await getFiles('basic');
|
||||
assert.not.fixture(src, out);
|
||||
|
||||
const formatted = format(src);
|
||||
assert.fixture(formatted, out);
|
||||
});
|
||||
|
||||
Prettier('can format an Astro file with frontmatter', async () => {
|
||||
const [src, out] = await getFiles('frontmatter');
|
||||
assert.not.fixture(src, out);
|
||||
|
||||
const formatted = format(src);
|
||||
assert.fixture(formatted, out);
|
||||
});
|
||||
|
||||
Prettier.skip('can format an Astro file with embedded JSX expressions', async () => {
|
||||
const [src, out] = await getFiles('embedded-expr');
|
||||
assert.not.fixture(src, out);
|
||||
|
||||
const formatted = format(src);
|
||||
assert.fixture(formatted, out);
|
||||
});
|
||||
|
||||
// This is currently failing! See: https://github.com/snowpackjs/astro/issues/478
|
||||
Prettier.skip('can format an Astro file with a JSX expression in an attribute', async () => {
|
||||
const [src, out] = await getFiles('attribute-with-embedded-expr');
|
||||
assert.not.fixture(src, out);
|
||||
|
||||
const formatted = format(src);
|
||||
assert.fixture(formatted, out);
|
||||
});
|
||||
|
||||
Prettier.run();
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
export let post
|
||||
export let author
|
||||
---
|
||||
|
||||
<a class="author" href={`/author/${post.author}`}>{author.name}</a>
|
|
@ -1,13 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
Hello world!</h1>
|
||||
</body>
|
||||
</html>
|
|
@ -1,26 +0,0 @@
|
|||
---
|
||||
import Color from '../components/Color.jsx';
|
||||
|
||||
let title =
|
||||
'My Site';
|
||||
|
||||
const colors = ['red', 'yellow', 'blue',];
|
||||
---
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>My site</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{title}</h1>
|
||||
|
||||
{"I'm some super long text and oh boy I sure do hope this formatter doesn't break me!"}
|
||||
|
||||
{colors.map(color => (
|
||||
<div><Color name={color} /></div>))}
|
||||
</body>
|
||||
</html>
|
|
@ -1,18 +0,0 @@
|
|||
---
|
||||
import Color from '../components/Color.jsx';
|
||||
|
||||
let title =
|
||||
'My Site';
|
||||
|
||||
const colors = ['red', 'yellow', 'blue',];
|
||||
---
|
||||
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>My site</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{title}</h1>
|
||||
</body>
|
||||
</html>
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
export let post;
|
||||
export let author;
|
||||
---
|
||||
|
||||
<a class="author" href={`/author/${post.author}`}>{author.name}</a>
|
|
@ -1,12 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello world!</h1>
|
||||
</body>
|
||||
</html>
|
|
@ -1,24 +0,0 @@
|
|||
---
|
||||
import Color from "../components/Color.jsx";
|
||||
|
||||
let title = "My Site";
|
||||
|
||||
const colors = ["red", "yellow", "blue"];
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>My site</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{title}</h1>
|
||||
|
||||
{"I'm some super long text and oh boy I sure do hope this formatter doesn't break me!"}
|
||||
|
||||
{colors.map((color) => (
|
||||
<div>
|
||||
<Color name={color} />
|
||||
</div>
|
||||
))}
|
||||
</body>
|
||||
</html>
|
|
@ -1,16 +0,0 @@
|
|||
---
|
||||
import Color from "../components/Color.jsx";
|
||||
|
||||
let title = "My Site";
|
||||
|
||||
const colors = ["red", "yellow", "blue"];
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>My site</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{title}</h1>
|
||||
</body>
|
||||
</html>
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"type": "module"
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
import prettier from 'prettier';
|
||||
import { fileURLToPath } from 'url';
|
||||
/**
|
||||
* format the contents of an astro file
|
||||
* @param contents {string}
|
||||
*/
|
||||
export function format(contents) {
|
||||
return prettier.format(contents, {
|
||||
parser: 'astro',
|
||||
plugins: [fileURLToPath(new URL('../', import.meta.url))],
|
||||
});
|
||||
}
|
|
@ -1507,11 +1507,6 @@
|
|||
resolved "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz"
|
||||
integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==
|
||||
|
||||
"@types/prettier@^2.2.1":
|
||||
version "2.3.0"
|
||||
resolved "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.0.tgz"
|
||||
integrity sha512-hkc1DATxFLQo4VxPDpMH1gCkPpBbpOoJ/4nhuXw4n63/0R6bCpQECj4+K226UJ4JO/eJQz+1mC2I7JsWanAdQw==
|
||||
|
||||
"@types/prompts@^2.0.12":
|
||||
version "2.0.12"
|
||||
resolved "https://registry.npmjs.org/@types/prompts/-/prompts-2.0.12.tgz"
|
||||
|
|
Loading…
Reference in a new issue