UNPKG

cartorio-plataforma-cli

Version:

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

212 lines (180 loc) 7.27 kB
/** * Módulo para gerar e manter o arquivo de configuração do Docker Buildx Bake */ const fs = require('fs'); const path = require('path'); /** * Classe para gerenciar o arquivo bake.hcl */ class BakeGenerator { /** * Cria um novo gerador de configuração bake * @param {ModuleRegistry} registry - Registro de módulos da plataforma */ constructor(registry) { this.registry = registry; } /** * Gera um arquivo bake.hcl com base nos módulos registrados * @param {string} filePath - Caminho do arquivo a ser gerado * @param {string} domain - Domínio da plataforma * @returns {boolean} - Resultado da operação */ generateBakeFile(filePath, domain = 'plataforma.cartoriocriciumasc.com.br') { try { let content = this._generateVariablesSection(domain); content += this._generateGroupsSection(); content += this._generateTargetsSection(); fs.writeFileSync(filePath, content, 'utf8'); return true; } catch (error) { console.error(`Erro ao gerar arquivo bake: ${error.message}`); return false; } } /** * Gera a seção de variáveis do arquivo bake * @param {string} domain - Domínio da plataforma * @returns {string} - Conteúdo da seção */ _generateVariablesSection(domain) { return `// Configurações variáveis para ambientes variable "PLATAFORMA_DOMAIN" { default = "${domain}" } variable "ENV" { default = "development" } `; } /** * Gera a seção de grupos do arquivo bake * @returns {string} - Conteúdo da seção */ _generateGroupsSection() { let content = ''; const environments = ['dev', 'local', 'prod']; // Para cada ambiente, criar grupos environments.forEach(env => { // Obter módulos para este ambiente const modules = this.registry.getModulesForEnv(env); // Grupos por tipo const coreModules = modules.filter(m => m.type === 'core'); const frontendModules = modules.filter(m => m.type === 'frontend'); const backendModules = modules.filter(m => m.type === 'backend'); // Criar grupo principal (todos os módulos não-infraestrutura) const allTargets = modules .filter(m => m.type !== 'infrastructure') .map(m => m.profile) .filter(Boolean); content += `// Grupo para ambiente de ${env}\n`; content += `group "${env}" {\n`; content += ` targets = [${allTargets.map(t => `"${t}"`).join(', ')}]\n`; content += `}\n\n`; // Grupo para infraestrutura content += `// Grupo específico para infraestrutura em ambiente de ${env}\n`; content += `group "${env}-infra" {\n`; content += ` targets = []\n`; content += `}\n\n`; // Grupos específicos para cada tipo de infraestrutura const infraTypes = ['consul', 'postgres', 'traefik']; infraTypes.forEach(infraType => { content += `group "${infraType}-${env}" {\n`; content += ` targets = []\n`; content += `}\n\n`; }); // Grupo para core const coreTargets = coreModules.map(m => m.profile).filter(Boolean); content += `// Grupo específico para core em ambiente de ${env}\n`; content += `group "${env}-core" {\n`; content += ` targets = [${coreTargets.map(t => `"${t}"`).join(', ')}]\n`; content += `}\n\n`; // Grupo para módulos (frontend + backend, excluindo core) const moduleTargets = [...frontendModules, ...backendModules] .filter(m => m.type !== 'core') .map(m => m.profile) .filter(Boolean); content += `// Grupo específico para módulos em ambiente de ${env}\n`; content += `group "${env}-modules" {\n`; content += ` targets = [${moduleTargets.map(t => `"${t}"`).join(', ')}]\n`; content += `}\n\n`; // Grupo para full (todos exceto infra) content += `// Grupo específico para full (tudo exceto infra) em ambiente de ${env}\n`; content += `group "${env}-full" {\n`; content += ` targets = [${allTargets.map(t => `"${t}"`).join(', ')}]\n`; content += `}\n\n`; }); return content; } /** * Gera a seção de targets do arquivo bake * @returns {string} - Conteúdo da seção */ _generateTargetsSection() { let content = `// Configuração padrão compartilhada para todos os serviços target "default" { context = ".." args = { ENV = "\${ENV}" } } // Configurações específicas por serviço e ambiente `; // Para cada módulo não-infraestrutura, criar targets para cada ambiente const modules = this.registry.getAllModules().filter(m => m.type !== 'infrastructure'); const environments = ['dev', 'local', 'prod']; modules.forEach(module => { environments.forEach(env => { if (module.profiles && module.profiles[env]) { const targetName = module.profiles[env]; const dockerfile = module.docker && module.docker.dockerfile ? (env === 'prod' ? module.docker.dockerfile.prod : module.docker.dockerfile.dev) : (env === 'prod' ? 'Dockerfile' : 'Dockerfile.dev'); const context = module.docker && module.docker.context ? module.docker.context : './'; const relativePath = path.relative('..', module.path); content += `target "${targetName}" {\n`; content += ` inherits = ["default"]\n`; content += ` context = "${relativePath}"\n`; content += ` dockerfile = "${dockerfile}"\n`; content += ` args = {\n`; content += ` ENV = "${env === 'dev' ? 'development' : (env === 'prod' ? 'production' : 'local')}"\n`; content += ` }\n`; content += ` tags = ["${targetName.split('-')[0]}:${env}"]\n`; content += `}\n\n`; } }); }); return content; } /** * Atualiza o arquivo bake.hcl existente com novos módulos * @param {string} filePath - Caminho do arquivo bake.hcl * @returns {boolean} - Resultado da operação */ updateBakeFile(filePath) { try { // Verificar se o arquivo existe if (!fs.existsSync(filePath)) { return this.generateBakeFile(filePath); } // Ler o arquivo atual para preservar configurações customizadas const currentContent = fs.readFileSync(filePath, 'utf8'); // Atualizar as seções de grupos e targets // Esta é uma implementação simplificada, uma abordagem mais robusta // envolveria parsing do arquivo HCL const updatedGroups = this._generateGroupsSection(); const updatedTargets = this._generateTargetsSection(); // Substituir as seções no arquivo atual // Isto assume que há comentários específicos para delimitar as seções let newContent = currentContent; // Aqui teríamos um parser mais sofisticado para HCL // Esta é uma aproximação simplificada fs.writeFileSync(filePath, newContent, 'utf8'); return true; } catch (error) { console.error(`Erro ao atualizar arquivo bake: ${error.message}`); return false; } } } module.exports = BakeGenerator;