citty-test-utils
Version:
Unified testing framework for CLI applications with auto-detecting local/cleanroom execution, vitest config integration, and simplified scenario DSL.
154 lines (141 loc) โข 4.56 kB
JavaScript
// src/commands/gen/config.js - Gen config verb command
import { defineCommand } from 'citty'
import nunjucks from 'nunjucks'
import { writeFile, mkdir } from 'node:fs/promises'
import { existsSync } from 'node:fs'
import { join } from 'node:path'
export const configCommand = defineCommand({
meta: {
name: 'config',
description: 'Generate configuration files',
},
args: {
name: {
type: 'positional',
description: 'Name for the generated config file',
required: true,
},
output: {
type: 'string',
description: 'Output directory',
default: '.',
},
format: {
type: 'string',
description: 'Output format (js, mjs, ts, json)',
default: 'json',
},
version: {
type: 'string',
description: 'Version for generated files',
default: '1.0.0',
},
description: {
type: 'string',
description: 'Description for generated files',
default: '',
},
overwrite: {
type: 'boolean',
description: 'Overwrite existing files',
default: false,
},
},
run: async (ctx) => {
const { name, output, format, version, description, overwrite, json, verbose } = ctx.args
if (verbose) {
console.error(`Generating config template: ${name}.${format}`)
console.error(`Output: ${output}`)
}
try {
// Configure nunjucks
nunjucks.configure(join(process.cwd(), 'templates'), {
autoescape: false,
throwOnUndefined: true,
})
// Ensure output directory exists
// Generate config in a temporary directory
const { tmpdir } = await import('node:os')
const tempDir = join(tmpdir(), `citty-test-${Date.now()}`)
const outputDir = join(tempDir, output)
if (!existsSync(outputDir)) {
await mkdir(outputDir, { recursive: true })
}
// Generate config file
const templateFile = 'config/package.json.njk'
const outputFile = join(outputDir, 'package.json')
const templateData = {
name,
version,
description: description || `Package for ${name}`,
main: `src/${name}.${format === 'json' ? 'mjs' : format}`,
scripts: [
{ name: 'test', command: 'vitest' },
{ name: 'test:watch', command: 'vitest --watch' },
{ name: 'test:coverage', command: 'vitest --coverage' },
],
dependencies: [
{ name: 'citty', version: '^0.1.6' },
{ name: 'citty-test-utils', version: '^0.2.3' },
],
devDependencies: [
{ name: 'vitest', version: '^1.0.0' },
{ name: '@vitest/coverage-v8', version: '^1.0.0' },
],
keywords: ['cli', 'testing', 'citty'],
author: 'Generated by citty-test-utils',
license: 'MIT',
cittyTestUtils: {
testEnvironment: 'local',
timeout: 10000,
scenarios: ['help', 'version'],
},
}
// Check if file exists and handle overwrite
if (existsSync(outputFile) && !overwrite) {
throw new Error(`File ${outputFile} already exists. Use --overwrite to replace it.`)
}
// Render template
const content = nunjucks.render(templateFile, templateData)
// Write file
await writeFile(outputFile, content)
const result = {
template: 'config',
name,
output: outputFile,
format,
status: 'success',
message: `Config template generated successfully`,
timestamp: new Date().toISOString(),
}
if (json) {
console.log(JSON.stringify(result))
} else {
console.log(`โ
Generated config template: ${name}.${format}`)
console.log(`๐ Location: ${outputFile}`)
console.log(`โ ๏ธ Note: This is a temporary directory that will be cleaned up automatically`)
console.log(`๐งน Cleanup scheduled for: ${tempDir}`)
console.log(`๐ Template: ${templateFile}`)
console.log(`๐ฏ Status: ${result.status}`)
}
} catch (error) {
const errorResult = {
template: 'config',
name,
output,
format,
status: 'error',
error: error.message,
timestamp: new Date().toISOString(),
}
if (json) {
console.log(JSON.stringify(errorResult))
} else {
console.error(`โ Failed to generate config template: ${name}.${format}`)
console.error(`Error: ${error.message}`)
}
process.exit(1)
}
},
})