Merge pull request #2115 from hmcts/use-cookiecutter-installed-on-host
Use cookie cutter installed on host if available
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
"@octokit/rest": "^18.0.0",
|
||||
"@types/dockerode": "^2.5.32",
|
||||
"@types/express": "^4.17.6",
|
||||
"command-exists-promise": "^2.0.2",
|
||||
"compression": "^1.7.4",
|
||||
"cors": "^2.8.5",
|
||||
"dockerode": "^3.2.0",
|
||||
|
||||
@@ -15,11 +15,13 @@
|
||||
*/
|
||||
import fs from 'fs-extra';
|
||||
import { JsonValue } from '@backstage/config';
|
||||
import { runDockerContainer } from './helpers';
|
||||
import { runDockerContainer, runCommand } from './helpers';
|
||||
import { TemplaterBase, TemplaterRunOptions } from '.';
|
||||
import path from 'path';
|
||||
import { TemplaterRunResult } from './types';
|
||||
|
||||
const commandExists = require('command-exists-promise');
|
||||
|
||||
export class CookieCutter implements TemplaterBase {
|
||||
private async fetchTemplateCookieCutter(
|
||||
directory: string,
|
||||
@@ -51,21 +53,30 @@ export class CookieCutter implements TemplaterBase {
|
||||
const templateDir = options.directory;
|
||||
const resultDir = await fs.promises.mkdtemp(`${options.directory}-result`);
|
||||
|
||||
await runDockerContainer({
|
||||
imageName: 'spotify/backstage-cookiecutter',
|
||||
args: [
|
||||
'cookiecutter',
|
||||
'--no-input',
|
||||
'-o',
|
||||
'/result',
|
||||
'/template',
|
||||
'--verbose',
|
||||
],
|
||||
templateDir,
|
||||
resultDir,
|
||||
logStream: options.logStream,
|
||||
dockerClient: options.dockerClient,
|
||||
});
|
||||
const cookieCutterInstalled = await commandExists('cookiecutter');
|
||||
if (cookieCutterInstalled) {
|
||||
await runCommand({
|
||||
command: 'cookiecutter',
|
||||
args: ['--no-input', '-o', resultDir, templateDir, '--verbose'],
|
||||
logStream: options.logStream,
|
||||
});
|
||||
} else {
|
||||
await runDockerContainer({
|
||||
imageName: 'spotify/backstage-cookiecutter',
|
||||
args: [
|
||||
'cookiecutter',
|
||||
'--no-input',
|
||||
'-o',
|
||||
'/result',
|
||||
'/template',
|
||||
'--verbose',
|
||||
],
|
||||
templateDir,
|
||||
resultDir,
|
||||
logStream: options.logStream,
|
||||
dockerClient: options.dockerClient,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
resultDir: path.resolve(resultDir, options.values.component_id as string),
|
||||
|
||||
@@ -18,6 +18,7 @@ import Docker from 'dockerode';
|
||||
import fs from 'fs';
|
||||
import { TemplateEntityV1alpha1 } from '@backstage/catalog-model';
|
||||
import { InputError } from '@backstage/backend-common';
|
||||
import { spawn } from 'child_process';
|
||||
|
||||
export type RunDockerContainerOptions = {
|
||||
imageName: string;
|
||||
@@ -29,6 +30,12 @@ export type RunDockerContainerOptions = {
|
||||
createOptions?: Docker.ContainerCreateOptions;
|
||||
};
|
||||
|
||||
export type RunCommandOptions = {
|
||||
command: string;
|
||||
args: string[];
|
||||
logStream?: Writable;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the templater key to use for templating from the entity
|
||||
* @param entity Template entity
|
||||
@@ -43,6 +50,42 @@ export const getTemplaterKey = (entity: TemplateEntityV1alpha1): string => {
|
||||
return templater;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param options the options object
|
||||
* @param options.command the command to run
|
||||
* @param options.args the arguments to pass the command
|
||||
* @param options.logStream the log streamer to capture log messages
|
||||
*/
|
||||
export const runCommand = async ({
|
||||
command,
|
||||
args,
|
||||
logStream = new PassThrough(),
|
||||
}: RunCommandOptions) => {
|
||||
await new Promise((resolve, reject) => {
|
||||
const process = spawn(command, args);
|
||||
|
||||
process.stdout.on('data', stream => {
|
||||
logStream.write(stream);
|
||||
});
|
||||
|
||||
process.stderr.on('data', stream => {
|
||||
logStream.write(stream);
|
||||
});
|
||||
|
||||
process.on('error', error => {
|
||||
return reject(error);
|
||||
});
|
||||
|
||||
process.on('close', code => {
|
||||
if (code !== 0) {
|
||||
return reject(`Command ${command} failed, exit code: ${code}`);
|
||||
}
|
||||
return resolve();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param options the options object
|
||||
|
||||
Reference in New Issue
Block a user