Skip to content

Commit a27ec78

Browse files
committed
refactor: clean up init script utils
1 parent c67b929 commit a27ec78

18 files changed

Lines changed: 499 additions & 115 deletions

.changeset/sixty-roses-learn.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'create-solana-dapp': patch
3+
---
4+
5+
clean up init script utils
Lines changed: 14 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,41 @@
11
import { log } from '@clack/prompts'
2-
import { join } from 'node:path'
3-
import { ensureTargetPath } from './ensure-target-path'
42
import { GetArgsResult } from './get-args-result'
5-
import { deleteInitScript, getInitScript, InitScript } from './get-init-script'
63
import { getPackageJson } from './get-package-json'
4+
import { initScriptDelete } from './init-script-delete'
5+
import { initScriptInstructions } from './init-script-instructions'
6+
import { initScriptKey } from './init-script-key'
7+
import { initScriptRename } from './init-script-rename'
78
import { initScriptVersion } from './init-script-version'
8-
import { searchAndReplace } from './search-and-replace'
99
import { Task, taskFail } from './vendor/clack-tasks'
10-
import { namesValues } from './vendor/names'
1110

1211
export function createAppTaskRunInitScript(args: GetArgsResult): Task {
1312
return {
1413
enabled: !args.skipInit,
1514
title: 'Running init script',
1615
task: async (result) => {
1716
try {
18-
const init = getInitScript(args.targetDirectory)
17+
const { contents } = getPackageJson(args.targetDirectory)
18+
const init = contents[initScriptKey]
1919
if (!init) {
20-
return result({ message: 'Repository does not have an init script' })
20+
return result({ message: 'Init script not found' })
2121
}
2222
if (args.verbose) {
23-
log.warn(`Running init script`)
23+
log.warn(`Init script started`)
2424
}
2525

2626
await initScriptVersion(init.versions, args.verbose)
27-
if (args.verbose) {
28-
log.warn(`initCheckVersion done`)
29-
}
30-
await initRename(args, init, args.verbose)
31-
if (args.verbose) {
32-
log.warn(`initRename done`)
33-
}
3427

35-
const instructions: string[] = (initInstructions(init) ?? [])
28+
await initScriptRename(args, init.rename, args.verbose)
29+
30+
const instructions: string[] = initScriptInstructions(init.instructions, args.verbose)
3631
?.filter(Boolean)
3732
.map((msg) => msg.replace('{pm}', args.packageManager))
3833

39-
if (args.verbose) {
40-
log.warn(`initInstructions done`)
41-
}
42-
deleteInitScript(args.targetDirectory)
43-
if (args.verbose) {
44-
log.warn(`deleteInitScript done`)
45-
}
46-
return result({ message: 'Executed init script', instructions })
34+
initScriptDelete(args)
35+
return result({ message: 'Init script done', instructions })
4736
} catch (error) {
48-
taskFail(`init: Error running init script: ${error}`)
37+
taskFail(`Error running init script: ${error}`)
4938
}
5039
},
5140
}
5241
}
53-
54-
async function initRename(args: GetArgsResult, init: InitScript, verbose: boolean) {
55-
const { contents } = getPackageJson(args.targetDirectory)
56-
// Rename template from package.json to project name throughout the whole project
57-
if (contents.name) {
58-
await searchAndReplace(args.targetDirectory, [contents.name], [args.name], false, verbose)
59-
}
60-
61-
// Return early if there are no renames defined in the init script
62-
if (!init?.rename) {
63-
return
64-
}
65-
66-
// Loop through each word in the rename object
67-
for (const from of Object.keys(init.rename)) {
68-
// Get the 'to' property from the rename object
69-
const to = init.rename[from].to.replace('{{name}}', args.name.replace(/-/g, ''))
70-
71-
// Get the name matrix for the 'from' and the 'to' value
72-
const fromNames = namesValues(from)
73-
const toNames = namesValues(to)
74-
75-
for (const path of init.rename[from].paths) {
76-
const targetPath = join(args.targetDirectory, path)
77-
if (!(await ensureTargetPath(targetPath))) {
78-
console.error(`init-script.rename: target does not exist ${targetPath}`)
79-
continue
80-
}
81-
await searchAndReplace(join(args.targetDirectory, path), fromNames, toNames, args.dryRun)
82-
}
83-
}
84-
}
85-
86-
function initInstructions(init: InitScript) {
87-
return init?.instructions?.length === 0 ? [] : init?.instructions
88-
}

