Skip to content

Commit 0db38ad

Browse files
Add prettier formatting for www (apache#29768)
* Add prettier formatter for www * Ignore markdown as formatted by eslint * Fix CI * Update CONTRIBUTING.rst
1 parent df4abcb commit 0db38ad

File tree

169 files changed

+6634
-4964
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

169 files changed

+6634
-4964
lines changed

.codespellignorelines

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
roles = relationship("Role", secondary=assoc_user_role, backref="user", lazy="selectin")
44
The platform supports **C**reate, **R**ead, **U**pdate, and **D**elete operations on most resources.
55
<pre><code>Code block\ndoes not\nrespect\nnewlines\n</code></pre>
6+
"trough",

.pre-commit-config.yaml

+4-4
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ repos:
641641
language: node
642642
files: ^airflow/www/.*\.(css|sass|scss)$
643643
# Keep dependency versions in sync w/ airflow/www/package.json
644-
additional_dependencies: ['[email protected]', '[email protected]']
644+
additional_dependencies: ['[email protected]', '[email protected]', '[email protected]']
645645
- id: compile-www-assets
646646
name: Compile www assets
647647
language: node
@@ -877,10 +877,10 @@ repos:
877877
additional_dependencies: ['rich>=12.4.4']
878878
pass_filenames: false
879879
files: ^tests/.*\.py$
880-
- id: ts-compile-and-lint-javascript
881-
name: TS types generation and ESLint against current UI files
880+
- id: ts-compile-format-lint-www
881+
name: TS types generation and ESLint/Prettier against current UI files
882882
language: node
883-
'types_or': [javascript, ts, tsx, yaml]
883+
'types_or': [javascript, ts, tsx, yaml, css, json]
884884
files: ^airflow/www/static/js/|^airflow/api_connexion/openapi/v1\.yaml$
885885
entry: ./scripts/ci/pre_commit/pre_commit_www_lint.py
886886
additional_dependencies: ['[email protected]']

.rat-excludes

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
.coveragerc
1414
.codecov.yml
1515
.codespellignorelines
16-
.eslintrc
1716
.eslintignore
17+
.eslintrc
18+
.prettierignore
19+
.prettierrc
1820
.rat-excludes
1921
.stylelintignore
2022
.stylelintrc

CONTRIBUTING.rst

+12-9
Original file line numberDiff line numberDiff line change
@@ -1179,29 +1179,32 @@ commands:
11791179
yarn run dev
11801180
11811181
1182-
Follow JavaScript Style Guide
1183-
-----------------------------
1182+
Follow Style Guide
1183+
------------------
11841184

1185-
We try to enforce a more consistent style and follow the JS community
1185+
We try to enforce a more consistent style and follow the Javascript/Typescript community
11861186
guidelines.
11871187

1188-
Once you add or modify any JavaScript code in the project, please make sure it
1188+
Once you add or modify any JS/TS code in the project, please make sure it
11891189
follows the guidelines defined in `Airbnb
11901190
JavaScript Style Guide <https://github.com/airbnb/javascript>`__.
11911191

11921192
Apache Airflow uses `ESLint <https://eslint.org/>`__ as a tool for identifying and
1193-
reporting on patterns in JavaScript. To use it, run any of the following
1194-
commands:
1193+
reporting issues in JS/TS, and `Prettier <https://prettier.io/>`__ for code formatting.
1194+
Most IDE directly integrate with these tools, you can also manually run them with any of the following commands:
11951195

11961196
.. code-block:: bash
11971197
1198-
# Check JS code in .js, .jsx, and .html files, and report any errors/warnings
1198+
# Format code in .js, .jsx, .ts, .tsx, .json, .css, .html files
1199+
yarn format
1200+
1201+
# Check JS/TS code in .js, .jsx, .ts, .tsx, .html files and report any errors/warnings
11991202
yarn run lint
12001203
1201-
# Check JS code in .js, .jsx, and .html files, report any errors/warnings and fix them if possible
1204+
# Check JS/TS code in .js, .jsx, .ts, .tsx, .html files and report any errors/warnings and fix them if possible
12021205
yarn run lint:fix
12031206
1204-
# Runs tests for all .test.js and .test.jsx files
1207+
# Run tests for all .test.js, .test.jsx, .test.ts, test.tsx files
12051208
yarn test
12061209
12071210
React, JSX and Chakra

STATIC_CODE_CHECKS.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ require Breeze Docker image to be build locally.
305305
+-----------------------------------------------------------+------------------------------------------------------------------+---------+
306306
| trailing-whitespace | Remove trailing whitespace at end of line | |
307307
+-----------------------------------------------------------+------------------------------------------------------------------+---------+
308-
| ts-compile-and-lint-javascript | TS types generation and ESLint against current UI files | |
308+
| ts-compile-format-lint-www | TS types generation and ESLint/Prettier against current UI files | |
309309
+-----------------------------------------------------------+------------------------------------------------------------------+---------+
310310
| update-black-version | Update black versions everywhere | |
311311
+-----------------------------------------------------------+------------------------------------------------------------------+---------+

airflow/www/.eslintrc

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
{
2-
"extends": ["airbnb", "airbnb/hooks"],
2+
"extends": ["airbnb", "airbnb/hooks", "prettier"],
33
"parser": "@babel/eslint-parser",
44
"parserOptions": {
55
"babelOptions": {
6-
"presets": ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"],
6+
"presets": [
7+
"@babel/preset-env",
8+
"@babel/preset-react",
9+
"@babel/preset-typescript"
10+
],
711
"plugins": ["@babel/plugin-transform-runtime"]
812
}
913
},
10-
"plugins": [ "html", "react" ],
14+
"plugins": ["html", "react"],
1115
"rules": {
1216
"no-param-reassign": 1,
1317
"react/prop-types": 0,
@@ -21,7 +25,7 @@
2125
"ts": "never",
2226
"tsx": "never"
2327
}
24-
],
28+
],
2529
"import/no-extraneous-dependencies": [
2630
"error",
2731
{
@@ -48,11 +52,9 @@
4852
"overrides": [
4953
{
5054
"files": ["*.ts", "*.tsx"],
51-
"extends": [
52-
"airbnb-typescript"
53-
],
55+
"extends": ["airbnb-typescript", "prettier"],
5456
"parser": "@typescript-eslint/parser",
55-
"plugins": [ "@typescript-eslint" ],
57+
"plugins": ["@typescript-eslint"],
5658
"parserOptions": {
5759
"project": "./tsconfig.json"
5860
},

airflow/www/.prettierignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.mypy_cache/
2+
templates/**/*.html
3+
dist/
4+
*.md
5+
*.yaml

airflow/www/.prettierrc

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"overrides": [
3+
{
4+
"files": "*.json",
5+
"options": {
6+
"tabWidth": 2
7+
}
8+
}
9+
]
10+
}

airflow/www/.stylelintrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"extends": "stylelint-config-standard"
2+
"extends": ["stylelint-config-standard", "stylelint-config-prettier"]
33
}

airflow/www/alias-rest-types.js

+76-44
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
* under the License.
1818
*/
1919

20-
const ts = require('typescript');
21-
const fs = require('fs');
20+
const ts = require("typescript");
21+
const fs = require("fs");
2222

2323
/* This library does three things to make openapi-typescript generation easier to use.
2424
* 1. Creates capitalized exports for Paths and Operations
@@ -29,16 +29,16 @@ const fs = require('fs');
2929
*/
3030

3131
/* Finds all words, capitalizes them, and removes all other characters. */
32-
const toPascalCase = (str) => (
32+
const toPascalCase = (str) =>
3333
(str.match(/[a-zA-Z0-9]+/g) || [])
3434
.map((w) => `${w.charAt(0).toUpperCase()}${w.slice(1)}`)
35-
.join('')
36-
);
35+
.join("");
3736

3837
/* Adds a prefix to a type prop as necessary.
3938
* ('', 'components') => 'components'
4039
*/
41-
const prefixPath = (rootPrefix, prop) => (rootPrefix ? `${rootPrefix}['${prop}']` : prop);
40+
const prefixPath = (rootPrefix, prop) =>
41+
rootPrefix ? `${rootPrefix}['${prop}']` : prop;
4242

4343
// Recursively find child nodes by name.
4444
const findNode = (node, ...names) => {
@@ -58,87 +58,114 @@ const findNode = (node, ...names) => {
5858
// Generate Variable Type Aliases for a given path or operation
5959
const generateVariableAliases = (node, operationPath, operationName) => {
6060
const variableTypes = [];
61-
const hasPath = !!findNode(node, 'parameters', 'path');
62-
const hasQuery = !!findNode(node, 'parameters', 'query');
63-
const hasBody = !!findNode(node, 'requestBody', 'content', 'application/json');
61+
const hasPath = !!findNode(node, "parameters", "path");
62+
const hasQuery = !!findNode(node, "parameters", "query");
63+
const hasBody = !!findNode(
64+
node,
65+
"requestBody",
66+
"content",
67+
"application/json"
68+
);
6469

6570
if (hasPath) variableTypes.push(`${operationPath}['parameters']['path']`);
6671
if (hasQuery) variableTypes.push(`${operationPath}['parameters']['query']`);
67-
if (hasBody) variableTypes.push(`${operationPath}['requestBody']['content']['application/json']`);
72+
if (hasBody)
73+
variableTypes.push(
74+
`${operationPath}['requestBody']['content']['application/json']`
75+
);
6876

69-
if (variableTypes.length === 0) return '';
77+
if (variableTypes.length === 0) return "";
7078
const typeName = `${toPascalCase(operationName)}Variables`;
71-
return [typeName, `export type ${typeName} = CamelCasedPropertiesDeep<${variableTypes.join(' & ')}>;`];
79+
return [
80+
typeName,
81+
`export type ${typeName} = CamelCasedPropertiesDeep<${variableTypes.join(
82+
" & "
83+
)}>;`,
84+
];
7285
};
7386

7487
// Generate Type Aliases
75-
const generateAliases = (rootNode, writeText, prefix = '') => {
88+
const generateAliases = (rootNode, writeText, prefix = "") => {
7689
// Loop through the root AST nodes of the file
7790
ts.forEachChild(rootNode, (node) => {
7891
// Response Data Types
79-
if (ts.isInterfaceDeclaration(node) && node.name?.text === 'components') {
80-
const schemaMemberNames = findNode(node, 'schemas').type.members.map((n) => n.name?.text);
92+
if (ts.isInterfaceDeclaration(node) && node.name?.text === "components") {
93+
const schemaMemberNames = findNode(node, "schemas").type.members.map(
94+
(n) => n.name?.text
95+
);
8196

8297
const types = schemaMemberNames.map((n) => [
8398
`${n}`,
84-
`export type ${n} = CamelCasedPropertiesDeep<${prefixPath(prefix, 'components')}['schemas']['${n}']>;`,
99+
`export type ${n} = CamelCasedPropertiesDeep<${prefixPath(
100+
prefix,
101+
"components"
102+
)}['schemas']['${n}']>;`,
85103
]);
86104
if (types.length) {
87-
writeText.push(['comment', `Types for returned data ${prefix}`]);
105+
writeText.push(["comment", `Types for returned data ${prefix}`]);
88106
writeText.push(...types);
89107
}
90108
}
91109

92110
// Paths referencing an operation are skipped
93-
if (node.name?.text === 'paths') {
111+
if (node.name?.text === "paths") {
94112
if (!prefix) {
95-
writeText.push(['comment', 'Alias paths to PascalCase.']);
96-
writeText.push(['Paths', 'export type Paths = paths;']);
113+
writeText.push(["comment", "Alias paths to PascalCase."]);
114+
writeText.push(["Paths", "export type Paths = paths;"]);
97115
}
98116

99117
const types = [];
100118

101119
(node.members || node.type.members).forEach((path) => {
102120
const methodNames = path.type.members.map((m) => m.name.text);
103-
const methodTypes = methodNames.map((m) => (
121+
const methodTypes = methodNames.map((m) =>
104122
generateVariableAliases(
105123
findNode(path, m),
106-
`${prefixPath(prefix, 'paths')}['${path.name?.text}']['${m}']`,
107-
`${path.name.text}${toPascalCase(m)}`,
108-
)));
124+
`${prefixPath(prefix, "paths")}['${path.name?.text}']['${m}']`,
125+
`${path.name.text}${toPascalCase(m)}`
126+
)
127+
);
109128
types.push(...methodTypes.filter((m) => !!m));
110129
});
111130

112131
if (types.length) {
113-
writeText.push(['comment', `Types for path operation variables ${prefix}`]);
132+
writeText.push([
133+
"comment",
134+
`Types for path operation variables ${prefix}`,
135+
]);
114136
writeText.push(...types);
115137
}
116138
}
117139

118140
// operationIds are defined
119-
if (node.name?.text === 'operations') {
141+
if (node.name?.text === "operations") {
120142
if (!prefix) {
121-
writeText.push(['comment', 'Alias operations to PascalCase.']);
122-
writeText.push(['Operations', 'export type Operations = operations;']);
143+
writeText.push(["comment", "Alias operations to PascalCase."]);
144+
writeText.push(["Operations", "export type Operations = operations;"]);
123145
}
124146

125-
const types = (node.members || node.type.members).map((operation) => (
147+
const types = (node.members || node.type.members).map((operation) =>
126148
generateVariableAliases(
127149
operation,
128-
`${prefixPath(prefix, 'operations')}['${operation.name.text}']`,
129-
operation.name.text,
130-
)));
150+
`${prefixPath(prefix, "operations")}['${operation.name.text}']`,
151+
operation.name.text
152+
)
153+
);
131154
if (types.length) {
132-
writeText.push(['comment', `Types for operation variables ${prefix}`]);
155+
writeText.push(["comment", `Types for operation variables ${prefix}`]);
133156
writeText.push(...types);
134-
writeText.push('\n');
157+
writeText.push("\n");
135158
}
136159
}
137160

138161
// recursively call this for any externals
139-
if (ts.isInterfaceDeclaration(node) && node.name?.text === 'external') {
162+
if (ts.isInterfaceDeclaration(node) && node.name?.text === "external") {
140163
node.members.forEach((external) => {
141-
generateAliases(external.type, writeText, `external['${external.name.text}']`);
164+
generateAliases(
165+
external.type,
166+
writeText,
167+
`external['${external.name.text}']`
168+
);
142169
});
143170
}
144171
});
@@ -169,27 +196,32 @@ function generate(file) {
169196
const program = ts.createProgram([file], { allowJs: true });
170197
const sourceFile = program.getSourceFile(file);
171198
const writeText = [];
172-
writeText.push(['block', license]);
173-
writeText.push(['comment', 'eslint-disable']);
199+
writeText.push(["block", license]);
200+
writeText.push(["comment", "eslint-disable"]);
174201
// eslint-disable-next-line quotes
175-
writeText.push(['block', `import type { CamelCasedPropertiesDeep } from 'type-fest';`]);
176-
writeText.push(['block', sourceFile.text]);
202+
writeText.push([
203+
"block",
204+
`import type { CamelCasedPropertiesDeep } from 'type-fest';`,
205+
]);
206+
writeText.push(["block", sourceFile.text]);
177207
generateAliases(sourceFile, writeText);
178208

179209
const finalText = writeText
180210
// Deduplicate types
181211
.map((pair) => {
182212
// keep all comments and code blocks
183-
if (pair[0] === 'comment' || pair[0] === 'block') return pair;
213+
if (pair[0] === "comment" || pair[0] === "block") return pair;
184214
// return the first instance of this key only
185215
const firstInstance = writeText.find((p) => p[0] === pair[0]);
186-
return firstInstance === pair ? pair : ['comment', `Duplicate removed: ${pair[1]}`];
216+
return firstInstance === pair
217+
? pair
218+
: ["comment", `Duplicate removed: ${pair[1]}`];
187219
})
188220
// Remove undefined created above
189221
.filter((p) => !!p)
190222
// Escape comments and flatten.
191-
.map((pair) => (pair[0] === 'comment' ? `\n/* ${pair[1]} */` : pair[1]))
192-
.join('\n');
223+
.map((pair) => (pair[0] === "comment" ? `\n/* ${pair[1]} */` : pair[1]))
224+
.join("\n");
193225

194226
fs.writeFileSync(file, finalText, (err) => {
195227
if (err) {

airflow/www/babel.config.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,13 @@
2020
module.exports = function (api) {
2121
api.cache(true);
2222

23-
const presets = ['@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript'];
23+
const presets = [
24+
"@babel/preset-env",
25+
"@babel/preset-react",
26+
"@babel/preset-typescript",
27+
];
2428

25-
const plugins = ['@babel/plugin-transform-runtime'];
29+
const plugins = ["@babel/plugin-transform-runtime"];
2630

2731
return {
2832
presets,

0 commit comments

Comments
 (0)