import * as path from 'path'; import * as fs from 'fs'; import { get } from 'lodash'; import { createError, match, rimraf } from '@cirrusct/core-node'; import { Logger } from '@cirrusct/logging'; import { MonoRepoPackage, MonoRepo, MrPackageConfig } from '@cirrusct/mr-core'; import { BuildConfig, MrBuild } from '@cirrusct/mr-build'; import { MrCommandHandler } from '@cirrusct/mr-command'; import { MrDeployOptions, ResolvedDeploymentConfig, MrConfig } from './types'; import { DeploymentConfigResolver } from './DeployConfigResolver'; import { DeployTemplateContext } from './DeployTemplateContext'; import { getPackagesWithDeployments, getResolvedConfigs } from './config'; export const handleGenerateCommand: MrCommandHandler = async ({ logger, packages, options = {}, cwd, monoRepo, }): Promise => { try { if (options.deployment) { const resolvedConfigs = await getResolvedConfigs(options.deployment, options, monoRepo); await generate(resolvedConfigs, logger); } else { const packagesWithDeployments = await getPackagesWithDeployments(monoRepo, packages); for (const pkg of packagesWithDeployments) { const childLogger = logger.child({ package: pkg.name }); childLogger.info('Running Package Deploy'); await generatePackageDeployment(pkg, options, logger); } } } catch (e) { throw createError(`Deploy Command Failed`, e); } }; export const generatePackageDeployment = async ( mrPackage: MonoRepoPackage, options: MrDeployOptions, logger: Logger, name?: string ) => { const buildConfig = await MrBuild.getPackageBuildConfig(mrPackage); if (buildConfig.specs) { const mr: MonoRepo = mrPackage.monoRepo; const deployConfig = mr.config.deploy; // TODO: centralize const spec = get(buildConfig.specs, 'default', get(buildConfig.specs, Object.keys(buildConfig.specs)[0])); const resolver = new DeploymentConfigResolver(mrPackage, deployConfig, spec, options, name); const resolved = await resolver.resolve(); await generate(resolved, logger); } else { logger.info({}, `Skipping package ${mrPackage.name}. No Build Spec`); } }; export const generate = async ( resolvedConfig: ResolvedDeploymentConfig | ResolvedDeploymentConfig[], logger: Logger ) => { const deploymentConfigs = Array.isArray(resolvedConfig) ? resolvedConfig : [resolvedConfig]; if (deploymentConfigs && deploymentConfigs.length > 0) { logger.info(`Generating ${deploymentConfigs.length} deployment${deploymentConfigs.length === 1 ? '' : 's'}`); for (const config of deploymentConfigs) { const childLogger = logger.child({ deployment: config.name, output: config.output }); childLogger.info(`Generating deployment`); const serverContexts = config.dependsOnServersResolvedConfigs.map(serverConfig => { return new DeployTemplateContext(serverConfig); }); childLogger.debug(`Removing existing output folder`); rimraf(config.output); const context = new DeployTemplateContext(config, serverContexts); for (const templateFile of context.templateFiles) { childLogger.debug( { source: templateFile.source.filePath, output: templateFile.outputPath }, `Generating template..'` ); templateFile.render(); } for (const serverContext of serverContexts) { const serverLogger = childLogger.child({ serverPackage: serverContext.mrPackage.name }); serverLogger.info({ serverPackage: serverContext.mrPackage.name }, `Generating server templates..'`); context.currentServerContext = serverContext; for (const templateFile of serverContext.templateFiles) { templateFile.context = context; serverLogger.debug( { source: templateFile.source.filePath, output: templateFile.getOutputPath(serverContext.output), }, `Generating server template..'` ); templateFile.render(serverContext.output); } } } } else { logger.info(`No Deployment Configs Resolved`); } };