src/utils/create-app.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export async function createApp(args: GetArgsResult) {
1111
createAppTaskCloneTemplate(args),
1212
// Install the dependencies
1313
createAppTaskInstallDependencies(args),
14-
// Run the init script define in package.json .init property
14+
// Run the (optional) init script defined in package.json
1515
createAppTaskRunInitScript(args),
1616
// Initialize git repository
1717
createAppTaskInitializeGit(args),

src/utils/get-init-script.ts

Lines changed: 0 additions & 51 deletions
This file was deleted.

src/utils/get-package-json.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { existsSync, readFileSync } from 'node:fs'
22
import { z } from 'zod'
33
import { getPackageJsonPath } from './get-package-json-path'
4+
import { initScriptKey } from './init-script-key'
5+
import { InitScriptSchema } from './init-script-schema'
46

57
export function getPackageJson(targetDirectory: string): { path: string; contents: PackageJson } {
68
const path = getPackageJsonPath(targetDirectory)
@@ -26,6 +28,7 @@ const PackageJsonSchema = z
2628
.object({
2729
name: z.string().optional(),
2830
scripts: z.record(z.string()).optional(),
31+
[initScriptKey]: InitScriptSchema.optional(),
2932
})
3033
.passthrough()
3134

src/utils/init-script-delete.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { writeFileSync } from 'node:fs'
2+
import { GetArgsResult } from './get-args-result'
3+
import { getPackageJson } from './get-package-json'
4+
import { initScriptKey } from './init-script-key'
5+
6+
export function initScriptDelete(args: GetArgsResult) {
7+
const tag = `initScriptDelete`
8+
const { path, contents } = getPackageJson(args.targetDirectory)
9+
delete contents[initScriptKey]
10+
writeFileSync(path, JSON.stringify(contents, undefined, 2) + '\n')
11+
if (args.verbose) {
12+
console.log(`${tag}: deleted ${initScriptKey} from package.json`)
13+
}
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { InitScriptInstructions } from './init-script-schema-instructions'
2+
3+
export function initScriptInstructions(instructions?: InitScriptInstructions, verbose = false): string[] {
4+
const tag = `initScriptInstructions`
5+
if (!instructions || instructions.length === 0) {
6+
if (verbose) {
7+
console.log(`${tag}: no instructions found`)
8+
}
9+
return []
10+
}
11+
if (verbose) {
12+
console.log(`${tag}: ${instructions.length} instructions found`)
13+
}
14+
return instructions
15+
}

src/utils/init-script-key.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const initScriptKey = 'create-solana-dapp'

src/utils/init-script-rename.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { log } from '@clack/prompts'
2+
import { join } from 'node:path'
3+
import { ensureTargetPath } from './ensure-target-path'
4+
import { GetArgsResult } from './get-args-result'
5+
import { getPackageJson } from './get-package-json'
6+
import { InitScriptRename } from './init-script-schema-rename'
7+
import { searchAndReplace } from './search-and-replace'
8+
import { namesValues } from './vendor/names'
9+
10+
export async function initScriptRename(args: GetArgsResult, rename?: InitScriptRename, verbose = false) {
11+
const tag = `initScriptRename`
12+
const { contents } = getPackageJson(args.targetDirectory)
13+
// Rename template from package.json to project name throughout the whole project
14+
if (contents.name) {
15+
if (args.verbose) {
16+
log.warn(`${tag}: renaming template name '${contents.name}' to project name '${args.name}'`)
17+
}
18+
await searchAndReplace(args.targetDirectory, [contents.name], [args.name], false, verbose)
19+
}
20+
21+
// Return early if there are no renames defined in the init script
22+
if (!rename) {
23+
if (args.verbose) {
24+
log.warn(`${tag}: no renames found`)
25+
}
26+
return
27+
}
28+
29+
// Loop through each word in the rename object
30+
for (const from of Object.keys(rename)) {
31+
// Get the 'to' property from the rename object
32+
const to = rename[from].to.replace('{{name}}', args.name.replace(/-/g, ''))
33+
34+
// Get the name matrix for the 'from' and the 'to' value
35+
const fromNames = namesValues(from)
36+
const toNames = namesValues(to)
37+
38+
for (const path of rename[from].paths) {
39+
const targetPath = join(args.targetDirectory, path)
40+
if (!(await ensureTargetPath(targetPath))) {
41+
console.error(`${tag}: target does not exist ${targetPath}`)
42+
continue
43+
}
44+
if (args.verbose) {
45+
log.warn(`${tag}: ${targetPath} -> ${fromNames.join('|')} -> ${toNames.join('|')}`)
46+
}
47+
await searchAndReplace(targetPath, fromNames, toNames, args.dryRun, args.verbose)
48+
}
49+
}
50+
51+
if (args.verbose) {
52+
log.warn(`${tag}: done`)
53+
}
54+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { z } from 'zod'
2+
3+
export const InitScriptSchemaInstructions = z.array(z.string())
4+
5+
export type InitScriptInstructions = z.infer<typeof InitScriptSchemaInstructions>

0 commit comments

Comments
 (0)