/ scripts / lintChanged.js
lintChanged.js
 1  #!/usr/bin/env node
 2  
 3  const { execSync, spawnSync } = require("node:child_process")
 4  
 5  const mode = process.argv[2] || "check"
 6  
 7  if (!["check", "fix"].includes(mode)) {
 8    console.error('Usage: node scripts/lintChanged.js [check|fix]')
 9    process.exit(1)
10  }
11  
12  const runGit = command => {
13    try {
14      return execSync(command, {
15        encoding: "utf8",
16        stdio: ["ignore", "pipe", "pipe"],
17      }).trim()
18    } catch (_err) {
19      return ""
20    }
21  }
22  
23  const originDefaultBranch = (() => {
24    const head = runGit("git symbolic-ref refs/remotes/origin/HEAD")
25    if (!head) {
26      return ""
27    }
28  
29    return head.replace("refs/remotes/origin/", "")
30  })()
31  
32  const baseRef = originDefaultBranch ? `origin/${originDefaultBranch}` : "origin/master"
33  const mergeBase = runGit(`git merge-base ${baseRef} HEAD`) || "HEAD~1"
34  
35  const changedSets = [
36    runGit(`git diff --name-only --diff-filter=ACMR ${mergeBase}...HEAD`),
37    runGit("git diff --name-only --diff-filter=ACMR"),
38    runGit("git diff --name-only --cached --diff-filter=ACMR"),
39    runGit("git ls-files --others --exclude-standard"),
40  ]
41  
42  const lintableFiles = [...new Set(changedSets.join("\n").split("\n"))].filter(
43    file =>
44      file.startsWith("packages/") &&
45      (file.endsWith(".js") || file.endsWith(".ts") || file.endsWith(".svelte"))
46  )
47  
48  if (lintableFiles.length === 0) {
49    console.log("No changed lintable files under packages/")
50    process.exit(0)
51  }
52  
53  const resolveBin = name =>
54    process.platform === "win32"
55      ? `.\\node_modules\\.bin\\${name}.cmd`
56      : `./node_modules/.bin/${name}`
57  
58  const run = (bin, args) => {
59    const result = spawnSync(resolveBin(bin), args, {
60      stdio: "inherit",
61      shell: process.platform === "win32",
62    })
63  
64    if (result.status !== 0) {
65      process.exit(result.status || 1)
66    }
67  }
68  
69  if (mode === "fix") {
70    run("eslint", ["--fix", "--max-warnings=0", ...lintableFiles])
71    run("prettier", ["--write", ...lintableFiles])
72  } else {
73    run("eslint", ["--max-warnings=0", ...lintableFiles])
74    run("prettier", ["--check", ...lintableFiles])
75  }