-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathensure-dependencies-up-to-date.ts
75 lines (67 loc) · 2.3 KB
/
ensure-dependencies-up-to-date.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { exec as execOriginal, spawn } from "child_process"
import { mkdir, readFile, writeFile } from "fs/promises"
import path from "path"
import { fileURLToPath } from "url"
import { promisify } from "util"
const exec = promisify(execOriginal)
const currentDir = path.dirname(fileURLToPath(import.meta.url))
const projectRoot = path.resolve(currentDir, "..")
const savedCommitHashesPath = `${projectRoot}/.husky/_/saved-hashes`
async function main(): Promise<void> {
await mkdir(savedCommitHashesPath, { recursive: true })
await detectChange("package-lock.json", "package-lock", async () => {
console.log("Running npm ci to install latest dependencies.")
console.log(`> npm ci`)
await runCommandWithVisibleOutput("npm", ["ci"])
})
await detectChange(
"shared-module/packages/common/src/locales",
"shared-module-common-locales",
async () => {
console.log("Installing the shared module again.")
console.log(`> npm run postinstall`)
await runCommandWithVisibleOutput("npm", ["run", "postinstall"])
},
)
}
async function detectChange(
relativePath: string,
key: string,
onChangeDetected: () => Promise<void>,
): Promise<void> {
const hash = await getLatestCommitHash(relativePath)
const savedHash = await getSavedCommitHash(key)
if (hash === savedHash) {
return
}
console.log(
`Detected a change in '${relativePath}'. (Saved hash: '${savedHash}', New hash: '${hash}')`,
)
await onChangeDetected()
await writeFile(`${savedCommitHashesPath}/${key}`, hash)
}
async function getSavedCommitHash(key: string): Promise<string | null> {
try {
return await readFile(`${savedCommitHashesPath}/${key}`, "utf-8")
} catch (_e) {
// Happens usually when we have not written yet
return null
}
}
function runCommandWithVisibleOutput(program: string, args: string[]): Promise<void> {
return new Promise((resolve, reject) => {
const handle = spawn(program, args, { cwd: process.cwd(), detached: false, stdio: "inherit" })
handle.on("close", (code) => {
if (code !== 0) {
reject()
return
}
resolve()
})
})
}
async function getLatestCommitHash(relativePath: string): Promise<string> {
const res = await exec(`git log -n 1 --pretty=format:%H -- '${projectRoot}/${relativePath}'`)
return res.stdout.trim()
}
main()