-
Notifications
You must be signed in to change notification settings - Fork 52
/
Copy pathfix.js
111 lines (97 loc) · 3.05 KB
/
fix.js
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// This should run by node without any dependencies
// because you may need to run it without deps.
import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const here = (...p) => path.join(__dirname, ...p)
// const VERBOSE = false
// const logVerbose = (...args) => (VERBOSE ? console.log(...args) : undefined)
const workshopRoot = here('..')
const examples = (await readDir(here('../examples'))).map((dir) =>
here(`../examples/${dir}`),
)
const exercises = (await readDir(here('../exercises')))
.map((name) => here(`../exercises/${name}`))
.filter((filepath) => fs.statSync(filepath).isDirectory())
const exerciseApps = (
await Promise.all(
exercises.flatMap(async (exercise) => {
return (await readDir(exercise))
.filter((dir) => {
return /(problem|solution)/.test(dir)
})
.map((dir) => path.join(exercise, dir))
}),
)
).flat()
const exampleApps = (await readDir(here('../examples'))).map((dir) =>
here(`../examples/${dir}`),
)
const apps = [...exampleApps, ...exerciseApps]
const appsWithPkgJson = [...examples, ...apps].filter((app) => {
const pkgjsonPath = path.join(app, 'package.json')
return exists(pkgjsonPath)
})
// update the package.json file name property
// to match the parent directory name + directory name
// e.g. exercises/01-goo/problem.01-great
// name: "exercises__sep__01-goo.problem__sep__01-great"
function relativeToWorkshopRoot(dir) {
return dir.replace(`${workshopRoot}${path.sep}`, '')
}
await updatePkgNames()
await copyTestFiles()
async function updatePkgNames() {
for (const file of appsWithPkgJson) {
const pkgjsonPath = path.join(file, 'package.json')
const pkg = JSON.parse(await fs.promises.readFile(pkgjsonPath, 'utf8'))
pkg.name = relativeToWorkshopRoot(file).replace(/\\|\//g, '__sep__')
const written = await writeIfNeeded(
pkgjsonPath,
`${JSON.stringify(pkg, null, 2)}\n`,
)
if (written) {
console.log(`updated ${path.relative(process.cwd(), pkgjsonPath)}`)
}
}
}
async function copyTestFiles() {
for (const app of exerciseApps) {
if (app.includes('problem')) {
const solutionApp = app.replace('problem', 'solution')
const testDir = path.join(solutionApp, 'tests')
const destTestDir = path.join(app, 'tests')
if (exists(testDir)) {
// Remove existing test directory in problem app if it exists
if (exists(destTestDir)) {
await fs.promises.rm(destTestDir, { recursive: true, force: true })
}
// Copy the entire test directory from solution to problem
await fs.promises.cp(testDir, destTestDir, { recursive: true })
}
}
}
}
async function writeIfNeeded(filepath, content) {
const oldContent = await fs.promises.readFile(filepath, 'utf8')
if (oldContent !== content) {
await fs.promises.writeFile(filepath, content)
}
return oldContent !== content
}
function exists(p) {
if (!p) return false
try {
fs.statSync(p)
return true
} catch {
return false
}
}
async function readDir(dir) {
if (exists(dir)) {
return fs.promises.readdir(dir)
}
return []
}