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