@dimensional-innovations/tool-config 1.4.1 â 2.0.0
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 +72 -18
- package/bin/lib/ci-setup.js +142 -0
- package/bin/lib/handlers/eslint.js +61 -0
- package/bin/lib/handlers/prettier.js +83 -0
- package/bin/lib/handlers/semantic-release.js +60 -0
- package/bin/lib/handlers/stylelint.js +85 -0
- package/bin/lib/handlers/typescript.js +156 -0
- package/bin/lib/package-manager.js +114 -0
- package/bin/lib/ui.js +111 -0
- package/bin/lib/validators.js +28 -0
- package/bin/setup-tool-config.js +112 -596
- package/package.json +16 -4
- package/src/detectors.js +27 -2
- package/src/index.js +8 -3
- package/src/tools/typescript/README.md +665 -0
- package/src/tools/typescript/checker-detection.js +113 -0
- package/src/tools/typescript/index.js +202 -0
- package/src/tools/typescript/presets/base.js +58 -0
- package/src/tools/typescript/presets/environments/browser.js +10 -0
- package/src/tools/typescript/presets/environments/node.js +11 -0
- package/src/tools/typescript/presets/environments/universal.js +11 -0
- package/src/tools/typescript/presets/frameworks/angular.js +11 -0
- package/src/tools/typescript/presets/frameworks/astro.js +11 -0
- package/src/tools/typescript/presets/frameworks/electron.js +100 -0
- package/src/tools/typescript/presets/frameworks/node.js +12 -0
- package/src/tools/typescript/presets/frameworks/react.js +10 -0
- package/src/tools/typescript/presets/frameworks/solid.js +11 -0
- package/src/tools/typescript/presets/frameworks/svelte.js +10 -0
- package/src/tools/typescript/presets/frameworks/vanilla.js +9 -0
- package/src/tools/typescript/presets/frameworks/vue.js +17 -0
package/bin/setup-tool-config.js
CHANGED
|
@@ -3,485 +3,139 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* @dimensional-innovations/tool-config CLI Setup Tool
|
|
5
5
|
*
|
|
6
|
-
* Interactive configuration generator for ESLint, Prettier, Stylelint, and semantic-release
|
|
6
|
+
* Interactive configuration generator for ESLint, Prettier, Stylelint, TypeScript, and semantic-release
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { writeFileSync, existsSync, readFileSync, mkdirSync, copyFileSync } from 'fs'
|
|
10
|
-
import { join, dirname } from 'path'
|
|
11
|
-
import { fileURLToPath } from 'url'
|
|
12
|
-
|
|
13
9
|
import prompts from 'prompts'
|
|
14
10
|
|
|
15
11
|
import { autoDetect } from '../src/detectors.js'
|
|
16
|
-
import { prettierIgnoreContent } from '../src/tools/prettier/index.js'
|
|
17
|
-
|
|
18
|
-
const __filename = fileURLToPath(import.meta.url)
|
|
19
|
-
const __dirname = dirname(__filename)
|
|
20
|
-
|
|
21
|
-
const VERSION = '0.0.0-development'
|
|
22
|
-
|
|
23
|
-
// Parse CLI arguments
|
|
24
|
-
const args = process.argv.slice(2)
|
|
25
|
-
const flags = {
|
|
26
|
-
help: args.includes('--help') || args.includes('-h'),
|
|
27
|
-
version: args.includes('--version') || args.includes('-v'),
|
|
28
|
-
dryRun: args.includes('--dry-run') || args.includes('-d'),
|
|
29
|
-
all: args.includes('--all') || args.includes('-a'),
|
|
30
|
-
setupCI: args.includes('--setup-ci')
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Check for --ci flag with optional provider
|
|
34
|
-
const ciIndex = args.indexOf('--ci')
|
|
35
|
-
const ciProvider =
|
|
36
|
-
ciIndex !== -1 && args[ciIndex + 1] && !args[ciIndex + 1].startsWith('-')
|
|
37
|
-
? args[ciIndex + 1]
|
|
38
|
-
: null
|
|
39
|
-
const hasCI = args.includes('--ci')
|
|
40
|
-
|
|
41
|
-
// Single tool mode: setup-tool-config eslint (but not --ci provider value)
|
|
42
|
-
const singleTool = args.find(arg => !arg.startsWith('-') && arg !== ciProvider)
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Show help message
|
|
46
|
-
*/
|
|
47
|
-
function showHelp() {
|
|
48
|
-
console.log(`
|
|
49
|
-
đĻ @dimensional-innovations/tool-config Setup Tool
|
|
50
|
-
|
|
51
|
-
Usage:
|
|
52
|
-
setup-tool-config [tool] [options]
|
|
53
|
-
|
|
54
|
-
Tools:
|
|
55
|
-
eslint Setup ESLint only
|
|
56
|
-
prettier Setup Prettier only
|
|
57
|
-
stylelint Setup Stylelint only
|
|
58
|
-
semantic-release Setup semantic-release only
|
|
59
|
-
|
|
60
|
-
Options:
|
|
61
|
-
--all, -a Setup all tools (non-interactive)
|
|
62
|
-
--ci [provider] Setup CI/CD pipeline (gitlab, github, bitbucket)
|
|
63
|
-
--setup-ci Interactive CI/CD setup
|
|
64
|
-
--dry-run, -d Preview changes without writing files
|
|
65
|
-
--help, -h Show this help message
|
|
66
|
-
--version, -v Show version number
|
|
67
|
-
|
|
68
|
-
Examples:
|
|
69
|
-
setup-tool-config # Interactive mode
|
|
70
|
-
setup-tool-config eslint # Setup ESLint only
|
|
71
|
-
setup-tool-config --all # Setup all tools
|
|
72
|
-
setup-tool-config --dry-run # Preview without changes
|
|
73
|
-
setup-tool-config --ci gitlab # Setup GitLab CI/CD
|
|
74
|
-
setup-tool-config --ci github # Setup GitHub Actions
|
|
75
|
-
setup-tool-config --setup-ci # Interactive CI setup
|
|
76
|
-
setup-tool-config semantic-release --ci # Setup release + CI
|
|
77
|
-
|
|
78
|
-
For more information, visit:
|
|
79
|
-
https://gitlab.com/dimensional-innovations/tool-config
|
|
80
|
-
`)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Show version
|
|
85
|
-
*/
|
|
86
|
-
function showVersion() {
|
|
87
|
-
console.log(`@dimensional-innovations/tool-config v${VERSION}`)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Generate config file content for a tool
|
|
92
|
-
*/
|
|
93
|
-
function generateConfigContent(tool) {
|
|
94
|
-
const configs = {
|
|
95
|
-
eslint: `import { createConfig } from '@dimensional-innovations/tool-config'
|
|
96
|
-
|
|
97
|
-
export default await createConfig('eslint')
|
|
98
|
-
`,
|
|
99
|
-
prettier: `import { createConfig } from '@dimensional-innovations/tool-config'
|
|
100
|
-
|
|
101
|
-
export default createConfig('prettier')
|
|
102
|
-
`,
|
|
103
|
-
stylelint: `import { createConfig } from '@dimensional-innovations/tool-config'
|
|
104
|
-
|
|
105
|
-
export default createConfig('stylelint')
|
|
106
|
-
`,
|
|
107
|
-
'semantic-release': `import { createConfig } from '@dimensional-innovations/tool-config'
|
|
108
|
-
|
|
109
|
-
export default createConfig('semantic-release')
|
|
110
|
-
`
|
|
111
|
-
}
|
|
112
12
|
|
|
113
|
-
|
|
13
|
+
import { copyCITemplate } from './lib/ci-setup.js'
|
|
14
|
+
import * as eslintHandler from './lib/handlers/eslint.js'
|
|
15
|
+
import * as prettierHandler from './lib/handlers/prettier.js'
|
|
16
|
+
import * as semanticReleaseHandler from './lib/handlers/semantic-release.js'
|
|
17
|
+
import * as stylelintHandler from './lib/handlers/stylelint.js'
|
|
18
|
+
import * as typescriptHandler from './lib/handlers/typescript.js'
|
|
19
|
+
import { updatePackageJsonScripts } from './lib/package-manager.js'
|
|
20
|
+
import {
|
|
21
|
+
showBanner,
|
|
22
|
+
showCICompletion,
|
|
23
|
+
showCompletion,
|
|
24
|
+
showHelp,
|
|
25
|
+
showSection,
|
|
26
|
+
showVersion
|
|
27
|
+
} from './lib/ui.js'
|
|
28
|
+
import { VALID_TOOLS, validateProvider, validateTool } from './lib/validators.js'
|
|
29
|
+
|
|
30
|
+
// Tool handler registry
|
|
31
|
+
const TOOL_HANDLERS = {
|
|
32
|
+
eslint: eslintHandler,
|
|
33
|
+
prettier: prettierHandler,
|
|
34
|
+
stylelint: stylelintHandler,
|
|
35
|
+
typescript: typescriptHandler,
|
|
36
|
+
'semantic-release': semanticReleaseHandler
|
|
114
37
|
}
|
|
115
38
|
|
|
116
39
|
/**
|
|
117
|
-
* Get
|
|
40
|
+
* Get tool scripts (wrapper for handler getScripts)
|
|
118
41
|
*/
|
|
119
|
-
function
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
prettier: 'prettier.config.js',
|
|
123
|
-
stylelint: 'stylelint.config.js',
|
|
124
|
-
'semantic-release': 'release.config.js'
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return filenames[tool] || `${tool}.config.js`
|
|
42
|
+
function getToolScripts(tool, detected) {
|
|
43
|
+
const handler = TOOL_HANDLERS[tool]
|
|
44
|
+
return handler.getScripts ? handler.getScripts(detected) : {}
|
|
128
45
|
}
|
|
129
46
|
|
|
130
47
|
/**
|
|
131
|
-
*
|
|
132
|
-
* @param {string} framework - Detected framework
|
|
133
|
-
* @param {Object} cssType - CSS type detection results
|
|
134
|
-
* @returns {string[]} Array of file extensions
|
|
48
|
+
* Setup tools
|
|
135
49
|
*/
|
|
136
|
-
function
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
// Add preprocessor extensions
|
|
140
|
-
if (cssType.preprocessor === 'scss') {
|
|
141
|
-
extensions.push('scss')
|
|
142
|
-
} else if (cssType.preprocessor === 'less') {
|
|
143
|
-
extensions.push('less')
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Add framework-specific extensions
|
|
147
|
-
if (framework === 'vue') extensions.push('vue')
|
|
148
|
-
if (framework === 'svelte') extensions.push('svelte')
|
|
50
|
+
async function setupTools(tools, detected, cwd, dryRun = false) {
|
|
51
|
+
showSection('đ Generating configuration files...')
|
|
149
52
|
|
|
150
|
-
|
|
151
|
-
|
|
53
|
+
// Track which tools successfully created configs
|
|
54
|
+
const successfulTools = []
|
|
152
55
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
function getSmartScripts(tool, detected) {
|
|
160
|
-
switch (tool) {
|
|
161
|
-
case 'stylelint': {
|
|
162
|
-
const extensions = getStylelintExtensions(detected.framework, detected.cssType)
|
|
163
|
-
const pattern =
|
|
164
|
-
extensions.length === 1 ? `**/*.${extensions[0]}` : `**/*.{${extensions.join(',')}}`
|
|
165
|
-
|
|
166
|
-
return {
|
|
167
|
-
style: `stylelint "${pattern}"`,
|
|
168
|
-
'style:fix': `stylelint "${pattern}" --fix`
|
|
169
|
-
}
|
|
56
|
+
for (const tool of tools) {
|
|
57
|
+
console.log(`${tool}:`)
|
|
58
|
+
const handler = TOOL_HANDLERS[tool]
|
|
59
|
+
const success = await handler.writeConfig(cwd, detected, dryRun)
|
|
60
|
+
if (success) {
|
|
61
|
+
successfulTools.push(tool)
|
|
170
62
|
}
|
|
171
|
-
|
|
172
|
-
case 'eslint':
|
|
173
|
-
return {
|
|
174
|
-
lint: 'eslint .',
|
|
175
|
-
'lint:fix': 'eslint --fix .'
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
case 'prettier':
|
|
179
|
-
return {
|
|
180
|
-
'prettier:fix': 'prettier --write .',
|
|
181
|
-
prettier: 'prettier --check .'
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
case 'semantic-release':
|
|
185
|
-
return {
|
|
186
|
-
release: 'semantic-release'
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
default:
|
|
190
|
-
return {}
|
|
191
63
|
}
|
|
192
|
-
}
|
|
193
64
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
* @returns {Object} Tool-specific scripts
|
|
199
|
-
*/
|
|
200
|
-
function getToolScripts(tool, detected = null) {
|
|
201
|
-
// If no detection provided, use basic scripts
|
|
202
|
-
if (!detected) {
|
|
203
|
-
return (
|
|
204
|
-
{
|
|
205
|
-
eslint: {
|
|
206
|
-
lint: 'eslint .',
|
|
207
|
-
'lint:fix': 'eslint --fix .'
|
|
208
|
-
},
|
|
209
|
-
prettier: {
|
|
210
|
-
'prettier:fix': 'prettier --write .',
|
|
211
|
-
prettier: 'prettier --check .'
|
|
212
|
-
},
|
|
213
|
-
stylelint: {
|
|
214
|
-
style: 'stylelint "**/*.css"',
|
|
215
|
-
'style:fix': 'stylelint "**/*.css" --fix'
|
|
216
|
-
},
|
|
217
|
-
'semantic-release': {
|
|
218
|
-
release: 'semantic-release'
|
|
219
|
-
}
|
|
220
|
-
}[tool] || {}
|
|
221
|
-
)
|
|
65
|
+
// Only add scripts for tools that created configs
|
|
66
|
+
if (successfulTools.length > 0) {
|
|
67
|
+
showSection('đĻ Updating package.json scripts...')
|
|
68
|
+
updatePackageJsonScripts(successfulTools, getToolScripts, { detected, cwd, dryRun })
|
|
222
69
|
}
|
|
223
|
-
|
|
224
|
-
// Generate framework-aware scripts
|
|
225
|
-
return getSmartScripts(tool, detected)
|
|
226
70
|
}
|
|
227
71
|
|
|
228
72
|
/**
|
|
229
|
-
*
|
|
73
|
+
* Prompt for CI provider if not detected
|
|
230
74
|
*/
|
|
231
|
-
function
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
// Prettier also creates .prettierignore
|
|
245
|
-
if (tool === 'prettier') {
|
|
246
|
-
const ignoreFile = '.prettierignore'
|
|
247
|
-
const ignoreExists = existsSync(join(cwd, ignoreFile))
|
|
248
|
-
if (!ignoreExists) {
|
|
249
|
-
console.log(` đ Would create: ${ignoreFile}`)
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
return true
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
try {
|
|
257
|
-
writeFileSync(filepath, content, 'utf8')
|
|
258
|
-
console.log(` â
Created: ${filename}`)
|
|
259
|
-
|
|
260
|
-
// Prettier also creates .prettierignore
|
|
261
|
-
if (tool === 'prettier') {
|
|
262
|
-
const ignoreFile = '.prettierignore'
|
|
263
|
-
const ignorePath = join(cwd, ignoreFile)
|
|
264
|
-
|
|
265
|
-
if (!existsSync(ignorePath)) {
|
|
266
|
-
writeFileSync(ignorePath, prettierIgnoreContent, 'utf8')
|
|
267
|
-
console.log(` â
Created: ${ignoreFile}`)
|
|
268
|
-
} else {
|
|
269
|
-
console.log(` â ī¸ ${ignoreFile} already exists - skipping`)
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return true
|
|
274
|
-
} catch (error) {
|
|
275
|
-
console.error(` â Failed to create ${filename}:`, error.message)
|
|
276
|
-
return false
|
|
277
|
-
}
|
|
75
|
+
async function promptForProvider() {
|
|
76
|
+
const providerResponse = await prompts({
|
|
77
|
+
type: 'select',
|
|
78
|
+
name: 'provider',
|
|
79
|
+
message: 'Which CI/CD platform would you like to use?',
|
|
80
|
+
choices: [
|
|
81
|
+
{ title: 'GitLab CI', value: 'gitlab' },
|
|
82
|
+
{ title: 'GitHub Actions', value: 'github' },
|
|
83
|
+
{ title: 'Bitbucket Pipelines', value: 'bitbucket' }
|
|
84
|
+
]
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
return providerResponse.provider
|
|
278
88
|
}
|
|
279
89
|
|
|
280
90
|
/**
|
|
281
|
-
*
|
|
91
|
+
* Setup CI/CD pipeline
|
|
282
92
|
*/
|
|
283
|
-
function
|
|
284
|
-
|
|
93
|
+
async function setupCI(detected, cwd, dryRun, ciProvider = null) {
|
|
94
|
+
showSection('đ CI/CD Pipeline Setup')
|
|
285
95
|
|
|
286
|
-
|
|
287
|
-
console.log(' â ī¸ No package.json found - skipping script injection')
|
|
288
|
-
return
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
try {
|
|
292
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'))
|
|
96
|
+
let provider = ciProvider || detected.gitProvider
|
|
293
97
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
const toolScripts = getToolScripts(tool, detected)
|
|
301
|
-
for (const [name, command] of Object.entries(toolScripts)) {
|
|
302
|
-
if (!packageJson.scripts[name]) {
|
|
303
|
-
scriptsToAdd[name] = command
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
if (Object.keys(scriptsToAdd).length === 0) {
|
|
309
|
-
console.log(' âšī¸ All scripts already exist in package.json')
|
|
310
|
-
return
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
if (dryRun) {
|
|
314
|
-
console.log(' đ Would add scripts to package.json:')
|
|
315
|
-
for (const [name, command] of Object.entries(scriptsToAdd)) {
|
|
316
|
-
console.log(` "${name}": "${command}"`)
|
|
317
|
-
}
|
|
98
|
+
// If provider not detected or unknown, prompt for it
|
|
99
|
+
if (!provider || provider === 'unknown') {
|
|
100
|
+
provider = await promptForProvider()
|
|
101
|
+
if (!provider) {
|
|
102
|
+
console.log('â ī¸ Skipping CI/CD setup.')
|
|
103
|
+
console.log('')
|
|
318
104
|
return
|
|
319
105
|
}
|
|
320
|
-
|
|
321
|
-
Object.assign(packageJson.scripts, scriptsToAdd)
|
|
322
|
-
|
|
323
|
-
writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`, 'utf8')
|
|
324
|
-
|
|
325
|
-
console.log(' â
Updated package.json with scripts:')
|
|
326
|
-
for (const name of Object.keys(scriptsToAdd)) {
|
|
327
|
-
console.log(` - ${name}`)
|
|
328
|
-
}
|
|
329
|
-
} catch (error) {
|
|
330
|
-
console.error(' â Failed to update package.json:', error.message)
|
|
331
106
|
}
|
|
332
|
-
}
|
|
333
107
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
const ciFiles = {
|
|
339
|
-
gitlab: {
|
|
340
|
-
filename: '.gitlab-ci.yml',
|
|
341
|
-
destination: '.gitlab-ci.yml',
|
|
342
|
-
template: '.gitlab-ci.yml'
|
|
343
|
-
},
|
|
344
|
-
github: {
|
|
345
|
-
filename: 'ci.yml',
|
|
346
|
-
destination: '.github/workflows/ci.yml',
|
|
347
|
-
template: 'github-workflow.yml',
|
|
348
|
-
needsDir: true
|
|
349
|
-
},
|
|
350
|
-
bitbucket: {
|
|
351
|
-
filename: 'bitbucket-pipelines.yml',
|
|
352
|
-
destination: 'bitbucket-pipelines.yml',
|
|
353
|
-
template: 'bitbucket-pipelines.yml'
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
return ciFiles[provider] || null
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
/**
|
|
361
|
-
* Get environment variable instructions for a git provider
|
|
362
|
-
*/
|
|
363
|
-
function getCIInstructions(provider) {
|
|
364
|
-
const instructions = {
|
|
365
|
-
gitlab: `
|
|
366
|
-
â ī¸ Configuration Required:
|
|
367
|
-
Add these CI/CD variables in GitLab Settings > CI/CD > Variables:
|
|
368
|
-
- GL_TOKEN: GitLab Personal Access Token (with api scope)
|
|
369
|
-
- NPM_TOKEN: npm authentication token
|
|
370
|
-
|
|
371
|
-
Then push to main branch to trigger automated releases.`,
|
|
372
|
-
github: `
|
|
373
|
-
â ī¸ Configuration Required:
|
|
374
|
-
Add these secrets in GitHub Settings > Secrets and variables > Actions:
|
|
375
|
-
- GITHUB_TOKEN: Automatically provided by GitHub Actions
|
|
376
|
-
- NPM_TOKEN: npm authentication token
|
|
377
|
-
|
|
378
|
-
Then push to main branch to trigger automated releases.`,
|
|
379
|
-
bitbucket: `
|
|
380
|
-
â ī¸ Configuration Required:
|
|
381
|
-
Add this repository variable in Bitbucket Settings > Pipelines > Repository variables:
|
|
382
|
-
- NPM_TOKEN: npm authentication token
|
|
383
|
-
|
|
384
|
-
Then push to main branch to trigger automated releases.`
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
return instructions[provider] || ''
|
|
108
|
+
console.log('đ Setting up CI/CD...')
|
|
109
|
+
console.log('')
|
|
110
|
+
copyCITemplate(provider, cwd, dryRun)
|
|
111
|
+
showCICompletion(dryRun)
|
|
388
112
|
}
|
|
389
113
|
|
|
390
114
|
/**
|
|
391
|
-
*
|
|
115
|
+
* Main CLI function
|
|
392
116
|
*/
|
|
393
|
-
function
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
)
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
const ciInfo = getCIFileInfo(provider)
|
|
404
|
-
|
|
405
|
-
if (!ciInfo) {
|
|
406
|
-
console.log(` â ī¸ Unsupported git provider: ${provider}`)
|
|
407
|
-
return false
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
const destPath = join(cwd, ciInfo.destination)
|
|
411
|
-
const destDir = dirname(destPath)
|
|
412
|
-
|
|
413
|
-
// Check if CI file already exists
|
|
414
|
-
if (existsSync(destPath)) {
|
|
415
|
-
console.log(` â ī¸ ${ciInfo.destination} already exists - skipping`)
|
|
416
|
-
return false
|
|
117
|
+
async function main() {
|
|
118
|
+
// Parse CLI arguments
|
|
119
|
+
const args = process.argv.slice(2)
|
|
120
|
+
const flags = {
|
|
121
|
+
help: args.includes('--help') || args.includes('-h'),
|
|
122
|
+
version: args.includes('--version') || args.includes('-v'),
|
|
123
|
+
dryRun: args.includes('--dry-run') || args.includes('-d'),
|
|
124
|
+
all: args.includes('--all') || args.includes('-a'),
|
|
125
|
+
setupCI: args.includes('--setup-ci')
|
|
417
126
|
}
|
|
418
127
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
128
|
+
// Check for --ci flag with optional provider
|
|
129
|
+
const ciIndex = args.indexOf('--ci')
|
|
130
|
+
const ciProvider =
|
|
131
|
+
ciIndex !== -1 && args[ciIndex + 1] && !args[ciIndex + 1].startsWith('-')
|
|
132
|
+
? args[ciIndex + 1]
|
|
133
|
+
: null
|
|
134
|
+
const hasCI = args.includes('--ci')
|
|
426
135
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
if (ciInfo.needsDir && !existsSync(destDir)) {
|
|
430
|
-
mkdirSync(destDir, { recursive: true })
|
|
431
|
-
console.log(` â
Created directory: ${dirname(ciInfo.destination)}`)
|
|
432
|
-
}
|
|
136
|
+
// Single tool mode: setup-tool-config eslint (but not --ci provider value)
|
|
137
|
+
const singleTool = args.find(arg => !arg.startsWith('-') && arg !== ciProvider)
|
|
433
138
|
|
|
434
|
-
// Copy template
|
|
435
|
-
const templatePath = join(
|
|
436
|
-
__dirname,
|
|
437
|
-
'..',
|
|
438
|
-
'src',
|
|
439
|
-
'tools',
|
|
440
|
-
'semantic-release',
|
|
441
|
-
'templates',
|
|
442
|
-
ciInfo.template
|
|
443
|
-
)
|
|
444
|
-
copyFileSync(templatePath, destPath)
|
|
445
|
-
console.log(` â
Created: ${ciInfo.destination}`)
|
|
446
|
-
|
|
447
|
-
// Show configuration instructions
|
|
448
|
-
console.log(getCIInstructions(provider))
|
|
449
|
-
|
|
450
|
-
console.log('\n đ For more details, see:')
|
|
451
|
-
console.log(
|
|
452
|
-
' node_modules/@dimensional-innovations/tool-config/src/tools/semantic-release/CI_SETUP.md'
|
|
453
|
-
)
|
|
454
|
-
|
|
455
|
-
return true
|
|
456
|
-
} catch (error) {
|
|
457
|
-
console.error(` â Failed to copy CI template:`, error.message)
|
|
458
|
-
return false
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
/**
|
|
463
|
-
* Setup tools
|
|
464
|
-
*/
|
|
465
|
-
function setupTools(tools, detected, cwd, dryRun = false) {
|
|
466
|
-
console.log('')
|
|
467
|
-
console.log('đ Generating configuration files...')
|
|
468
|
-
console.log('')
|
|
469
|
-
|
|
470
|
-
for (const tool of tools) {
|
|
471
|
-
console.log(`${tool}:`)
|
|
472
|
-
writeConfigFile(tool, cwd, dryRun)
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
console.log('')
|
|
476
|
-
console.log('đĻ Updating package.json scripts...')
|
|
477
|
-
console.log('')
|
|
478
|
-
updatePackageJsonScripts(tools, detected, cwd, dryRun)
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
/**
|
|
482
|
-
* Main CLI function
|
|
483
|
-
*/
|
|
484
|
-
async function main() {
|
|
485
139
|
// Handle flags
|
|
486
140
|
if (flags.help) {
|
|
487
141
|
showHelp()
|
|
@@ -495,159 +149,41 @@ async function main() {
|
|
|
495
149
|
|
|
496
150
|
const cwd = process.cwd()
|
|
497
151
|
|
|
498
|
-
// Show banner
|
|
499
|
-
console.log('')
|
|
500
|
-
console.log('đĻ @dimensional-innovations/tool-config Setup')
|
|
501
|
-
console.log('â'.repeat(50))
|
|
502
|
-
console.log('')
|
|
503
|
-
|
|
504
|
-
// Auto-detect project
|
|
152
|
+
// Show banner and auto-detect
|
|
505
153
|
const detected = autoDetect(cwd)
|
|
506
|
-
|
|
507
|
-
console.log(` Framework: ${detected.framework}`)
|
|
508
|
-
console.log(` Environment: ${detected.environment}`)
|
|
509
|
-
console.log(` TypeScript: ${detected.typescript ? 'Yes' : 'No'}`)
|
|
510
|
-
console.log(` Git Provider: ${detected.gitProvider || 'Unknown'}`)
|
|
511
|
-
console.log('')
|
|
154
|
+
showBanner(detected)
|
|
512
155
|
|
|
513
156
|
// Handle standalone --setup-ci flag
|
|
514
157
|
if (flags.setupCI) {
|
|
515
|
-
|
|
516
|
-
console.log('')
|
|
517
|
-
|
|
518
|
-
let provider = detected.gitProvider
|
|
519
|
-
|
|
520
|
-
// If provider not detected or unknown, prompt for it
|
|
521
|
-
if (!provider || provider === 'unknown') {
|
|
522
|
-
const providerResponse = await prompts({
|
|
523
|
-
type: 'select',
|
|
524
|
-
name: 'provider',
|
|
525
|
-
message: 'Which CI/CD platform would you like to use?',
|
|
526
|
-
choices: [
|
|
527
|
-
{ title: 'GitLab CI', value: 'gitlab' },
|
|
528
|
-
{ title: 'GitHub Actions', value: 'github' },
|
|
529
|
-
{ title: 'Bitbucket Pipelines', value: 'bitbucket' }
|
|
530
|
-
]
|
|
531
|
-
})
|
|
532
|
-
|
|
533
|
-
if (!providerResponse.provider) {
|
|
534
|
-
console.log('â No provider selected. Exiting.')
|
|
535
|
-
process.exit(0)
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
provider = providerResponse.provider
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
console.log('đ Setting up CI/CD...')
|
|
542
|
-
console.log('')
|
|
543
|
-
copyCITemplate(provider, cwd, flags.dryRun)
|
|
544
|
-
|
|
545
|
-
console.log('')
|
|
546
|
-
if (flags.dryRun) {
|
|
547
|
-
console.log('âšī¸ Dry run mode - no files were modified')
|
|
548
|
-
} else {
|
|
549
|
-
console.log('â
CI/CD setup complete!')
|
|
550
|
-
}
|
|
551
|
-
console.log('')
|
|
158
|
+
await setupCI(detected, cwd, flags.dryRun)
|
|
552
159
|
process.exit(0)
|
|
553
160
|
}
|
|
554
161
|
|
|
555
162
|
// Handle --ci flag with provider
|
|
556
163
|
if (hasCI && ciProvider) {
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
if (!validProviders.includes(ciProvider)) {
|
|
560
|
-
console.error(`â Unknown provider: ${ciProvider}`)
|
|
561
|
-
console.error(`Valid providers: ${validProviders.join(', ')}`)
|
|
562
|
-
process.exit(1)
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
console.log('đ CI/CD Pipeline Setup')
|
|
566
|
-
console.log('')
|
|
567
|
-
console.log('đ Setting up CI/CD...')
|
|
568
|
-
console.log('')
|
|
569
|
-
copyCITemplate(ciProvider, cwd, flags.dryRun)
|
|
570
|
-
|
|
571
|
-
console.log('')
|
|
572
|
-
if (flags.dryRun) {
|
|
573
|
-
console.log('âšī¸ Dry run mode - no files were modified')
|
|
574
|
-
} else {
|
|
575
|
-
console.log('â
CI/CD setup complete!')
|
|
576
|
-
}
|
|
577
|
-
console.log('')
|
|
164
|
+
validateProvider(ciProvider)
|
|
165
|
+
await setupCI(detected, cwd, flags.dryRun, ciProvider)
|
|
578
166
|
process.exit(0)
|
|
579
167
|
}
|
|
580
168
|
|
|
581
169
|
// Handle --all flag
|
|
582
170
|
if (flags.all) {
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
console.log('')
|
|
586
|
-
if (flags.dryRun) {
|
|
587
|
-
console.log('âšī¸ Dry run mode - no files were modified')
|
|
588
|
-
console.log('Run without --dry-run to apply changes')
|
|
589
|
-
} else {
|
|
590
|
-
console.log('â
Setup complete!')
|
|
591
|
-
}
|
|
592
|
-
console.log('')
|
|
171
|
+
await setupTools(VALID_TOOLS, detected, cwd, flags.dryRun)
|
|
172
|
+
showCompletion(flags.dryRun)
|
|
593
173
|
process.exit(0)
|
|
594
174
|
}
|
|
595
175
|
|
|
596
176
|
// Handle single tool mode
|
|
597
177
|
if (singleTool) {
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
if (!validTools.includes(singleTool)) {
|
|
601
|
-
console.error(`â Unknown tool: ${singleTool}`)
|
|
602
|
-
console.error(`Valid tools: ${validTools.join(', ')}`)
|
|
603
|
-
process.exit(1)
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
setupTools([singleTool], detected, cwd, flags.dryRun)
|
|
178
|
+
validateTool(singleTool)
|
|
179
|
+
await setupTools([singleTool], detected, cwd, flags.dryRun)
|
|
607
180
|
|
|
608
181
|
// If semantic-release + --ci flag, setup CI
|
|
609
182
|
if (singleTool === 'semantic-release' && hasCI) {
|
|
610
|
-
|
|
611
|
-
console.log('đ CI/CD Pipeline Setup')
|
|
612
|
-
console.log('')
|
|
613
|
-
|
|
614
|
-
let provider = ciProvider || detected.gitProvider
|
|
615
|
-
|
|
616
|
-
// If no provider specified and can't detect, prompt
|
|
617
|
-
if (!provider || provider === 'unknown') {
|
|
618
|
-
const providerResponse = await prompts({
|
|
619
|
-
type: 'select',
|
|
620
|
-
name: 'provider',
|
|
621
|
-
message: 'Which CI/CD platform would you like to use?',
|
|
622
|
-
choices: [
|
|
623
|
-
{ title: 'GitLab CI', value: 'gitlab' },
|
|
624
|
-
{ title: 'GitHub Actions', value: 'github' },
|
|
625
|
-
{ title: 'Bitbucket Pipelines', value: 'bitbucket' }
|
|
626
|
-
]
|
|
627
|
-
})
|
|
628
|
-
|
|
629
|
-
if (!providerResponse.provider) {
|
|
630
|
-
console.log('â ī¸ Skipping CI/CD setup.')
|
|
631
|
-
console.log('')
|
|
632
|
-
process.exit(0)
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
provider = providerResponse.provider
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
console.log('đ Setting up CI/CD...')
|
|
639
|
-
console.log('')
|
|
640
|
-
copyCITemplate(provider, cwd, flags.dryRun)
|
|
183
|
+
await setupCI(detected, cwd, flags.dryRun, ciProvider)
|
|
641
184
|
}
|
|
642
185
|
|
|
643
|
-
|
|
644
|
-
if (flags.dryRun) {
|
|
645
|
-
console.log('âšī¸ Dry run mode - no files were modified')
|
|
646
|
-
console.log('Run without --dry-run to apply changes')
|
|
647
|
-
} else {
|
|
648
|
-
console.log('â
Setup complete!')
|
|
649
|
-
}
|
|
650
|
-
console.log('')
|
|
186
|
+
showCompletion(flags.dryRun)
|
|
651
187
|
process.exit(0)
|
|
652
188
|
}
|
|
653
189
|
|
|
@@ -661,6 +197,11 @@ async function main() {
|
|
|
661
197
|
{ title: 'ESLint (JavaScript/TypeScript linting)', value: 'eslint', selected: true },
|
|
662
198
|
{ title: 'Prettier (Code formatting)', value: 'prettier', selected: true },
|
|
663
199
|
{ title: 'Stylelint (CSS/style linting)', value: 'stylelint', selected: false },
|
|
200
|
+
{
|
|
201
|
+
title: 'TypeScript (Type checking)',
|
|
202
|
+
value: 'typescript',
|
|
203
|
+
selected: detected.typescript
|
|
204
|
+
},
|
|
664
205
|
{
|
|
665
206
|
title: 'semantic-release (Automated versioning)',
|
|
666
207
|
value: 'semantic-release',
|
|
@@ -677,13 +218,11 @@ async function main() {
|
|
|
677
218
|
process.exit(0)
|
|
678
219
|
}
|
|
679
220
|
|
|
680
|
-
setupTools(response.tools, detected, cwd, flags.dryRun)
|
|
221
|
+
await setupTools(response.tools, detected, cwd, flags.dryRun)
|
|
681
222
|
|
|
682
223
|
// If semantic-release selected, prompt for CI setup
|
|
683
224
|
if (response.tools.includes('semantic-release')) {
|
|
684
|
-
|
|
685
|
-
console.log('đ CI/CD Pipeline Setup')
|
|
686
|
-
console.log('')
|
|
225
|
+
showSection('đ CI/CD Pipeline Setup')
|
|
687
226
|
|
|
688
227
|
const ciResponse = await prompts({
|
|
689
228
|
type: 'confirm',
|
|
@@ -697,21 +236,10 @@ async function main() {
|
|
|
697
236
|
|
|
698
237
|
// If provider not detected or unknown, prompt for it
|
|
699
238
|
if (!provider || provider === 'unknown') {
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
name: 'provider',
|
|
703
|
-
message: 'Which CI/CD platform would you like to use?',
|
|
704
|
-
choices: [
|
|
705
|
-
{ title: 'GitLab CI', value: 'gitlab' },
|
|
706
|
-
{ title: 'GitHub Actions', value: 'github' },
|
|
707
|
-
{ title: 'Bitbucket Pipelines', value: 'bitbucket' }
|
|
708
|
-
]
|
|
709
|
-
})
|
|
710
|
-
|
|
711
|
-
if (!providerResponse.provider) {
|
|
239
|
+
provider = await promptForProvider()
|
|
240
|
+
if (!provider) {
|
|
712
241
|
console.log('â ī¸ Skipping CI/CD setup.')
|
|
713
242
|
} else {
|
|
714
|
-
provider = providerResponse.provider
|
|
715
243
|
console.log('đ Setting up CI/CD...')
|
|
716
244
|
console.log('')
|
|
717
245
|
copyCITemplate(provider, cwd, flags.dryRun)
|
|
@@ -724,19 +252,7 @@ async function main() {
|
|
|
724
252
|
}
|
|
725
253
|
}
|
|
726
254
|
|
|
727
|
-
|
|
728
|
-
if (flags.dryRun) {
|
|
729
|
-
console.log('âšī¸ Dry run mode - no files were modified')
|
|
730
|
-
console.log('Run without --dry-run to apply changes')
|
|
731
|
-
} else {
|
|
732
|
-
console.log('â
Setup complete!')
|
|
733
|
-
console.log('')
|
|
734
|
-
console.log('Next steps:')
|
|
735
|
-
console.log(' 1. Review the generated config files')
|
|
736
|
-
console.log(' 2. Install peer dependencies if needed')
|
|
737
|
-
console.log(' 3. Run: npm run lint (or other added scripts)')
|
|
738
|
-
}
|
|
739
|
-
console.log('')
|
|
255
|
+
showCompletion(flags.dryRun)
|
|
740
256
|
}
|
|
741
257
|
|
|
742
258
|
// Run CLI
|