Skip to content

Commit 0552d04

Browse files
committed
DRY more things up
1 parent 4b09f8c commit 0552d04

File tree

6 files changed

+259
-266
lines changed

6 files changed

+259
-266
lines changed

packages/build/src/esbuild.ts

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
import * as fs from "fs"
2+
import * as path from "path"
3+
4+
import { ViewsContainer, Views, Menus, Configuration, contributesSchema } from "./types.js"
5+
6+
export function copyPaths(copyPaths: [string, string][], srcDir: string, dstDir: string) {
7+
copyPaths.forEach(([srcRelPath, dstRelPath]) => {
8+
const stats = fs.lstatSync(path.join(srcDir, srcRelPath))
9+
10+
if (stats.isDirectory()) {
11+
if (fs.existsSync(path.join(dstDir, dstRelPath))) {
12+
fs.rmSync(path.join(dstDir, dstRelPath), { recursive: true })
13+
}
14+
15+
fs.mkdirSync(path.join(dstDir, dstRelPath), { recursive: true })
16+
17+
const count = copyDir(path.join(srcDir, srcRelPath), path.join(dstDir, dstRelPath), 0)
18+
console.log(`[copyPaths] Copied ${count} files from ${srcRelPath} to ${dstRelPath}`)
19+
} else {
20+
fs.copyFileSync(path.join(srcDir, srcRelPath), path.join(dstDir, dstRelPath))
21+
console.log(`[copyPaths] Copied ${srcRelPath} to ${dstRelPath}`)
22+
}
23+
})
24+
}
25+
26+
export function copyDir(srcDir: string, dstDir: string, count: number): number {
27+
const entries = fs.readdirSync(srcDir, { withFileTypes: true })
28+
29+
for (const entry of entries) {
30+
const srcPath = path.join(srcDir, entry.name)
31+
const dstPath = path.join(dstDir, entry.name)
32+
33+
if (entry.isDirectory()) {
34+
fs.mkdirSync(dstPath, { recursive: true })
35+
count = copyDir(srcPath, dstPath, count)
36+
} else {
37+
count = count + 1
38+
fs.copyFileSync(srcPath, dstPath)
39+
}
40+
}
41+
42+
return count
43+
}
44+
45+
export function copyWasms(srcDir: string, distDir: string): void {
46+
const nodeModulesDir = path.join(srcDir, "node_modules")
47+
48+
fs.mkdirSync(distDir, { recursive: true })
49+
50+
// Tiktoken WASM file.
51+
fs.copyFileSync(
52+
path.join(nodeModulesDir, "tiktoken", "lite", "tiktoken_bg.wasm"),
53+
path.join(distDir, "tiktoken_bg.wasm"),
54+
)
55+
56+
console.log(`[copyWasms] Copied tiktoken WASMs to ${distDir}`)
57+
58+
// Also copy Tiktoken WASMs to the workers directory.
59+
const workersDir = path.join(distDir, "workers")
60+
fs.mkdirSync(workersDir, { recursive: true })
61+
62+
fs.copyFileSync(
63+
path.join(nodeModulesDir, "tiktoken", "lite", "tiktoken_bg.wasm"),
64+
path.join(workersDir, "tiktoken_bg.wasm"),
65+
)
66+
67+
console.log(`[copyWasms] Copied tiktoken WASMs to ${workersDir}`)
68+
69+
// Main tree-sitter WASM file.
70+
fs.copyFileSync(
71+
path.join(nodeModulesDir, "web-tree-sitter", "tree-sitter.wasm"),
72+
path.join(distDir, "tree-sitter.wasm"),
73+
)
74+
75+
console.log(`[copyWasms] Copied tree-sitter.wasm to ${distDir}`)
76+
77+
// Copy language-specific WASM files.
78+
const languageWasmDir = path.join(nodeModulesDir, "tree-sitter-wasms", "out")
79+
80+
if (!fs.existsSync(languageWasmDir)) {
81+
throw new Error(`Directory does not exist: ${languageWasmDir}`)
82+
}
83+
84+
// Dynamically read all WASM files from the directory instead of using a hardcoded list.
85+
const wasmFiles = fs.readdirSync(languageWasmDir).filter((file) => file.endsWith(".wasm"))
86+
87+
wasmFiles.forEach((filename) => {
88+
fs.copyFileSync(path.join(languageWasmDir, filename), path.join(distDir, filename))
89+
})
90+
91+
console.log(`[copyWasms] Copied ${wasmFiles.length} tree-sitter language wasms to ${distDir}`)
92+
}
93+
94+
export function copyLocales(srcDir: string, distDir: string): void {
95+
const destDir = path.join(distDir, "i18n", "locales")
96+
fs.mkdirSync(destDir, { recursive: true })
97+
const count = copyDir(path.join(srcDir, "i18n", "locales"), destDir, 0)
98+
console.log(`[copyLocales] Copied ${count} locale files to ${destDir}`)
99+
}
100+
101+
export function setupLocaleWatcher(srcDir: string, distDir: string) {
102+
const localesDir = path.join(srcDir, "i18n", "locales")
103+
104+
if (!fs.existsSync(localesDir)) {
105+
console.warn(`Cannot set up watcher: Source locales directory does not exist: ${localesDir}`)
106+
return
107+
}
108+
109+
console.log(`Setting up watcher for locale files in ${localesDir}`)
110+
111+
let debounceTimer: NodeJS.Timeout | null = null
112+
113+
const debouncedCopy = () => {
114+
if (debounceTimer) {
115+
clearTimeout(debounceTimer)
116+
}
117+
118+
// Wait 300ms after last change before copying.
119+
debounceTimer = setTimeout(() => {
120+
console.log("Locale files changed, copying...")
121+
copyLocales(srcDir, distDir)
122+
}, 300)
123+
}
124+
125+
try {
126+
fs.watch(localesDir, { recursive: true }, (_eventType, filename) => {
127+
if (filename && filename.endsWith(".json")) {
128+
console.log(`Locale file ${filename} changed, triggering copy...`)
129+
debouncedCopy()
130+
}
131+
})
132+
console.log("Watcher for locale files is set up")
133+
} catch (error) {
134+
console.error(
135+
`Error setting up watcher for ${localesDir}:`,
136+
error instanceof Error ? error.message : "Unknown error",
137+
)
138+
}
139+
}
140+
141+
export function generatePackageJson({
142+
packageJson: { contributes, ...packageJson },
143+
overrideJson,
144+
substitution,
145+
}: {
146+
packageJson: Record<string, any>
147+
overrideJson: Record<string, any>
148+
substitution: [string, string]
149+
}) {
150+
const { viewsContainers, views, commands, menus, submenus, configuration } = contributesSchema.parse(contributes)
151+
const [from, to] = substitution
152+
153+
return {
154+
...packageJson,
155+
...overrideJson,
156+
contributes: {
157+
viewsContainers: transformArrayRecord<ViewsContainer>(viewsContainers, from, to, ["id"]),
158+
views: transformArrayRecord<Views>(views, from, to, ["id"]),
159+
commands: transformArray(commands, from, to, "command"),
160+
menus: transformArrayRecord<Menus>(menus, from, to, ["command", "submenu", "when"]),
161+
submenus: transformArray(submenus, from, to, "id"),
162+
configuration: {
163+
title: configuration.title,
164+
properties: transformRecord<Configuration["properties"]>(configuration.properties, from, to),
165+
},
166+
},
167+
}
168+
}
169+
170+
function transformArrayRecord<T>(obj: Record<string, any[]>, from: string, to: string, props: string[]): T {
171+
return Object.entries(obj).reduce(
172+
(acc, [key, ary]) => ({
173+
...acc,
174+
[key.replace(from, to)]: ary.map((item) => {
175+
const transformedItem = { ...item }
176+
177+
for (const prop of props) {
178+
if (prop in item && typeof item[prop] === "string") {
179+
transformedItem[prop] = item[prop].replace(from, to)
180+
}
181+
}
182+
183+
return transformedItem
184+
}),
185+
}),
186+
{} as T,
187+
)
188+
}
189+
190+
function transformArray<T>(arr: any[], from: string, to: string, idProp: string): T[] {
191+
return arr.map(({ [idProp]: id, ...rest }) => ({
192+
[idProp]: id.replace(from, to),
193+
...rest,
194+
}))
195+
}
196+
197+
function transformRecord<T>(obj: Record<string, any>, from: string, to: string): T {
198+
return Object.entries(obj).reduce(
199+
(acc, [key, value]) => ({
200+
...acc,
201+
[key.replace(from, to)]: value,
202+
}),
203+
{} as T,
204+
)
205+
}

packages/build/src/git.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { execSync } from "child_process"
2+
3+
export function getGitSha() {
4+
let gitSha = undefined
5+
6+
try {
7+
gitSha = execSync("git rev-parse HEAD").toString().trim()
8+
} catch (e) {}
9+
10+
return gitSha
11+
}

0 commit comments

Comments
 (0)