@kunver/new 3.2.0 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.MD +0 -2
- package/dist/index.js +11 -11
- package/dist/templates/cmake-cpp/README.md +32 -32
- package/dist/templates/cmake-cpp/agents.md +8 -8
- package/dist/templates/cmake-cpp/manager.ts +276 -276
- package/dist/templates/next-prisma/_prettierrc.json +12 -12
- package/dist/templates/next-prisma/manager.cjs +71 -71
- package/dist/templates/next-prisma/next.config.ts +7 -7
- package/dist/templates/next-prisma/postcss.config.mjs +5 -5
- package/dist/templates/react-ts-tw/README.md +1 -1
- package/dist/templates/react-ts-tw/_prettierrc.json +12 -12
- package/dist/templates/react-ts-tw/manager.cjs +71 -71
- package/dist/templates/react-ts-tw/src/index.css +1 -1
- package/dist/templates/react-ts-tw/src/main.tsx +10 -10
- package/dist/templates/react-ts-tw/tsconfig.json +4 -4
- package/dist/templates/react-ts-tw/vite.config.ts +8 -8
- package/dist/templates/wxt-solid/_prettierrc.json +11 -0
- package/dist/templates/wxt-solid/entrypoints/content/Content.tsx +7 -7
- package/dist/templates/wxt-solid/entrypoints/options/main.tsx +6 -6
- package/dist/templates/wxt-solid/entrypoints/popup/{App.tsx → Popup.tsx} +7 -7
- package/dist/templates/wxt-solid/entrypoints/popup/main.tsx +6 -6
- package/dist/templates/wxt-solid/manager.cjs +71 -71
- package/dist/templates/wxt-svelte/_prettierrc.json +11 -11
- package/dist/templates/wxt-svelte/entrypoints/content/index.ts +25 -25
- package/dist/templates/wxt-svelte/entrypoints/options/index.html +13 -13
- package/dist/templates/wxt-svelte/entrypoints/options/main.ts +9 -9
- package/dist/templates/wxt-svelte/entrypoints/popup/index.html +13 -13
- package/dist/templates/wxt-svelte/entrypoints/popup/main.ts +9 -9
- package/dist/templates/wxt-svelte/manager.cjs +71 -71
- package/dist/templates/wxt-vanilla/_prettierrc.json +11 -11
- package/dist/templates/wxt-vanilla/entrypoints/background.ts +3 -3
- package/dist/templates/wxt-vanilla/entrypoints/content.ts +6 -6
- package/dist/templates/wxt-vanilla/entrypoints/popup/main.ts +1 -1
- package/dist/templates/wxt-vanilla/manager.cjs +71 -71
- package/package.json +55 -55
- package/dist/templates/electron-svelte/README.md +0 -3
- package/dist/templates/electron-svelte/_gitignore +0 -6
- package/dist/templates/electron-svelte/_prettierignore +0 -6
- package/dist/templates/electron-svelte/_prettierrc.yaml +0 -13
- package/dist/templates/electron-svelte/build/entitlements.mac.plist +0 -12
- package/dist/templates/electron-svelte/build/icon.icns +0 -0
- package/dist/templates/electron-svelte/build/icon.ico +0 -0
- package/dist/templates/electron-svelte/build/icon.png +0 -0
- package/dist/templates/electron-svelte/bun.lock +0 -1154
- package/dist/templates/electron-svelte/electron-builder.yml +0 -44
- package/dist/templates/electron-svelte/electron.vite.config.ts +0 -15
- package/dist/templates/electron-svelte/manager.cjs +0 -71
- package/dist/templates/electron-svelte/package.json +0 -44
- package/dist/templates/electron-svelte/resources/icon.png +0 -0
- package/dist/templates/electron-svelte/src/main/index.ts +0 -62
- package/dist/templates/electron-svelte/src/preload/index.d.ts +0 -8
- package/dist/templates/electron-svelte/src/preload/index.ts +0 -22
- package/dist/templates/electron-svelte/src/renderer/index.html +0 -16
- package/dist/templates/electron-svelte/src/renderer/src/App.svelte +0 -8
- package/dist/templates/electron-svelte/src/renderer/src/assets/main.css +0 -1
- package/dist/templates/electron-svelte/src/renderer/src/env.d.ts +0 -2
- package/dist/templates/electron-svelte/src/renderer/src/main.ts +0 -11
- package/dist/templates/electron-svelte/svelte.config.mjs +0 -7
- package/dist/templates/electron-svelte/tsconfig.json +0 -4
- package/dist/templates/electron-svelte/tsconfig.node.json +0 -11
- package/dist/templates/electron-svelte/tsconfig.web.json +0 -17
- /package/dist/templates/wxt-solid/entrypoints/options/{App.tsx → Options.tsx} +0 -0
- /package/dist/templates/wxt-svelte/entrypoints/content/{App.svelte → Content.svelte} +0 -0
- /package/dist/templates/wxt-svelte/entrypoints/options/{App.svelte → Options.svelte} +0 -0
- /package/dist/templates/wxt-svelte/entrypoints/popup/{App.svelte → Popup.svelte} +0 -0
|
@@ -1,276 +1,276 @@
|
|
|
1
|
-
import { existsSync, readdirSync, readFileSync, rmSync } from "node:fs"
|
|
2
|
-
import { join } from "node:path"
|
|
3
|
-
import { platform } from "node:os"
|
|
4
|
-
import { spawn } from "node:child_process"
|
|
5
|
-
|
|
6
|
-
type CommandName = "help" | "doctor" | "configure" | "build" | "run" | "dev" | "rebuild" | "clean"
|
|
7
|
-
|
|
8
|
-
type ManagerOptions = {
|
|
9
|
-
config?: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const ROOT_DIR = process.cwd()
|
|
13
|
-
const BUILD_DIR = join(ROOT_DIR, "build")
|
|
14
|
-
const IS_WINDOWS = platform() === "win32"
|
|
15
|
-
|
|
16
|
-
function print(message: string) {
|
|
17
|
-
process.stdout.write(`${message}\n`)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function printError(message: string) {
|
|
21
|
-
process.stderr.write(`${message}\n`)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function getProjectName() {
|
|
25
|
-
const cmakeListsPath = join(ROOT_DIR, "CMakeLists.txt")
|
|
26
|
-
|
|
27
|
-
if (!existsSync(cmakeListsPath)) {
|
|
28
|
-
return null
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const cmakeListsContent = readFileSync(cmakeListsPath, "utf-8")
|
|
32
|
-
const match = cmakeListsContent.match(/project\s*\(\s*(?:"([^"]+)"|([^\s\)]+))/i)
|
|
33
|
-
|
|
34
|
-
return match?.[1] ?? match?.[2] ?? null
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function parseArgs(argv: string[]) {
|
|
38
|
-
const [commandArg, ...rest] = argv
|
|
39
|
-
const command = (commandArg ?? "help") as CommandName
|
|
40
|
-
const options: ManagerOptions = {}
|
|
41
|
-
|
|
42
|
-
for (let index = 0; index < rest.length; index += 1) {
|
|
43
|
-
const arg = rest[index]
|
|
44
|
-
|
|
45
|
-
if ((arg === "--config" || arg === "-c") && rest[index + 1]) {
|
|
46
|
-
options.config = rest[index + 1]
|
|
47
|
-
index += 1
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return { command, options }
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function runCommand(command: string, args: string[], cwd = ROOT_DIR) {
|
|
55
|
-
return new Promise<boolean>(resolve => {
|
|
56
|
-
const child = spawn(command, args, {
|
|
57
|
-
cwd,
|
|
58
|
-
stdio: "inherit",
|
|
59
|
-
shell: false,
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
child.on("close", code => {
|
|
63
|
-
resolve(code === 0)
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
child.on("error", () => {
|
|
67
|
-
resolve(false)
|
|
68
|
-
})
|
|
69
|
-
})
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async function ensureCmakeAvailable() {
|
|
73
|
-
const ok = await runCommand("cmake", ["--version"])
|
|
74
|
-
if (!ok) {
|
|
75
|
-
printError("CMake not found. Install CMake and ensure it is available in PATH.")
|
|
76
|
-
}
|
|
77
|
-
return ok
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
async function configure() {
|
|
81
|
-
print("Configuring project with CMake...")
|
|
82
|
-
return runCommand("cmake", ["-S", ".", "-B", "build"])
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
async function build(config?: string) {
|
|
86
|
-
print("Building project...")
|
|
87
|
-
const args = ["--build", "build"]
|
|
88
|
-
|
|
89
|
-
if (config) {
|
|
90
|
-
args.push("--config", config)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return runCommand("cmake", args)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function getCandidateExecutablePaths(config?: string) {
|
|
97
|
-
const projectName = getProjectName()
|
|
98
|
-
if (!projectName) {
|
|
99
|
-
return []
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const executableName = IS_WINDOWS ? `${projectName}.exe` : projectName
|
|
103
|
-
const requestedConfig = config ? [config] : []
|
|
104
|
-
const commonConfigs = ["Debug", "Release", "RelWithDebInfo", "MinSizeRel"]
|
|
105
|
-
const configDirs = [...requestedConfig, ...commonConfigs]
|
|
106
|
-
const uniqueConfigDirs = [...new Set(configDirs)]
|
|
107
|
-
|
|
108
|
-
return [join(BUILD_DIR, executableName), ...uniqueConfigDirs.map(dir => join(BUILD_DIR, dir, executableName))]
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function findBuiltExecutable(config?: string) {
|
|
112
|
-
const projectName = getProjectName()
|
|
113
|
-
if (!projectName) {
|
|
114
|
-
return null
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
for (const candidate of getCandidateExecutablePaths(config)) {
|
|
118
|
-
if (existsSync(candidate)) {
|
|
119
|
-
return candidate
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (!existsSync(BUILD_DIR)) {
|
|
124
|
-
return null
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const topLevelEntries = readdirSync(BUILD_DIR, { withFileTypes: true })
|
|
128
|
-
for (const entry of topLevelEntries) {
|
|
129
|
-
if (!entry.isDirectory()) {
|
|
130
|
-
continue
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const executableName = IS_WINDOWS ? `${projectName}.exe` : projectName
|
|
134
|
-
const candidate = join(BUILD_DIR, entry.name, executableName)
|
|
135
|
-
if (existsSync(candidate)) {
|
|
136
|
-
return candidate
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return null
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
async function runBuiltApp(config?: string) {
|
|
144
|
-
const executablePath = findBuiltExecutable(config)
|
|
145
|
-
|
|
146
|
-
if (!executablePath) {
|
|
147
|
-
printError("Built executable not found. Run `bun manager.ts build` first.")
|
|
148
|
-
return false
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
print(`Running ${executablePath} ...`)
|
|
152
|
-
return runCommand(executablePath, [], ROOT_DIR)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
function clean() {
|
|
156
|
-
if (!existsSync(BUILD_DIR)) {
|
|
157
|
-
print("Build directory does not exist. Nothing to clean.")
|
|
158
|
-
return true
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
rmSync(BUILD_DIR, { recursive: true, force: true })
|
|
162
|
-
print("Removed build directory.")
|
|
163
|
-
return true
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function doctor() {
|
|
167
|
-
print("Checking project structure...")
|
|
168
|
-
|
|
169
|
-
const requiredPaths = ["CMakeLists.txt", "src/main.cpp", "src/example.cpp", "include/example.hpp"]
|
|
170
|
-
let ok = true
|
|
171
|
-
|
|
172
|
-
for (const requiredPath of requiredPaths) {
|
|
173
|
-
if (!existsSync(join(ROOT_DIR, requiredPath))) {
|
|
174
|
-
printError(`Missing required file: ${requiredPath}`)
|
|
175
|
-
ok = false
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
if (!getProjectName()) {
|
|
180
|
-
printError("Could not determine the project name from CMakeLists.txt")
|
|
181
|
-
ok = false
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return ok
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
function printHelp() {
|
|
188
|
-
print("CMake C++ manager")
|
|
189
|
-
print("")
|
|
190
|
-
print("Usage:")
|
|
191
|
-
print(" bun manager.ts <command> [--config Debug]")
|
|
192
|
-
print("")
|
|
193
|
-
print("Commands:")
|
|
194
|
-
print(" help Show this help message")
|
|
195
|
-
print(" doctor Check whether required files exist")
|
|
196
|
-
print(" configure Run `cmake -S . -B build`")
|
|
197
|
-
print(" build Configure if needed, then build the project")
|
|
198
|
-
print(" run Run the built executable")
|
|
199
|
-
print(" dev Configure, build, and run the project")
|
|
200
|
-
print(" rebuild Remove build directory, then configure and build again")
|
|
201
|
-
print(" clean Remove the build directory")
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
async function main() {
|
|
205
|
-
const { command, options } = parseArgs(process.argv.slice(2))
|
|
206
|
-
const validCommands: CommandName[] = ["help", "doctor", "configure", "build", "run", "dev", "rebuild", "clean"]
|
|
207
|
-
|
|
208
|
-
if (!validCommands.includes(command)) {
|
|
209
|
-
printError(`Unknown command: ${command}`)
|
|
210
|
-
printHelp()
|
|
211
|
-
process.exit(1)
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
if (command === "help") {
|
|
215
|
-
printHelp()
|
|
216
|
-
return
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
if (command === "doctor") {
|
|
220
|
-
const ok = doctor()
|
|
221
|
-
process.exit(ok ? 0 : 1)
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
if (command === "clean") {
|
|
225
|
-
const ok = clean()
|
|
226
|
-
process.exit(ok ? 0 : 1)
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
if (!doctor()) {
|
|
230
|
-
process.exit(1)
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
if (!(await ensureCmakeAvailable())) {
|
|
234
|
-
process.exit(1)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
if (command === "configure") {
|
|
238
|
-
process.exit((await configure()) ? 0 : 1)
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (command === "build") {
|
|
242
|
-
if (!existsSync(BUILD_DIR) && !(await configure())) {
|
|
243
|
-
process.exit(1)
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
process.exit((await build(options.config)) ? 0 : 1)
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
if (command === "run") {
|
|
250
|
-
process.exit((await runBuiltApp(options.config)) ? 0 : 1)
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
if (command === "dev") {
|
|
254
|
-
if (!(await configure())) {
|
|
255
|
-
process.exit(1)
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
if (!(await build(options.config))) {
|
|
259
|
-
process.exit(1)
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
process.exit((await runBuiltApp(options.config)) ? 0 : 1)
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if (command === "rebuild") {
|
|
266
|
-
clean()
|
|
267
|
-
|
|
268
|
-
if (!(await configure())) {
|
|
269
|
-
process.exit(1)
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
process.exit((await build(options.config)) ? 0 : 1)
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
await main()
|
|
1
|
+
import { existsSync, readdirSync, readFileSync, rmSync } from "node:fs"
|
|
2
|
+
import { join } from "node:path"
|
|
3
|
+
import { platform } from "node:os"
|
|
4
|
+
import { spawn } from "node:child_process"
|
|
5
|
+
|
|
6
|
+
type CommandName = "help" | "doctor" | "configure" | "build" | "run" | "dev" | "rebuild" | "clean"
|
|
7
|
+
|
|
8
|
+
type ManagerOptions = {
|
|
9
|
+
config?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const ROOT_DIR = process.cwd()
|
|
13
|
+
const BUILD_DIR = join(ROOT_DIR, "build")
|
|
14
|
+
const IS_WINDOWS = platform() === "win32"
|
|
15
|
+
|
|
16
|
+
function print(message: string) {
|
|
17
|
+
process.stdout.write(`${message}\n`)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function printError(message: string) {
|
|
21
|
+
process.stderr.write(`${message}\n`)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getProjectName() {
|
|
25
|
+
const cmakeListsPath = join(ROOT_DIR, "CMakeLists.txt")
|
|
26
|
+
|
|
27
|
+
if (!existsSync(cmakeListsPath)) {
|
|
28
|
+
return null
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const cmakeListsContent = readFileSync(cmakeListsPath, "utf-8")
|
|
32
|
+
const match = cmakeListsContent.match(/project\s*\(\s*(?:"([^"]+)"|([^\s\)]+))/i)
|
|
33
|
+
|
|
34
|
+
return match?.[1] ?? match?.[2] ?? null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function parseArgs(argv: string[]) {
|
|
38
|
+
const [commandArg, ...rest] = argv
|
|
39
|
+
const command = (commandArg ?? "help") as CommandName
|
|
40
|
+
const options: ManagerOptions = {}
|
|
41
|
+
|
|
42
|
+
for (let index = 0; index < rest.length; index += 1) {
|
|
43
|
+
const arg = rest[index]
|
|
44
|
+
|
|
45
|
+
if ((arg === "--config" || arg === "-c") && rest[index + 1]) {
|
|
46
|
+
options.config = rest[index + 1]
|
|
47
|
+
index += 1
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return { command, options }
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function runCommand(command: string, args: string[], cwd = ROOT_DIR) {
|
|
55
|
+
return new Promise<boolean>(resolve => {
|
|
56
|
+
const child = spawn(command, args, {
|
|
57
|
+
cwd,
|
|
58
|
+
stdio: "inherit",
|
|
59
|
+
shell: false,
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
child.on("close", code => {
|
|
63
|
+
resolve(code === 0)
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
child.on("error", () => {
|
|
67
|
+
resolve(false)
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function ensureCmakeAvailable() {
|
|
73
|
+
const ok = await runCommand("cmake", ["--version"])
|
|
74
|
+
if (!ok) {
|
|
75
|
+
printError("CMake not found. Install CMake and ensure it is available in PATH.")
|
|
76
|
+
}
|
|
77
|
+
return ok
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function configure() {
|
|
81
|
+
print("Configuring project with CMake...")
|
|
82
|
+
return runCommand("cmake", ["-S", ".", "-B", "build"])
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function build(config?: string) {
|
|
86
|
+
print("Building project...")
|
|
87
|
+
const args = ["--build", "build"]
|
|
88
|
+
|
|
89
|
+
if (config) {
|
|
90
|
+
args.push("--config", config)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return runCommand("cmake", args)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function getCandidateExecutablePaths(config?: string) {
|
|
97
|
+
const projectName = getProjectName()
|
|
98
|
+
if (!projectName) {
|
|
99
|
+
return []
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const executableName = IS_WINDOWS ? `${projectName}.exe` : projectName
|
|
103
|
+
const requestedConfig = config ? [config] : []
|
|
104
|
+
const commonConfigs = ["Debug", "Release", "RelWithDebInfo", "MinSizeRel"]
|
|
105
|
+
const configDirs = [...requestedConfig, ...commonConfigs]
|
|
106
|
+
const uniqueConfigDirs = [...new Set(configDirs)]
|
|
107
|
+
|
|
108
|
+
return [join(BUILD_DIR, executableName), ...uniqueConfigDirs.map(dir => join(BUILD_DIR, dir, executableName))]
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function findBuiltExecutable(config?: string) {
|
|
112
|
+
const projectName = getProjectName()
|
|
113
|
+
if (!projectName) {
|
|
114
|
+
return null
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
for (const candidate of getCandidateExecutablePaths(config)) {
|
|
118
|
+
if (existsSync(candidate)) {
|
|
119
|
+
return candidate
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (!existsSync(BUILD_DIR)) {
|
|
124
|
+
return null
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const topLevelEntries = readdirSync(BUILD_DIR, { withFileTypes: true })
|
|
128
|
+
for (const entry of topLevelEntries) {
|
|
129
|
+
if (!entry.isDirectory()) {
|
|
130
|
+
continue
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const executableName = IS_WINDOWS ? `${projectName}.exe` : projectName
|
|
134
|
+
const candidate = join(BUILD_DIR, entry.name, executableName)
|
|
135
|
+
if (existsSync(candidate)) {
|
|
136
|
+
return candidate
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return null
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async function runBuiltApp(config?: string) {
|
|
144
|
+
const executablePath = findBuiltExecutable(config)
|
|
145
|
+
|
|
146
|
+
if (!executablePath) {
|
|
147
|
+
printError("Built executable not found. Run `bun manager.ts build` first.")
|
|
148
|
+
return false
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
print(`Running ${executablePath} ...`)
|
|
152
|
+
return runCommand(executablePath, [], ROOT_DIR)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function clean() {
|
|
156
|
+
if (!existsSync(BUILD_DIR)) {
|
|
157
|
+
print("Build directory does not exist. Nothing to clean.")
|
|
158
|
+
return true
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
rmSync(BUILD_DIR, { recursive: true, force: true })
|
|
162
|
+
print("Removed build directory.")
|
|
163
|
+
return true
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function doctor() {
|
|
167
|
+
print("Checking project structure...")
|
|
168
|
+
|
|
169
|
+
const requiredPaths = ["CMakeLists.txt", "src/main.cpp", "src/example.cpp", "include/example.hpp"]
|
|
170
|
+
let ok = true
|
|
171
|
+
|
|
172
|
+
for (const requiredPath of requiredPaths) {
|
|
173
|
+
if (!existsSync(join(ROOT_DIR, requiredPath))) {
|
|
174
|
+
printError(`Missing required file: ${requiredPath}`)
|
|
175
|
+
ok = false
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (!getProjectName()) {
|
|
180
|
+
printError("Could not determine the project name from CMakeLists.txt")
|
|
181
|
+
ok = false
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return ok
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function printHelp() {
|
|
188
|
+
print("CMake C++ manager")
|
|
189
|
+
print("")
|
|
190
|
+
print("Usage:")
|
|
191
|
+
print(" bun manager.ts <command> [--config Debug]")
|
|
192
|
+
print("")
|
|
193
|
+
print("Commands:")
|
|
194
|
+
print(" help Show this help message")
|
|
195
|
+
print(" doctor Check whether required files exist")
|
|
196
|
+
print(" configure Run `cmake -S . -B build`")
|
|
197
|
+
print(" build Configure if needed, then build the project")
|
|
198
|
+
print(" run Run the built executable")
|
|
199
|
+
print(" dev Configure, build, and run the project")
|
|
200
|
+
print(" rebuild Remove build directory, then configure and build again")
|
|
201
|
+
print(" clean Remove the build directory")
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async function main() {
|
|
205
|
+
const { command, options } = parseArgs(process.argv.slice(2))
|
|
206
|
+
const validCommands: CommandName[] = ["help", "doctor", "configure", "build", "run", "dev", "rebuild", "clean"]
|
|
207
|
+
|
|
208
|
+
if (!validCommands.includes(command)) {
|
|
209
|
+
printError(`Unknown command: ${command}`)
|
|
210
|
+
printHelp()
|
|
211
|
+
process.exit(1)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (command === "help") {
|
|
215
|
+
printHelp()
|
|
216
|
+
return
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (command === "doctor") {
|
|
220
|
+
const ok = doctor()
|
|
221
|
+
process.exit(ok ? 0 : 1)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (command === "clean") {
|
|
225
|
+
const ok = clean()
|
|
226
|
+
process.exit(ok ? 0 : 1)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (!doctor()) {
|
|
230
|
+
process.exit(1)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (!(await ensureCmakeAvailable())) {
|
|
234
|
+
process.exit(1)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (command === "configure") {
|
|
238
|
+
process.exit((await configure()) ? 0 : 1)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (command === "build") {
|
|
242
|
+
if (!existsSync(BUILD_DIR) && !(await configure())) {
|
|
243
|
+
process.exit(1)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
process.exit((await build(options.config)) ? 0 : 1)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (command === "run") {
|
|
250
|
+
process.exit((await runBuiltApp(options.config)) ? 0 : 1)
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (command === "dev") {
|
|
254
|
+
if (!(await configure())) {
|
|
255
|
+
process.exit(1)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (!(await build(options.config))) {
|
|
259
|
+
process.exit(1)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
process.exit((await runBuiltApp(options.config)) ? 0 : 1)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (command === "rebuild") {
|
|
266
|
+
clean()
|
|
267
|
+
|
|
268
|
+
if (!(await configure())) {
|
|
269
|
+
process.exit(1)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
process.exit((await build(options.config)) ? 0 : 1)
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
await main()
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
{
|
|
2
|
-
"semi": false,
|
|
3
|
-
"trailingComma": "all",
|
|
4
|
-
"singleQuote": false,
|
|
5
|
-
"printWidth": 120,
|
|
6
|
-
"tabWidth": 2,
|
|
7
|
-
"useTabs": false,
|
|
8
|
-
"jsxSingleQuote": false,
|
|
9
|
-
"jsxBracketSameLine": false,
|
|
10
|
-
"arrowParens": "avoid",
|
|
11
|
-
"plugins": ["prettier-plugin-tailwindcss"]
|
|
12
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"semi": false,
|
|
3
|
+
"trailingComma": "all",
|
|
4
|
+
"singleQuote": false,
|
|
5
|
+
"printWidth": 120,
|
|
6
|
+
"tabWidth": 2,
|
|
7
|
+
"useTabs": false,
|
|
8
|
+
"jsxSingleQuote": false,
|
|
9
|
+
"jsxBracketSameLine": false,
|
|
10
|
+
"arrowParens": "avoid",
|
|
11
|
+
"plugins": ["prettier-plugin-tailwindcss"]
|
|
12
|
+
}
|