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
JavaScript
/**
* 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
`);
}