diff --git a/.eslint-resolver.js b/.eslint-resolver.js index e2b0f32d354f..32ca14b25ecc 100644 --- a/.eslint-resolver.js +++ b/.eslint-resolver.js @@ -1,23 +1,24 @@ const path = require('path'); -const resolve = require('resolve') +const resolve = require('resolve'); // eslint-disable-line node/no-extraneous-require // Implements the following resolver spec: // https://github.com/benmosher/eslint-plugin-import/blob/master/resolvers/README.md -exports.interfaceVersion = 2 +exports.interfaceVersion = 2; exports.resolve = function (source, file, config) { - if (resolve.isCore(source)) return { found: true, path: null } + if (resolve.isCore(source)) return { found: true, path: null }; source = source.replace(/\.js$/, '.ts'); try { return { - found: true, path: resolve.sync(source, { + found: true, + path: resolve.sync(source, { extensions: [], basedir: path.dirname(path.resolve(file)), ...config, - }) - } + }), + }; } catch (err) { - return { found: false } + return { found: false }; } -} +}; diff --git a/.eslintrc.json b/.eslintrc.json index f91c740ad7c0..ed085cefbecd 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,150 +1,161 @@ { "root": true, - "parser": "@typescript-eslint/parser", - "parserOptions": { "project": "./tsconfig.json" }, - "extends": [ - "./node_modules/gts", - "plugin:import/errors", - "plugin:import/warnings", - "plugin:import/typescript", - "plugin:n/recommended" - ], "env": { "browser": true, "node": true }, - "plugins": ["node", "ban", "import", "deprecation", "gpuweb-cts", "n"], - "rules": { - // Core rules - "linebreak-style": ["warn", "unix"], - "no-console": "warn", - "no-throw-literal": "warn", - "no-undef": "off", - "no-useless-rename": "warn", - "object-shorthand": "warn", - "prefer-promise-reject-errors": "warn", - "quotes": ["warn", "single", { "avoidEscape": true, "allowTemplateLiterals": true }], + "extends": ["./node_modules/gts"], + "overrides": [ + { + "files": ["**/*.ts"], + "parser": "@typescript-eslint/parser", + "parserOptions": { "project": "./tsconfig.json" }, + "extends": [ + "plugin:import/errors", + "plugin:import/warnings", + "plugin:import/typescript", + "plugin:n/recommended" + ], + "plugins": ["node", "ban", "import", "deprecation", "gpuweb-cts", "n"], + "rules": { + // Core rules + "linebreak-style": ["warn", "unix"], + "no-console": "warn", + "no-throw-literal": "warn", + "no-undef": "off", + "no-useless-rename": "warn", + "object-shorthand": "warn", + "prefer-promise-reject-errors": "warn", + "quotes": ["warn", "single", { "avoidEscape": true, "allowTemplateLiterals": true }], - // All test TODOs must be tracked inside file/test descriptions or READMEs. - // Comments relating to TODOs in descriptions can be marked with references like "[1]". - // TODOs not relating to test coverage can be marked MAINTENANCE_TODO or similar. - "no-warning-comments": ["warn", { "terms": ["todo", "fixme", "xxx"], "location": "anywhere" }], + // All test TODOs must be tracked inside file/test descriptions or READMEs. + // Comments relating to TODOs in descriptions can be marked with references like "[1]". + // TODOs not relating to test coverage can be marked MAINTENANCE_TODO or similar. + "no-warning-comments": [ + "warn", + { "terms": ["todo", "fixme", "xxx"], "location": "anywhere" } + ], - // Plugin: gpuweb-cts - "gpuweb-cts/string-trailing-space": "warn", - "gpuweb-cts/string-tabs": "warn", + // Plugin: gpuweb-cts + "gpuweb-cts/string-trailing-space": "warn", + "gpuweb-cts/string-tabs": "warn", - // Plugin: @typescript-eslint - "@typescript-eslint/no-inferrable-types": "off", - "@typescript-eslint/consistent-type-assertions": "warn", - // Recommended lints - // https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/README.md - "@typescript-eslint/adjacent-overload-signatures": "warn", - "@typescript-eslint/await-thenable": "warn", - "@typescript-eslint/ban-ts-comment": "warn", - "@typescript-eslint/no-empty-interface": "warn", - "@typescript-eslint/no-explicit-any": "warn", - "@typescript-eslint/no-extra-non-null-assertion": "warn", - "@typescript-eslint/no-floating-promises": "warn", - "@typescript-eslint/no-for-in-array": "warn", - "@typescript-eslint/no-misused-new": "warn", - "@typescript-eslint/no-namespace": "warn", - "@typescript-eslint/no-non-null-asserted-optional-chain": "warn", - "@typescript-eslint/no-this-alias": "warn", - "@typescript-eslint/no-unnecessary-type-assertion": "warn", - "@typescript-eslint/no-unnecessary-type-constraint": "warn", - "@typescript-eslint/no-unused-vars": [ - "warn", - // MAINTENANCE_TODO: Enable warnings for args - { "vars": "all", "args": "none", "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" } - ], - "@typescript-eslint/prefer-as-const": "warn", - "@typescript-eslint/prefer-for-of": "warn", - "@typescript-eslint/prefer-namespace-keyword": "warn", - "@typescript-eslint/require-await": "warn", - "@typescript-eslint/restrict-plus-operands": "warn", - "@typescript-eslint/triple-slash-reference": "warn", - "@typescript-eslint/unbound-method": "warn", - // MAINTENANCE_TODO: Try to clean up and enable these recommended lints? - //"@typescript-eslint/no-unsafe-argument": "warn", - //"@typescript-eslint/no-unsafe-assignment": "warn", - //"@typescript-eslint/no-unsafe-call": "warn", - //"@typescript-eslint/no-unsafe-member-access": "warn", - //"@typescript-eslint/no-unsafe-return": "warn", - // Note: These recommended lints are probably not practical to enable. - //"@typescript-eslint/no-misused-promises": "warn", - //"@typescript-eslint/no-non-null-assertion": "warn", - //"@typescript-eslint/no-var-requires": "warn", - //"@typescript-eslint/restrict-template-expressions": "warn", + // Plugin: @typescript-eslint + "@typescript-eslint/no-inferrable-types": "off", + "@typescript-eslint/consistent-type-assertions": "warn", + // Recommended lints + // https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/README.md + "@typescript-eslint/adjacent-overload-signatures": "warn", + "@typescript-eslint/await-thenable": "warn", + "@typescript-eslint/ban-ts-comment": "warn", + "@typescript-eslint/no-empty-interface": "warn", + "@typescript-eslint/no-explicit-any": "warn", + "@typescript-eslint/no-extra-non-null-assertion": "warn", + "@typescript-eslint/no-floating-promises": "warn", + "@typescript-eslint/no-for-in-array": "warn", + "@typescript-eslint/no-misused-new": "warn", + "@typescript-eslint/no-namespace": "warn", + "@typescript-eslint/no-non-null-asserted-optional-chain": "warn", + "@typescript-eslint/no-this-alias": "warn", + "@typescript-eslint/no-unnecessary-type-assertion": "warn", + "@typescript-eslint/no-unnecessary-type-constraint": "warn", + "@typescript-eslint/no-unused-vars": [ + "warn", + // MAINTENANCE_TODO: Enable warnings for args + { "vars": "all", "args": "none", "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" } + ], + "@typescript-eslint/prefer-as-const": "warn", + "@typescript-eslint/prefer-for-of": "warn", + "@typescript-eslint/prefer-namespace-keyword": "warn", + "@typescript-eslint/require-await": "warn", + "@typescript-eslint/restrict-plus-operands": "warn", + "@typescript-eslint/triple-slash-reference": "warn", + "@typescript-eslint/unbound-method": "warn", + // MAINTENANCE_TODO: Try to clean up and enable these recommended lints? + //"@typescript-eslint/no-unsafe-argument": "warn", + //"@typescript-eslint/no-unsafe-assignment": "warn", + //"@typescript-eslint/no-unsafe-call": "warn", + //"@typescript-eslint/no-unsafe-member-access": "warn", + //"@typescript-eslint/no-unsafe-return": "warn", + // Note: These recommended lints are probably not practical to enable. + //"@typescript-eslint/no-misused-promises": "warn", + //"@typescript-eslint/no-non-null-assertion": "warn", + //"@typescript-eslint/no-var-requires": "warn", + //"@typescript-eslint/restrict-template-expressions": "warn", - // Plugin: ban - "ban/ban": [ - "warn", - { - "name": "setTimeout", - "message": "WPT disallows setTimeout; use `common/util/timeout.js`." - } - ], + // Plugin: ban + "ban/ban": [ + "warn", + { + "name": "setTimeout", + "message": "WPT disallows setTimeout; use `common/util/timeout.js`." + } + ], - // Plugin: deprecation - //"deprecation/deprecation": "warn", + // Plugin: deprecation + //"deprecation/deprecation": "warn", - // Plugin: n (for Node) - "n/no-unsupported-features/es-syntax": "off", - "n/no-unsupported-features/node-builtins": "off", - "n/no-restricted-require": ["warn", ["*"]], - "n/no-restricted-import": ["warn", [ - { - "name": ["*", "!./**/*.js", "!../**/*.js"], - "message": "All imports must end in .js and be relative for Web. If this a Node-only file, use an eslint-disable directive or subdirectory .eslintrc.json to disable this lint." - } - ]], + // Plugin: n (for Node) + "n/no-unsupported-features/es-syntax": "off", + "n/no-unsupported-features/node-builtins": "off", + "n/no-restricted-require": ["warn", ["*"]], + "n/no-restricted-import": [ + "warn", + [ + { + "name": ["*", "!./**/*.js", "!../**/*.js"], + "message": "All imports must end in .js and be relative for Web. If this a Node-only file, use an eslint-disable directive or subdirectory .eslintrc.json to disable this lint." + } + ] + ], - // Plugin: import - "import/order": [ - "warn", - { - "groups": ["builtin", "external", "internal", "parent", "sibling", "index"], - "newlines-between": "always", - "alphabetize": { "order": "asc", "caseInsensitive": false } - } - ], - "import/newline-after-import": ["warn", { "count": 1 }], - "import/no-duplicates": "warn", - "import/no-restricted-paths": [ - "warn", - { - "zones": [ + // Plugin: import + "import/order": [ + "warn", { - "target": "./src/webgpu", - "from": "./src/common", - "except": ["./framework", "./util"], - "message": "Non-framework common/ code imported from webgpu/ suite" - }, - { - "target": "./src/unittests", - "from": "./src/common", - "except": ["./framework", "./util", "./internal"], - "message": "Non-framework common/ code imported from unittests/ suite" - }, - { - "target": "./src/webgpu", - "from": "./src/unittests", - "message": "unittests/ suite imported from webgpu/ suite" - }, + "groups": ["builtin", "external", "internal", "parent", "sibling", "index"], + "newlines-between": "always", + "alphabetize": { "order": "asc", "caseInsensitive": false } + } + ], + "import/newline-after-import": ["warn", { "count": 1 }], + "import/no-duplicates": "warn", + "import/no-restricted-paths": [ + "warn", { - "target": "./src/common", - "from": "./src", - "except": ["./common", "./external"], - "message": "Non common/ code imported from common/" + "zones": [ + { + "target": "./src/webgpu", + "from": "./src/common", + "except": ["./framework", "./util"], + "message": "Non-framework common/ code imported from webgpu/ suite" + }, + { + "target": "./src/unittests", + "from": "./src/common", + "except": ["./framework", "./util", "./internal"], + "message": "Non-framework common/ code imported from unittests/ suite" + }, + { + "target": "./src/webgpu", + "from": "./src/unittests", + "message": "unittests/ suite imported from webgpu/ suite" + }, + { + "target": "./src/common", + "from": "./src", + "except": ["./common", "./external"], + "message": "Non common/ code imported from common/" + } + ] } ] + }, + "settings": { + "import/resolver": { + "./.eslint-resolver": {} + } } - ] - }, - "settings": { - "import/resolver": { - "./.eslint-resolver": {} } - } + ] } diff --git a/Gruntfile.js b/Gruntfile.js index 626774843444..7f004ab468ec 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,5 +1,4 @@ /* eslint-disable node/no-unpublished-require */ -/* eslint-disable prettier/prettier */ /* eslint-disable no-console */ const timer = require('grunt-timer'); @@ -8,6 +7,15 @@ const path = require('path'); const kAllSuites = ['webgpu', 'stress', 'manual', 'unittests', 'demo']; +const kFilesForEslint = [ + // TS + 'src/**/*.ts', + // JS + '*.js', + '.*.js', + 'tools/**/*.js', +]; + module.exports = function (grunt) { timer.init(grunt); @@ -95,8 +103,10 @@ module.exports = function (grunt) { cmd: 'node', args: [ 'node_modules/typescript/lib/tsc.js', - '--project', 'node.tsconfig.json', - '--outDir', 'out-node/', + '--project', + 'node.tsconfig.json', + '--outDir', + 'out-node/', ], }, 'copy-assets': { @@ -105,7 +115,7 @@ module.exports = function (grunt) { 'node_modules/@babel/cli/bin/babel', 'src/resources/', '--out-dir=out/resources/', - '--copy-files' + '--copy-files', ], }, 'copy-assets-wpt': { @@ -114,7 +124,7 @@ module.exports = function (grunt) { 'node_modules/@babel/cli/bin/babel', 'src/resources/', '--out-dir=out-wpt/resources/', - '--copy-files' + '--copy-files', ], }, 'copy-assets-node': { @@ -123,21 +133,26 @@ module.exports = function (grunt) { 'node_modules/@babel/cli/bin/babel', 'src/resources/', '--out-dir=out-node/resources/', - '--copy-files' + '--copy-files', ], }, lint: { cmd: 'node', - args: ['node_modules/eslint/bin/eslint', 'src/**/*.ts', '--max-warnings=0'], + args: ['node_modules/eslint/bin/eslint', ...kFilesForEslint, '--max-warnings=0'], }, fix: { cmd: 'node', - args: ['node_modules/eslint/bin/eslint', 'src/**/*.ts', '--fix'], + args: ['node_modules/eslint/bin/eslint', ...kFilesForEslint, '--fix'], }, 'autoformat-out-wpt': { cmd: 'node', // MAINTENANCE_TODO(gpuweb/cts#3128): This autoformat step is broken after a dependencies upgrade. - args: ['node_modules/prettier/bin/prettier.cjs', '--log-level=warn', '--write', 'out-wpt/**/*.js'], + args: [ + 'node_modules/prettier/bin/prettier.cjs', + '--log-level=warn', + '--write', + 'out-wpt/**/*.js', + ], }, tsdoc: { cmd: 'node', @@ -150,8 +165,8 @@ module.exports = function (grunt) { serve: { cmd: 'node', - args: ['node_modules/http-server/bin/http-server', '-p8080', '-a127.0.0.1', '-c-1'] - } + args: ['node_modules/http-server/bin/http-server', '-p8080', '-a127.0.0.1', '-c-1'], + }, }, copy: { @@ -171,31 +186,20 @@ module.exports = function (grunt) { }, 'htmlfiles-to-out': { // Must run after run:build-out. - files: [ - { expand: true, dest: 'out/', cwd: 'src', src: 'webgpu/**/*.html' }, - ], + files: [{ expand: true, dest: 'out/', cwd: 'src', src: 'webgpu/**/*.html' }], }, 'htmlfiles-to-out-wpt': { // Must run after run:build-out-wpt. - files: [ - { expand: true, dest: 'out-wpt/', cwd: 'src', src: 'webgpu/**/*.html' }, - ], + files: [{ expand: true, dest: 'out-wpt/', cwd: 'src', src: 'webgpu/**/*.html' }], }, }, concurrent: { 'write-out-wpt-cts-html-all': { - tasks: [ - 'run:write-out-wpt-cts-html', - 'run:write-out-wpt-cts-html-chunked2sec', - ], + tasks: ['run:write-out-wpt-cts-html', 'run:write-out-wpt-cts-html-chunked2sec'], }, 'all-builds': { - tasks: [ - 'build-standalone', - 'build-wpt', - 'run:build-out-node', - ], + tasks: ['build-standalone', 'build-wpt', 'run:build-out-node'], }, 'all-checks': { tasks: [ @@ -230,15 +234,15 @@ module.exports = function (grunt) { helpMessageTasks.push({ name, desc }); } - grunt.registerTask('ts-check', function() { - spawnSync(path.join('node_modules', '.bin', 'tsc'), [ - '--project', - 'tsconfig.json', - '--noEmit', - ], { - shell: true, - stdio: 'inherit', - }); + grunt.registerTask('ts-check', () => { + spawnSync( + path.join('node_modules', '.bin', 'tsc'), + ['--project', 'tsconfig.json', '--noEmit'], + { + shell: true, + stdio: 'inherit', + } + ); }); grunt.registerTask('generate-common', 'Generate files into gen/ and src/', [ @@ -297,18 +301,10 @@ module.exports = function (grunt) { 'build-node', 'build-done-message', ]); - registerTaskAndAddToHelp('checks', 'Run all checks (and build tsdoc)', [ - 'concurrent:all-checks', - ]); - registerTaskAndAddToHelp('unittest', 'Just run unittests', [ - 'run:unittest', - ]); - registerTaskAndAddToHelp('typecheck', 'Just typecheck', [ - 'ts-check', - ]); - registerTaskAndAddToHelp('tsdoc', 'Just build tsdoc', [ - 'run:tsdoc', - ]); + registerTaskAndAddToHelp('checks', 'Run all checks (and build tsdoc)', ['concurrent:all-checks']); + registerTaskAndAddToHelp('unittest', 'Just run unittests', ['run:unittest']); + registerTaskAndAddToHelp('typecheck', 'Just typecheck', ['ts-check']); + registerTaskAndAddToHelp('tsdoc', 'Just build tsdoc', ['run:tsdoc']); registerTaskAndAddToHelp('serve', 'Serve out/ (without building anything)', ['run:serve']); registerTaskAndAddToHelp('lint', 'Check lint and formatting', ['run:lint']); @@ -318,7 +314,7 @@ module.exports = function (grunt) { grunt.registerTask('default', '', () => { console.error('\nRecommended tasks:'); - let nameColumnSize = Math.max(...helpMessageTasks.map(({ name }) => name.length)); + const nameColumnSize = Math.max(...helpMessageTasks.map(({ name }) => name.length)); for (const { name, desc } of helpMessageTasks) { console.error(`$ grunt ${name.padEnd(nameColumnSize)} # ${desc}`); } diff --git a/tools/eslint-plugin-gpuweb-cts/tabs-anywhere.js b/tools/eslint-plugin-gpuweb-cts/tabs-anywhere.js index 82238f8615c7..e4bc4f0ecdcb 100644 --- a/tools/eslint-plugin-gpuweb-cts/tabs-anywhere.js +++ b/tools/eslint-plugin-gpuweb-cts/tabs-anywhere.js @@ -2,7 +2,8 @@ module.exports = { meta: { type: 'suggestion', docs: { - description: 'Indentation tabs are not allowed, even in multiline strings, due to WPT lint rules. This rule simply disallows tabs anywhere.', + description: + 'Indentation tabs are not allowed, even in multiline strings, due to WPT lint rules. This rule simply disallows tabs anywhere.', }, schema: [], }, diff --git a/tools/eslint-plugin-gpuweb-cts/trailing-space-anywhere.js b/tools/eslint-plugin-gpuweb-cts/trailing-space-anywhere.js index 811b379ff648..070ae5c193e5 100644 --- a/tools/eslint-plugin-gpuweb-cts/trailing-space-anywhere.js +++ b/tools/eslint-plugin-gpuweb-cts/trailing-space-anywhere.js @@ -2,7 +2,8 @@ module.exports = { meta: { type: 'suggestion', docs: { - description: 'Trailing spaces are not allowed, even in multiline strings, due to WPT lint rules.', + description: + 'Trailing spaces are not allowed, even in multiline strings, due to WPT lint rules.', }, schema: [], }, diff --git a/tools/websocket-logger/.eslintrc.json b/tools/websocket-logger/.eslintrc.json new file mode 100644 index 000000000000..cca2ec844968 --- /dev/null +++ b/tools/websocket-logger/.eslintrc.json @@ -0,0 +1,13 @@ +{ + "parserOptions": { + "ecmaVersion": "2022", + // Needed because eslint doesn't pick up the subdirectory package.json. + "sourceType": "module" + }, + "rules": { + "no-process-exit": "off", + // Rules needed because eslint doesn't pick up the subdirectory package.json. + "node/no-unsupported-features/es-syntax": "off", + "node/no-missing-import": "off" + } +} diff --git a/tools/websocket-logger/main.js b/tools/websocket-logger/main.js old mode 100755 new mode 100644 index 4a5a89e7620a..eb14e73fac77 --- a/tools/websocket-logger/main.js +++ b/tools/websocket-logger/main.js @@ -1,12 +1,10 @@ -#!/usr/bin/env node - import fs from 'fs/promises'; import { WebSocketServer } from 'ws'; const wss = new WebSocketServer({ port: 59497 }); -const timestamp = new Date().toISOString().slice(0, 19).replace(/[:]/g, '-') -const filename = `wslog-${timestamp}.txt` +const timestamp = new Date().toISOString().slice(0, 19).replace(/[:]/g, '-'); +const filename = `wslog-${timestamp}.txt`; const f = await fs.open(filename, 'w'); console.log(`Writing to ${filename}`); console.log('Ctrl-C to stop');