Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"lint:fix": "eslint \"**/*.{js,mjs,jsx,ts,tsx}\" --fix",
"pretty:check": "prettier --check ./",
"pretty:fix": "prettier --write ./",
"format": "npm run pretty:fix && npm run lint:fix",
"format": "node tests/format.mjs",
"format:all": "node tests/format.mjs --all",
"test:chrome": "node tests/run-unittests.mjs --browser chrome",
"test:firefox": "node tests/run-unittests.mjs --browser firefox",
"test:safari": "node tests/run-unittests.mjs --browser safari",
Expand All @@ -46,16 +47,16 @@
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-vue": "^9.10.0",
"expect.js": "^0.3.1",
"mocha": "^10.2.0",
"prettier": "^2.8.3",
"selenium-webdriver": "^4.27.0",
"sinon": "^17.0.1",
"typescript": "^5.0.4",
"lws": "^4.2.0",
"lws-cors": "^4.2.1",
"lws-index": "^3.1.1",
"lws-log": "^3.0.0",
"lws-static": "^3.1.1",
"prettier-plugin-tailwindcss": "^0.4.1"
"mocha": "^10.2.0",
"prettier": "^2.8.3",
"prettier-plugin-tailwindcss": "^0.4.1",
"selenium-webdriver": "^4.27.0",
"sinon": "^17.0.1",
"typescript": "^5.0.4"
}
}
97 changes: 97 additions & 0 deletions tests/format.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { execFileSync } from "child_process";
import { parseArgs } from "util";
import fs from "fs";

function formatAll() {
console.log("Formatting all files...");
execFileSync("npm", ["run", "pretty:fix"], { stdio: "inherit" });
execFileSync("npm", ["run", "lint:fix"], { stdio: "inherit" });
}

// Chunk files into batches to avoid "Argument list too long" errors on large changelists.
function execFileSyncInBatches(command, args, files, batchSize = 100) {
for (let i = 0; i < files.length; i += batchSize) {
const batch = files.slice(i, i + batchSize);
execFileSync("npx", [command, ...args, ...batch], { stdio: "inherit" });
}
}

function runPrettier(files) {
try {
console.log(`Running prettier on ${files.length} file(s)`);
execFileSyncInBatches("prettier", ["--write", "--ignore-unknown"], files);
} catch (e) {
console.error("Prettier formatting failed");
process.exit(1);
}
}

function runEslint(files) {
const jsTsFiles = files.filter((f) => /\.(js|mjs|jsx|ts|tsx)$/.test(f));
if (jsTsFiles.length === 0)
return;
try {
console.log(`Running eslint on ${jsTsFiles.length} file(s)`);
execFileSyncInBatches("eslint", ["--fix"], jsTsFiles);
} catch (e) {
console.error("ESLint formatting failed");
process.exit(1);
}
}

function getChangedFiles() {
// "--diff-filter=ACMR" => ignore deleted files.
const diffOut = execFileSync("git", ["diff", "--name-only", "--diff-filter=ACMR", "@{upstream}"], { encoding: "utf8" });
const files = diffOut
.split("\n")
.map((f) => f.trim())
.filter((f) => f.length > 0 && fs.existsSync(f));
return [...new Set(files)];
}

let values;
try {
({ values } = parseArgs({
options: {
all: { type: "boolean" },
help: { type: "boolean", short: "h" },
},
strict: true,
}));
} catch (err) {
console.error(err.message);
console.error("Run 'node tests/format.mjs --help' for usage.");
process.exit(1);
}

if (values.help) {
console.log(`Usage: node tests/format.mjs [options]

Options:
--all Format all files across the repository instead of just changed files
-h, --help Show this help message`);
process.exit(0);
}

if (values.all) {
formatAll();
process.exit(0);
}

let changedFiles = [];
try {
changedFiles = getChangedFiles();
} catch (e) {
console.error("Failed to get changed files from git. Falling back to formatting all files.");
formatAll();
process.exit(0);
}

if (changedFiles.length === 0) {
console.log("No files changed compared to upstream.");
process.exit(0);
}
console.log(`Formatting ${changedFiles.length} changed files compared to upstream`);

runPrettier(changedFiles);
runEslint(changedFiles);
Loading