-
Notifications
You must be signed in to change notification settings - Fork 62
/
Copy pathfix.js
124 lines (110 loc) · 3.16 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
112
113
114
115
116
117
118
119
120
121
122
123
124
// This should run by node without any dependencies
// because you may need to run it without deps.
import fs from 'node:fs'
import cp from 'node:child_process'
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 updateTsconfig()
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 updateTsconfig() {
const tsconfig = {
files: [],
exclude: ['node_modules'],
references: appsWithPkgJson.map(a => ({
path: relativeToWorkshopRoot(a).replace(/\\/g, '/'),
})),
}
const written = await writeIfNeeded(
path.join(workshopRoot, 'tsconfig.json'),
`${JSON.stringify(tsconfig, null, 2)}\n`,
{ parser: 'json' },
)
if (written) {
// delete node_modules/.cache
const cacheDir = path.join(workshopRoot, 'node_modules', '.cache')
if (exists(cacheDir)) {
await fs.promises.rm(cacheDir, { recursive: true })
}
console.log('all fixed up')
}
}
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 (error) {
return false
}
}
function isFile(p) {
try {
return fs.statSync(p).isFile()
} catch (error) {
return false
}
}
async function readDir(dir) {
if (exists(dir)) {
return fs.promises.readdir(dir)
}
return []
}