UNPKG

cartorio-plataforma-cli

Version:

CLI para gerenciar a Plataforma do Cartório de Criciúma com sistema de módulos

267 lines (234 loc) 8.18 kB
/** * Comando para gerenciar módulos da plataforma */ const inquirer = require('inquirer'); const chalk = require('chalk'); const path = require('path'); const fs = require('fs'); const ModuleRegistry = require('../lib/module-registry'); const DockerCommandGenerator = require('../lib/docker-command-generator'); const { generateManifestTemplate, createManifestFile } = require('../lib/manifest-utils'); const BakeGenerator = require('../lib/bake-generator'); const boxen = require('boxen'); /** * Função principal do comando module */ module.exports = async function module(options) { // Criar instâncias para gerenciamento de modules e comandos const registry = new ModuleRegistry(); const commandGenerator = new DockerCommandGenerator(registry); try { // Encontra o diretório raiz do projeto const projectRoot = commandGenerator.findProjectDir(); // Carregar os módulos existentes registry.loadModules(projectRoot); // Subcomandos disponíveis if (options.create) { await createModule(registry, projectRoot, options); } else if (options.list) { listModules(registry); } else if (options.update) { await updateBakeFile(registry, projectRoot); } else { // Se nenhum subcomando foi especificado, mostrar ajuda showHelp(); } } catch (error) { console.error(chalk.red(`Erro ao executar comando: ${error.message}`)); console.error(chalk.red(error.stack)); } }; /** * Função para criar um novo módulo */ async function createModule(registry, projectRoot, options) { const moduleOptions = { ...options }; if (options.interactive) { const answers = await inquirer.prompt([ { type: 'input', name: 'id', message: 'ID do módulo:', validate: (input) => input.trim() !== '' ? true : 'O ID não pode estar vazio' }, { type: 'input', name: 'name', message: 'Nome do módulo:', validate: (input) => input.trim() !== '' ? true : 'O nome não pode estar vazio' }, { type: 'list', name: 'type', message: 'Tipo do módulo:', choices: [ { name: 'Frontend', value: 'frontend' }, { name: 'Backend', value: 'backend' }, { name: 'Core', value: 'core' }, { name: 'Infraestrutura', value: 'infrastructure' } ] }, { type: 'confirm', name: 'createDirectories', message: 'Criar diretórios para o módulo?', default: true } ]); Object.assign(moduleOptions, answers); } else { // Validar argumentos obrigatórios para o modo não interativo if (!moduleOptions.id) { console.error(chalk.red('Erro: ID do módulo é obrigatório. Use --id=valor')); return; } if (!moduleOptions.name) { console.error(chalk.red('Erro: Nome do módulo é obrigatório. Use --name=valor')); return; } if (!moduleOptions.type) { console.error(chalk.red('Erro: Tipo do módulo é obrigatório. Use --type=valor (frontend, backend, core, infrastructure)')); return; } } // Validar tipo do módulo const validTypes = ['frontend', 'backend', 'core', 'infrastructure']; if (!validTypes.includes(moduleOptions.type)) { console.error(chalk.red(`Erro: Tipo de módulo inválido: ${moduleOptions.type}. Use um dos tipos: ${validTypes.join(', ')}`)); return; } // Gerar o template do manifesto const manifest = generateManifestTemplate( moduleOptions.id, moduleOptions.name, moduleOptions.type ); // Caminho para o diretório do módulo const moduleDir = path.join(projectRoot, `${moduleOptions.id}-${moduleOptions.type}`); // Verificar se o diretório já existe if (fs.existsSync(moduleDir)) { const { overwrite } = await inquirer.prompt([ { type: 'confirm', name: 'overwrite', message: `O diretório ${moduleDir} já existe. Deseja continuar?`, default: false } ]); if (!overwrite) { console.log(chalk.yellow('Operação cancelada pelo usuário.')); return; } } else if (moduleOptions.createDirectories) { // Criar o diretório do módulo fs.mkdirSync(moduleDir, { recursive: true }); console.log(chalk.green(`Diretório criado: ${moduleDir}`)); } // Criar o arquivo de manifesto if (createManifestFile(moduleDir, manifest, 'js')) { console.log(chalk.green(`Manifesto criado em: ${path.join(moduleDir, 'plataforma-manifest.js')}`)); } else { console.error(chalk.red('Erro ao criar arquivo de manifesto.')); return; } // Atualizar o arquivo bake.hcl await updateBakeFile(registry, projectRoot); console.log( boxen( chalk.green(`Módulo ${moduleOptions.name} criado com sucesso!`) + '\n\n' + chalk.white(`ID: ${chalk.cyan(moduleOptions.id)}`) + '\n' + chalk.white(`Tipo: ${chalk.cyan(moduleOptions.type)}`) + '\n' + chalk.white(`Diretório: ${chalk.cyan(moduleDir)}`), { padding: 1, borderColor: 'green', borderStyle: 'round' } ) ); } /** * Função para listar módulos */ function listModules(registry) { const allModules = registry.getAllModules(); if (allModules.length === 0) { console.log(chalk.yellow('Nenhum módulo encontrado.')); return; } console.log(chalk.blue('Módulos registrados:')); console.log(); // Agrupar por tipo const modulesByType = { core: [], frontend: [], backend: [], infrastructure: [] }; allModules.forEach(module => { if (modulesByType[module.type]) { modulesByType[module.type].push(module); } }); // Exibir por tipo Object.keys(modulesByType).forEach(type => { const modules = modulesByType[type]; if (modules.length > 0) { console.log(chalk.cyan(`\n${type.toUpperCase()}:`)); modules.forEach(module => { console.log(` - ${chalk.green(module.name)} (${chalk.yellow(module.id)})`); console.log(` Descrição: ${module.description || 'Não informada'}`); console.log(` Caminho: ${module.path}`); console.log(); }); } }); } /** * Função para atualizar o arquivo bake */ async function updateBakeFile(registry, projectRoot) { console.log(chalk.blue('Atualizando arquivo bake.hcl...')); // Procurar pelo arquivo bake.hcl na pasta plataforma-infra const infraDir = path.join(projectRoot, 'plataforma-infra'); const bakeFilePath = fs.existsSync(path.join(infraDir, 'docker-compose.bake.hcl')) ? path.join(infraDir, 'docker-compose.bake.hcl') : path.join(projectRoot, 'docker-compose.bake.hcl'); if (!fs.existsSync(bakeFilePath)) { console.error(chalk.red(`Arquivo bake.hcl não encontrado em ${bakeFilePath}`)); return false; } // Criar gerador de bake const bakeGenerator = new BakeGenerator(registry); // Atualizar o arquivo bake.hcl if (bakeGenerator.updateBakeFile(bakeFilePath)) { console.log(chalk.green(`Arquivo bake.hcl atualizado com sucesso: ${bakeFilePath}`)); return true; } else { console.error(chalk.red(`Erro ao atualizar arquivo bake.hcl: ${bakeFilePath}`)); return false; } } /** * Exibir ajuda do comando */ function showHelp() { console.log(` ${chalk.blue('Gerenciamento de Módulos da Plataforma')} ${chalk.yellow('Uso:')} plataforma module [opções] ${chalk.yellow('Subcomandos:')} --create Criar um novo módulo --list Listar módulos existentes --update Atualizar arquivo bake.hcl com os módulos registrados ${chalk.yellow('Opções para --create:')} --id=valor ID do módulo --name=valor Nome do módulo --type=valor Tipo do módulo (frontend, backend, core, infrastructure) --interactive Modo interativo (padrão: true) --createDirectories Criar diretórios para o módulo (padrão: true) ${chalk.yellow('Exemplos:')} plataforma module --create --interactive plataforma module --list plataforma module --create --id=senhas --name="Módulo de Senhas" --type=frontend `); }