@aws-cdk-testing/cli-integ
Version:
Integration tests for the AWS CDK CLI
100 lines (83 loc) • 3.23 kB
text/typescript
import * as path from 'path';
import * as fs from 'fs-extra';
import { copyDirectoryContents, homeDir, loadLines, updateIniKey, writeLines } from '../files';
export const DEFAULT_USAGE_DIR = path.join(homeDir(), '.codeartifact/usage');
/**
* The usage directory is where we write per-session config files to access the CodeArtifact repository.
*
* Some config files may be written in a system-global location, but they will not be active unless the
* contents of this directory have been sourced/copied into the current terminal.
*
* CONTRACT
*
* There are two special entries:
*
* - `env`, a file with `key=value` entries for environment variables to set.
* - `cwd/`, a directory with files that need to be copied into the current directory before each command.
*
* Other than these, code may write tempfiles to this directory if it wants, but there is no meaning
* implied for other files.
*/
export class UsageDir {
public static default() {
return new UsageDir(DEFAULT_USAGE_DIR);
}
public readonly envFile: string;
public readonly cwdDir: string;
private constructor(public readonly directory: string) {
this.envFile = path.join(this.directory, 'env');
this.cwdDir = path.join(this.directory, 'cwd');
}
public async clean() {
await fs.rm(this.directory, { recursive: true, force: true });
await fs.mkdirp(path.join(this.directory, 'cwd'));
await fs.writeFile(path.join(this.directory, 'env'), '', { encoding: 'utf-8' });
await this.addToEnv({
CWD_FILES_DIR: path.join(this.directory, 'cwd'),
});
// Write a bash helper to load these settings
await fs.writeFile(path.join(this.directory, 'activate.bash'), [
`while read -u10 line; do [[ -z $line ]] || export "$line"; done 10<${this.directory}/env`,
'cp -R $CWD_FILES_DIR/ .', // Copy files from directory even if it is empty
].join('\n'), { encoding: 'utf-8' });
}
public async addToEnv(settings: Record<string, string>) {
const lines = await loadLines(this.envFile);
for (const [k, v] of Object.entries(settings)) {
updateIniKey(lines, k, v);
}
await writeLines(this.envFile, lines);
}
public async currentEnv(): Promise<Record<string, string>> {
const lines = await loadLines(this.envFile);
const splitter = /^([a-zA-Z0-9_-]+)\s*=\s*(.*)$/;
const ret: Record<string, string> = {};
for (const line of lines) {
const m = line.match(splitter);
if (m) {
ret[m[1]] = m[2];
}
}
return ret;
}
public cwdFile(filename: string) {
return path.join(this.cwdDir, filename);
}
public async activateInCurrentProcess() {
for (const [k, v] of Object.entries(await this.currentEnv())) {
process.env[k] = v;
}
await copyDirectoryContents(this.cwdDir, '.');
}
public async copyCwdFileHere(...filenames: string[]) {
for (const file of filenames) {
await fs.copyFile(path.join(this.cwdDir, file), file);
}
}
public advertise() {
// eslint-disable-next-line no-console
console.log('To activate these settings in the current terminal:');
// eslint-disable-next-line no-console
console.log(` source ${this.directory}/activate.bash`);
}
}