@puls-atlas/cli
Version:
The Puls Atlas CLI tool for managing Atlas projects
120 lines • 4.48 kB
JavaScript
import { logger } from '../../utils/index.js';
import { readJsonFile } from '../../utils/file.js';
import { resolveRootPath } from '../../utils/atlas.js';
import { normalizeOptionalString } from '../../utils/value.js';
import { resolveRuntimeEnvironmentBinding } from '../service/configShape.js';
import { SERVICE_CONFIG_ROOT_PATH } from '../service/config/serviceConfig.js';
import { resolveStartDevelopmentProjectId } from './projectSelection.js';
import { findService } from '../service/serviceRegistry.js';
import { getRuntimeServiceCatalogService, resolveLatestRuntimeServiceCatalogVersion, resolveRuntimeServiceCatalog } from '../service/runtimeServiceCatalog.js';
const readRootServiceConfig = (rootDir, dependencies = {}) => {
const readJsonFileImpl = dependencies.readJsonFileImpl ?? readJsonFile;
return readJsonFileImpl(resolveRootPath(SERVICE_CONFIG_ROOT_PATH, rootDir), {
allowMissing: true
}) ?? {
services: {}
};
};
export const collectServiceUpdateNotices = async ({
rootDir
}, dependencies = {}) => {
const developmentProjectId = resolveStartDevelopmentProjectId(rootDir, dependencies);
if (!developmentProjectId) {
return [];
}
const rootServiceConfig = readRootServiceConfig(rootDir, dependencies);
const configuredServices = rootServiceConfig?.services ?? {};
if (!configuredServices || typeof configuredServices !== 'object') {
return [];
}
const updateCandidates = Object.entries(configuredServices).flatMap(([serviceName, serviceConfig]) => {
if (findService(serviceName)) {
return [];
}
const bindingConfig = resolveRuntimeEnvironmentBinding(serviceConfig, 'development');
const configuredCatalogVersion = normalizeOptionalString(bindingConfig?.release?.catalogVersion);
if (bindingConfig?.enabled !== true || !configuredCatalogVersion) {
return [];
}
return [{
configuredCatalogVersion,
serviceName
}];
});
if (updateCandidates.length === 0) {
return [];
}
const resolveLatestRuntimeServiceCatalogVersionImpl = dependencies.resolveLatestRuntimeServiceCatalogVersionImpl ?? resolveLatestRuntimeServiceCatalogVersion;
const resolveRuntimeServiceCatalogImpl = dependencies.resolveRuntimeServiceCatalogImpl ?? resolveRuntimeServiceCatalog;
const latestCatalogVersion = resolveLatestRuntimeServiceCatalogVersionImpl({
runCommand: dependencies.runCommand
});
if (!latestCatalogVersion) {
return [];
}
const latestCatalog = resolveRuntimeServiceCatalogImpl({
catalogVersion: latestCatalogVersion,
runCommand: dependencies.runCommand
});
return updateCandidates.flatMap(({
configuredCatalogVersion,
serviceName
}) => {
if (configuredCatalogVersion === latestCatalogVersion) {
return [];
}
try {
const catalogService = getRuntimeServiceCatalogService(latestCatalog.catalog, serviceName, {
catalogVersion: latestCatalog.catalogVersion
});
if (normalizeOptionalString(catalogService?.serviceDeploy?.scope) !== 'project') {
return [];
}
return [{
category: 'services',
label: `Service ${catalogService.id}`,
value: `${configuredCatalogVersion} -> ${latestCatalogVersion} ` + `(project ${developmentProjectId}; run atlas service deploy ${catalogService.id} --latest)`
}];
} catch {
return [];
}
});
};
const START_UPDATE_NOTICE_COLLECTORS = [collectServiceUpdateNotices];
export const collectStartUpdateNotices = async ({
rootDir
}, dependencies = {}) => {
const notices = [];
for (const collector of START_UPDATE_NOTICE_COLLECTORS) {
try {
const collectorNotices = await collector({
rootDir
}, dependencies);
notices.push(...collectorNotices);
} catch (error) {
dependencies.loggerImpl?.debug?.('Failed to collect Atlas start update notices.', error);
}
}
return notices;
};
export const outputStartUpdateNotices = (notices, {
loggerImpl = logger
} = {}) => {
if (!Array.isArray(notices) || notices.length === 0) {
return false;
}
loggerImpl.summary('Available updates', notices.map(notice => ({
label: notice.label,
tone: 'warning',
value: notice.value
})), {
spacing: 'after'
});
loggerImpl.warning('Atlas start detected available updates. Review the available updates summary above.');
return true;
};
export default {
collectServiceUpdateNotices,
collectStartUpdateNotices,
outputStartUpdateNotices
};