From bc15e7a7103cb0e49d5ea6e7eb01919feec2e1ad Mon Sep 17 00:00:00 2001 From: Ivan Shmidt Date: Tue, 23 Jun 2020 11:56:56 +0200 Subject: [PATCH] feat(scaffolder): cookiecutter templater wip Co-authored-by: Ben Lambert --- plugins/scaffolder-backend/package.json | 1 + .../hooks/post_gen_project.sh | 17 ++++++---------- .../hooks/pre_gen_project.sh | 9 --------- .../package.json | 2 +- plugins/scaffolder-backend/scripts/Dockerfile | 11 ++++++++++ .../src/scaffolder/templater/cookiecutter.ts | 20 +++++++++++++++++-- .../scaffolder-backend/src/service/router.ts | 9 ++++++--- yarn.lock | 7 +++++++ 8 files changed, 50 insertions(+), 26 deletions(-) delete mode 100644 plugins/scaffolder-backend/sample-templates/react-ssr-template/hooks/pre_gen_project.sh create mode 100644 plugins/scaffolder-backend/scripts/Dockerfile diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 0edf7a8fe9..e85a65e744 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -37,6 +37,7 @@ }, "devDependencies": { "@backstage/cli": "^0.1.1-alpha.9", + "@types/dockerode": "^2.5.32", "@types/fs-extra": "^9.0.1", "@types/supertest": "^2.0.8", "supertest": "^4.0.2", diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/hooks/post_gen_project.sh b/plugins/scaffolder-backend/sample-templates/react-ssr-template/hooks/post_gen_project.sh index 033a102fed..75c35f2034 100644 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/hooks/post_gen_project.sh +++ b/plugins/scaffolder-backend/sample-templates/react-ssr-template/hooks/post_gen_project.sh @@ -1,12 +1,7 @@ -#!/bin/bash +#!/bin/sh -# package name is "__component_id__" so that yarn doesn't throw an error -# about invalid characters when running yarn commands. here we replace it with the actual name -sed -i -e "s/__component_id__/{{ cookiecutter.component_id }}/g" package.json - -# node_modules was moved out of the template folder, during the pre_gen hook, -# to avoid cookie_cutter from copying all of them. time to move it back -mv ../../node_modules.tmp ../../\{\{cookiecutter.component_id\}\}/node_modules 2>/dev/null ||: - -# move back the build directory that was moved out in the pre_gen hook (if it exists) -mv ../../build.tmp ../../\{\{cookiecutter.component_id\}\}/build 2>/dev/null ||: +# Move all template files to the root folder +mv ./* ../ +cd .. +rm -rf {{cookiecutter.component_id}} +# # # # # # # # diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/hooks/pre_gen_project.sh b/plugins/scaffolder-backend/sample-templates/react-ssr-template/hooks/pre_gen_project.sh deleted file mode 100644 index 142fda9ad9..0000000000 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/hooks/pre_gen_project.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -# no way to ignore files in cookiecutter, so move node_modules out while building -# to avoid cookiecutter from copying all of them -mv ../../\{\{cookiecutter.component_id\}\}/node_modules ../../node_modules.tmp 2>/dev/null ||: - -# cookicutter really doesn't like the next.js build directory, so if the app has -# been built from inside the template folder, that folders needs to be moved out as well -mv ../../\{\{cookiecutter.component_id\}\}/build ../../build.tmp 2>/dev/null ||: diff --git a/plugins/scaffolder-backend/sample-templates/react-ssr-template/{{cookiecutter.component_id}}/package.json b/plugins/scaffolder-backend/sample-templates/react-ssr-template/{{cookiecutter.component_id}}/package.json index a0ae26e267..6ae3e63a17 100644 --- a/plugins/scaffolder-backend/sample-templates/react-ssr-template/{{cookiecutter.component_id}}/package.json +++ b/plugins/scaffolder-backend/sample-templates/react-ssr-template/{{cookiecutter.component_id}}/package.json @@ -1,5 +1,5 @@ { - "name": "__component_id__", + "name": "{{ cookiecutter.component_id }}", "version": "0.0.0", "description": "{{ cookiecutter.description }}", "license": "UNLICENSED", diff --git a/plugins/scaffolder-backend/scripts/Dockerfile b/plugins/scaffolder-backend/scripts/Dockerfile new file mode 100644 index 0000000000..b33c7cbe64 --- /dev/null +++ b/plugins/scaffolder-backend/scripts/Dockerfile @@ -0,0 +1,11 @@ +FROM alpine:3.7 + +RUN apk add --update \ + git \ + python \ + python-dev \ + py-pip \ + g++ && \ + pip install cookiecutter && \ + apk del g++ py-pip python-dev && \ + rm -rf /var/cache/apk/* diff --git a/plugins/scaffolder-backend/src/scaffolder/templater/cookiecutter.ts b/plugins/scaffolder-backend/src/scaffolder/templater/cookiecutter.ts index ee5265fde8..cabb1d4f1e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/templater/cookiecutter.ts +++ b/plugins/scaffolder-backend/src/scaffolder/templater/cookiecutter.ts @@ -16,9 +16,18 @@ import { TemplaterBase, TemplaterRunOptions } from '.'; * limitations under the License. */ import fs from 'fs-extra'; +import Docker from 'dockerode'; export class CookieCutter implements TemplaterBase { + private docker:Docker; + constructor() { + this.docker = new Docker(); + } + public async run(options: TemplaterRunOptions): Promise { + + + // first we need to make cookiecutter.json in the directory provided with the input values. const cookieInfo = { _copy_without_render: ['.github/workflows/*'], @@ -26,7 +35,14 @@ export class CookieCutter implements TemplaterBase { }; await fs.writeJSON(`${options.directory}/cookiecutter.json`, cookieInfo); - return ''; - // run cookie cutter with new json + const realTemplatePath = await fs.promises.realpath(options.directory); + const outDir = realTemplatePath + '/result'; + + + await this.docker.run('backstage/cookiecutter', ['cookiecutter', '--no-input', '-o', '/result', '/template', '--verbose'], process.stdout, {Volumes: { '/result': {}, '/template': {}}, HostConfig: { + Binds: [`${outDir}:/result`, `${realTemplatePath}:/template`], + }}); + + return outDir; } } diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index c9b92494fd..e71593b6ba 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -64,12 +64,15 @@ export async function createRouter( const preparer = preparers.get(mockEntity); // Run the preparer for the mock entity to produce a temporary directory with template in - const path = await preparer.prepare(mockEntity); + const skeletonPath = await preparer.prepare(mockEntity); // Run the templater on the mock directory with values from the post body - await templater.run({ directory: path, values: { component_id: 'test' } }); + const templatedPath = await templater.run({ + directory: skeletonPath, + values: { component_id: 'test', description: "Something for now" }, + }); - console.warn(path); + console.warn(templatedPath); }); const app = express(); diff --git a/yarn.lock b/yarn.lock index fd351efe36..88a9861af6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3520,6 +3520,13 @@ resolved "https://registry.npmjs.org/@types/diff/-/diff-4.0.2.tgz#2e9bb89f9acc3ab0108f0f3dc4dbdcf2fff8a99c" integrity sha512-mIenTfsIe586/yzsyfql69KRnA75S8SVXQbTLpDejRrjH0QSJcpu3AUOi/Vjnt9IOsXKxPhJfGpQUNMueIU1fQ== +"@types/dockerode@^2.5.32": + version "2.5.32" + resolved "https://registry.npmjs.org/@types/dockerode/-/dockerode-2.5.32.tgz#52d3628f605f8ea65202541c59a8a6dd166384fd" + integrity sha512-TfaGOoOHxsjkWRj2sPoQ3FLmTC5mVMhZ4kzZy13U7mjtIDoloE4e7AMj5jPLbffWB6Csy5DF5e0lC9M+tnKz/A== + dependencies: + "@types/node" "*" + "@types/eslint-visitor-keys@^1.0.0": version "1.0.0" resolved "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"