packages/aws-cdk/lib/cxapp/environments.ts (50 lines of code) (raw):
import type * as cxapi from '@aws-cdk/cx-api';
import { minimatch } from 'minimatch';
import { ToolkitError } from '../api';
import type { SdkProvider, StackCollection } from '../api';
export function looksLikeGlob(environment: string) {
return environment.indexOf('*') > -1;
}
// eslint-disable-next-line max-len
export async function globEnvironmentsFromStacks(stacks: StackCollection, environmentGlobs: string[], sdk: SdkProvider): Promise<cxapi.Environment[]> {
if (environmentGlobs.length === 0) {
return [];
}
const availableEnvironments = new Array<cxapi.Environment>();
for (const stack of stacks.stackArtifacts) {
const actual = await sdk.resolveEnvironment(stack.environment);
availableEnvironments.push(actual);
}
const environments = distinct(availableEnvironments).filter(env => environmentGlobs.find(glob => minimatch(env!.name, glob)));
if (environments.length === 0) {
const globs = JSON.stringify(environmentGlobs);
const envList = availableEnvironments.length > 0 ? availableEnvironments.map(env => env!.name).join(', ') : '<none>';
throw new ToolkitError(`No environments were found when selecting across ${globs} (available: ${envList})`);
}
return environments;
}
/**
* Given a set of "<account>/<region>" strings, construct environments for them
*/
export function environmentsFromDescriptors(envSpecs: string[]): cxapi.Environment[] {
const ret = new Array<cxapi.Environment>();
for (const spec of envSpecs) {
const parts = spec.replace(/^aws:\/\//, '').split('/');
if (parts.length !== 2) {
throw new ToolkitError(`Expected environment name in format 'aws://<account>/<region>', got: ${spec}`);
}
ret.push({
name: spec,
account: parts[0],
region: parts[1],
});
}
return ret;
}
/**
* De-duplicates a list of environments, such that a given account and region is only represented exactly once
* in the result.
*
* @param envs the possibly full-of-duplicates list of environments.
*
* @return a de-duplicated list of environments.
*/
function distinct(envs: cxapi.Environment[]): cxapi.Environment[] {
const unique: { [id: string]: cxapi.Environment } = {};
for (const env of envs) {
const id = `${env.account || 'default'}/${env.region || 'default'}`;
if (id in unique) {
continue;
}
unique[id] = env;
}
return Object.values(unique);
}