From d7bb95b87ab8bc6fac8cece08ff007a9f993cfcb Mon Sep 17 00:00:00 2001 From: blam Date: Fri, 1 May 2020 18:27:43 +0200 Subject: [PATCH 1/5] refactor: move to globby instead of glob library for nice promises and efficiency! --- plugins/scaffolder-backend/package.json | 2 +- .../src/lib/storage/disk.ts | 70 +++++++++---------- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 5bfde524c7..d0cec7faea 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -19,7 +19,7 @@ "dependencies": { "express": "^4.17.1", "fs-extra": "^9.0.0", - "glob": "^7.1.6", + "globby": "^11.0.0", "winston": "^3.2.1" } } diff --git a/plugins/scaffolder-backend/src/lib/storage/disk.ts b/plugins/scaffolder-backend/src/lib/storage/disk.ts index 6f3c5f14dc..985313f070 100644 --- a/plugins/scaffolder-backend/src/lib/storage/disk.ts +++ b/plugins/scaffolder-backend/src/lib/storage/disk.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import glob from 'glob'; +import globby from 'globby'; import fs from 'fs-extra'; import { logger } from '../logger'; import { Template, StorageBase as Base } from '.'; @@ -29,8 +29,9 @@ export class DiskStorage implements Base { private localIndex: DiskIndexEntry[] = []; constructor(private repoDir = `${__dirname}/../../../sample-templates`) { - console.warn(require('path').resolve(repoDir)); + } + public async list(): Promise { if (this.repository.length === 0) { await this.reindex(); @@ -59,43 +60,38 @@ export class DiskStorage implements Base { } private async index(): Promise { - return new Promise((resolve, reject) => { - glob(`${this.repoDir}/**/template-info.json`, async (err, matches) => { - if (err) { - reject(err); + const matches = await globby(`${this.repoDir}/**/template-info.json`); + + const fileContents: Array<{ + location: string; + contents: string; + }> = await Promise.all( + matches.map(async (location: string) => ({ + location, + contents: await fs.readFile(location, 'utf-8'), + })), + ); + + const validFiles = fileContents.reduce( + (diskIndexEntries: DiskIndexEntry[], currentFile) => { + try { + const parsed: Template = JSON.parse(currentFile.contents); + return [ + ...diskIndexEntries, + { location: currentFile.location, contents: parsed }, + ]; + } catch (ex) { + logger.error('Failure parsing JSON for template', { + path: currentFile.location, + }); } - const fileContents: Array<{ - location: string; - contents: string; - }> = await Promise.all( - matches.map(async (location: string) => ({ - location, - contents: await fs.readFile(location, 'utf-8'), - })), - ); + return diskIndexEntries; + }, + [], + ); + + return validFiles; - const validFiles = fileContents.reduce( - (diskIndexEntries: DiskIndexEntry[], currentFile) => { - try { - const parsed: Template = JSON.parse(currentFile.contents); - return [ - ...diskIndexEntries, - { location: currentFile.location, contents: parsed }, - ]; - } catch (ex) { - logger.error('Failure parsing JSON for template', { - path: currentFile.location, - }); - } - - return diskIndexEntries; - }, - [], - ); - - resolve(validFiles); - }); - }); } } From 31c4785cc041171abacd5bfb2fae7e1cf4cc61cf Mon Sep 17 00:00:00 2001 From: blam Date: Sun, 3 May 2020 15:42:53 +0200 Subject: [PATCH 2/5] chore(scaffolder): Updating dependency graph to include docker api --- plugins/scaffolder-backend/package.json | 1 + yarn.lock | 103 ++++++++++++++++++++++-- 2 files changed, 99 insertions(+), 5 deletions(-) diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index d0cec7faea..da4a86306e 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -17,6 +17,7 @@ "supertest": "^4.0.2" }, "dependencies": { + "dockerode": "^3.2.0", "express": "^4.17.1", "fs-extra": "^9.0.0", "globby": "^11.0.0", diff --git a/yarn.lock b/yarn.lock index 79eac2cb21..585a0f98ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5227,7 +5227,7 @@ asn1.js@^4.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" -asn1@~0.2.3: +asn1@~0.2.0, asn1@~0.2.3: version "0.2.4" resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== @@ -5827,7 +5827,7 @@ batch@0.6.1: resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= -bcrypt-pbkdf@^1.0.0: +bcrypt-pbkdf@^1.0.0, bcrypt-pbkdf@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= @@ -5878,6 +5878,15 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" +bl@^4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz#52b71e9088515d0606d9dd9cc7aa48dc1f98e73a" + integrity sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + bluebird@3.7.2, bluebird@^3.3.5, bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5: version "3.7.2" resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" @@ -6137,6 +6146,14 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" +buffer@^5.5.0: + version "5.6.0" + resolved "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" + integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + builtin-modules@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz#aad97c15131eb76b65b50ef208e7584cd76a7484" @@ -6957,7 +6974,7 @@ concat-stream@^1.5.0, concat-stream@^1.6.2: readable-stream "^2.2.2" typedarray "^0.0.6" -concat-stream@^2.0.0: +concat-stream@^2.0.0, concat-stream@~2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1" integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A== @@ -8175,6 +8192,25 @@ dns-txt@^2.0.2: dependencies: buffer-indexof "^1.0.0" +docker-modem@^2.1.0: + version "2.1.3" + resolved "https://registry.npmjs.org/docker-modem/-/docker-modem-2.1.3.tgz#15432225f63db02eb5de4bb9a621b7293e5f264d" + integrity sha512-cwaRptBmYZwu/FyhGcqBm2MzXA77W2/E6eVkpOZVDk6PkI9Bjj84xPrXiHMA+OWjzNy+DFjgKh8Q+1hMR7/OHg== + dependencies: + debug "^4.1.1" + readable-stream "^3.5.0" + split-ca "^1.0.1" + ssh2 "^0.8.7" + +dockerode@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/dockerode/-/dockerode-3.2.0.tgz#80e5bd9c2a988bdde4c995ae4aa2584fa0166c23" + integrity sha512-C+y/W4Kks7YLBsfUOTMkk1IVilb4cdj+rE+UZ5hnE+rpcn2frSs7kX+6H8GteTqHcv8sln+GyxuP1qdno3IzIw== + dependencies: + concat-stream "~2.0.0" + docker-modem "^2.1.0" + tar-fs "~2.0.1" + doctrine@1.5.0: version "1.5.0" resolved "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" @@ -8492,7 +8528,7 @@ encoding@^0.1.11: dependencies: iconv-lite "~0.4.13" -end-of-stream@^1.0.0, end-of-stream@^1.1.0: +end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== @@ -9735,6 +9771,11 @@ from@~0: resolved "https://registry.npmjs.org/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4= +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + fs-extra@8.1.0, fs-extra@^8.0.1, fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" @@ -14316,6 +14357,11 @@ mixin-object@^2.0.1: for-in "^0.1.3" is-extendable "^0.1.1" +mkdirp-classic@^0.5.2: + version "0.5.2" + resolved "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.2.tgz#54c441ce4c96cd7790e10b41a87aa51068ecab2b" + integrity sha512-ejdnDQcR75gwknmMw/tx02AuRs8jCtqFoFqDZMjiNxsu85sRIJVXDKHuLYvUUPRBUtV2FpSZa9bL1BUa3BdR2g== + mkdirp-promise@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1" @@ -17591,7 +17637,7 @@ read@1, read@~1.0.1, read@~1.0.7: string_decoder "~1.1.1" util-deprecate "~1.0.1" -"readable-stream@2 || 3", readable-stream@^3.0.2, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.6.0: +"readable-stream@2 || 3", readable-stream@^3.0.2, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -18974,6 +19020,11 @@ spdy@^4.0.1: select-hose "^2.0.0" spdy-transport "^3.0.0" +split-ca@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz#6c83aff3692fa61256e0cd197e05e9de157691a6" + integrity sha1-bIOv82kvphJW4M0ZfgXp3hV2kaY= + split-on-first@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" @@ -19019,6 +19070,22 @@ sprintf-js@~1.0.2: resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= +ssh2-streams@~0.4.10: + version "0.4.10" + resolved "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.4.10.tgz#48ef7e8a0e39d8f2921c30521d56dacb31d23a34" + integrity sha512-8pnlMjvnIZJvmTzUIIA5nT4jr2ZWNNVHwyXfMGdRJbug9TpI3kd99ffglgfSWqujVv/0gxwMsDn9j9RVst8yhQ== + dependencies: + asn1 "~0.2.0" + bcrypt-pbkdf "^1.0.2" + streamsearch "~0.1.2" + +ssh2@^0.8.7: + version "0.8.9" + resolved "https://registry.npmjs.org/ssh2/-/ssh2-0.8.9.tgz#54da3a6c4ba3daf0d8477a538a481326091815f3" + integrity sha512-GmoNPxWDMkVpMFa9LVVzQZHF6EW3WKmBwL+4/GeILf2hFmix5Isxm7Amamo8o7bHiU0tC+wXsGcUXOxp8ChPaw== + dependencies: + ssh2-streams "~0.4.10" + sshpk@^1.7.0: version "1.16.1" resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" @@ -19197,6 +19264,11 @@ stream-shift@^1.0.0: resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== +streamsearch@~0.1.2: + version "0.1.2" + resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" + integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= + strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" @@ -19627,6 +19699,27 @@ tapable@^1.0.0, tapable@^1.1.3: resolved "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== +tar-fs@~2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz#e44086c1c60d31a4f0cf893b1c4e155dabfae9e2" + integrity sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.0.0" + +tar-stream@^2.0.0: + version "2.1.2" + resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz#6d5ef1a7e5783a95ff70b69b97455a5968dc1325" + integrity sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q== + dependencies: + bl "^4.0.1" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + tar@^4.4.10, tar@^4.4.12, tar@^4.4.13, tar@^4.4.8: version "4.4.13" resolved "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" From 1af6cbea8da086c050e59c54c0ec9aeeab2998c6 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 4 May 2020 20:39:13 +0200 Subject: [PATCH 3/5] feat(scaffolder): Bring up to date with the latest changes in the inventory service --- packages/backend/src/index.ts | 11 +++- plugins/scaffolder-backend/package.json | 6 ++ plugins/scaffolder-backend/src/index.ts | 30 +--------- plugins/scaffolder-backend/src/lib/logger.ts | 41 ------------- plugins/scaffolder-backend/src/run.ts | 34 +++++++++++ .../src/scaffolder/index.ts | 20 +++++++ .../{lib => scaffolder}/storage/disk.test.ts | 10 ++-- .../src/{lib => scaffolder}/storage/disk.ts | 11 ++-- .../{lib => scaffolder}/storage/index.test.ts | 9 ++- .../src/{lib => scaffolder}/storage/index.ts | 7 ++- .../templater/cookiecutter.ts | 0 .../{lib => scaffolder}/templater/index.ts | 9 +-- .../scaffolder-backend/src/service/router.ts | 54 +++++++++++++++++ .../src/service/standaloneApplication.ts | 55 +++++++++++++++++ .../src/service/standaloneServer.ts | 60 +++++++++++++++++++ 15 files changed, 266 insertions(+), 91 deletions(-) delete mode 100644 plugins/scaffolder-backend/src/lib/logger.ts create mode 100644 plugins/scaffolder-backend/src/run.ts create mode 100644 plugins/scaffolder-backend/src/scaffolder/index.ts rename plugins/scaffolder-backend/src/{lib => scaffolder}/storage/disk.test.ts (88%) rename plugins/scaffolder-backend/src/{lib => scaffolder}/storage/disk.ts (88%) rename plugins/scaffolder-backend/src/{lib => scaffolder}/storage/index.test.ts (85%) rename plugins/scaffolder-backend/src/{lib => scaffolder}/storage/index.ts (91%) rename plugins/scaffolder-backend/src/{lib => scaffolder}/templater/cookiecutter.ts (100%) rename plugins/scaffolder-backend/src/{lib => scaffolder}/templater/index.ts (88%) create mode 100644 plugins/scaffolder-backend/src/service/router.ts create mode 100644 plugins/scaffolder-backend/src/service/standaloneApplication.ts create mode 100644 plugins/scaffolder-backend/src/service/standaloneServer.ts diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index f8456a0e34..a22befd794 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -33,7 +33,11 @@ import { createRouter as inventoryRouter, StaticInventory, } from '@backstage/plugin-inventory-backend'; -import { createScaffolder } from '@backstage/plugin-scaffolder-backend'; +import { + createRouter as scaffolderRouter, + DiskStorage, + CookieCutter, +} from '@backstage/plugin-scaffolder-backend'; import compression from 'compression'; import cors from 'cors'; import express from 'express'; @@ -54,6 +58,9 @@ async function main() { ]), ); + const storage = new DiskStorage({ logger }); + const templater = new CookieCutter(); + const app = express(); app.use(helmet()); @@ -62,7 +69,7 @@ async function main() { app.use(express.json()); app.use(requestLoggingHandler()); app.use('/inventory', await inventoryRouter({ inventory, logger })); - app.use('/scaffolder', createScaffolder()); + app.use('/scaffolder', await scaffolderRouter({ storage, templater, logger })); app.use(notFoundHandler()); app.use(errorHandler()); diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index da4a86306e..ce1161a208 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -17,10 +17,16 @@ "supertest": "^4.0.2" }, "dependencies": { + "@backstage/backend-common": "0.1.1-alpha.4", "dockerode": "^3.2.0", "express": "^4.17.1", "fs-extra": "^9.0.0", "globby": "^11.0.0", + "compression": "^1.7.4", + "cors": "^2.8.5", + "express-promise-router": "^3.0.3", + "helmet": "^3.22.0", + "morgan": "^1.10.0", "winston": "^3.2.1" } } diff --git a/plugins/scaffolder-backend/src/index.ts b/plugins/scaffolder-backend/src/index.ts index 8c790c51f9..c461bfede6 100644 --- a/plugins/scaffolder-backend/src/index.ts +++ b/plugins/scaffolder-backend/src/index.ts @@ -14,31 +14,5 @@ * limitations under the License. */ -import { TemplaterConfig, createTemplater } from './lib/templater'; -import { createStorage, StorageConfig } from './lib/storage'; -import express from 'express'; - -export const createScaffolder = (config?: TemplaterConfig & StorageConfig) => { - const store = createStorage(config); - - const templater = createTemplater(config); - - const router = express.Router(); - - router.get('/v1/templates', async (_, res) => { - const templates = await store.list(); - res.status(200).json(templates); - }); - - router.post('/v1/job/create', async (_, res) => { - // TODO(blam): Actually make this function work' - - const mock = 'templateid'; - res.status(201).json({ accepted: true }); - - const path = await store.prepare(mock); - await templater.run({ directory: path, values: { componentId: 'test' } }); - }); - - return router; -}; +export * from './scaffolder'; +export * from './service/router'; diff --git a/plugins/scaffolder-backend/src/lib/logger.ts b/plugins/scaffolder-backend/src/lib/logger.ts deleted file mode 100644 index c3a4a4e26c..0000000000 --- a/plugins/scaffolder-backend/src/lib/logger.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import * as winston from 'winston'; - -export const logger = winston.createLogger({ - level: 'info', - format: winston.format.json(), - transports: [ - // - // - Write all logs with level `error` and below to `error.log` - // - Write all logs with level `info` and below to `combined.log` - // - new winston.transports.File({ filename: 'error.log', level: 'error' }), - new winston.transports.File({ filename: 'combined.log' }), - ], -}); - -// -// If we're not in production then log to the `console` with the format: -// `${info.level}: ${info.message} JSON.stringify({ ...rest }) ` -// -if (process.env.NODE_ENV !== 'production') { - logger.add( - new winston.transports.Console({ - format: winston.format.simple(), - }), - ); -} diff --git a/plugins/scaffolder-backend/src/run.ts b/plugins/scaffolder-backend/src/run.ts new file mode 100644 index 0000000000..133aad163e --- /dev/null +++ b/plugins/scaffolder-backend/src/run.ts @@ -0,0 +1,34 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getRootLogger } from '@backstage/backend-common'; +import { startStandaloneServer } from './service/standaloneServer'; + +const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 3004; +const enableCors = process.env.PLUGIN_CORS + ? Boolean(process.env.PLUGIN_CORS) + : false; +const logger = getRootLogger(); + +startStandaloneServer({ port, enableCors, logger }).catch((err) => { + logger.error(err); + process.exit(1); +}); + +process.on('SIGINT', () => { + logger.info('CTRL+C pressed; exiting.'); + process.exit(0); +}); diff --git a/plugins/scaffolder-backend/src/scaffolder/index.ts b/plugins/scaffolder-backend/src/scaffolder/index.ts new file mode 100644 index 0000000000..a665b32ead --- /dev/null +++ b/plugins/scaffolder-backend/src/scaffolder/index.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './storage'; +export * from './templater'; + +export * from './storage/disk'; +export * from './templater/cookiecutter'; diff --git a/plugins/scaffolder-backend/src/lib/storage/disk.test.ts b/plugins/scaffolder-backend/src/scaffolder/storage/disk.test.ts similarity index 88% rename from plugins/scaffolder-backend/src/lib/storage/disk.test.ts rename to plugins/scaffolder-backend/src/scaffolder/storage/disk.test.ts index d06d56a519..92c9d3c37f 100644 --- a/plugins/scaffolder-backend/src/lib/storage/disk.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/storage/disk.test.ts @@ -15,6 +15,7 @@ */ import { DiskStorage } from './disk'; import * as path from 'path'; +import { Logger } from 'winston'; describe('Disk Storage', () => { it('should load a simple template from a simple directory', async () => { const testTemplateDir = path.resolve( @@ -23,7 +24,7 @@ describe('Disk Storage', () => { ); const templateInfo = require(`${testTemplateDir}/mock-template/template-info.json`); - const repository = new DiskStorage(testTemplateDir); + const repository = new DiskStorage({ directory: testTemplateDir}); await repository.reindex(); @@ -42,7 +43,8 @@ describe('Disk Storage', () => { '../../../test/mock-multiple-templates-dir', ); - const repository = new DiskStorage(testTemplateDir); + const repository = new DiskStorage({ directory: testTemplateDir}); + await repository.reindex(); @@ -57,7 +59,7 @@ describe('Disk Storage', () => { '/some-folder-that-deffo-does-not-exist', ); - const repository = new DiskStorage(testTemplateDir); + const repository = new DiskStorage({ directory: testTemplateDir}); await repository.reindex(); @@ -72,7 +74,7 @@ describe('Disk Storage', () => { '../../../test/mock-failing-template-dir', ); - const repository = new DiskStorage(testTemplateDir); + const repository = new DiskStorage({ directory: testTemplateDir}); await repository.reindex(); diff --git a/plugins/scaffolder-backend/src/lib/storage/disk.ts b/plugins/scaffolder-backend/src/scaffolder/storage/disk.ts similarity index 88% rename from plugins/scaffolder-backend/src/lib/storage/disk.ts rename to plugins/scaffolder-backend/src/scaffolder/storage/disk.ts index 985313f070..860321d2e9 100644 --- a/plugins/scaffolder-backend/src/lib/storage/disk.ts +++ b/plugins/scaffolder-backend/src/scaffolder/storage/disk.ts @@ -16,8 +16,8 @@ import globby from 'globby'; import fs from 'fs-extra'; -import { logger } from '../logger'; import { Template, StorageBase as Base } from '.'; +import { Logger } from 'winston'; interface DiskIndexEntry { contents: Template; @@ -28,8 +28,11 @@ export class DiskStorage implements Base { private repository: Template[] = []; private localIndex: DiskIndexEntry[] = []; - constructor(private repoDir = `${__dirname}/../../../sample-templates`) { - + private repoDir: string; + private logger?: Logger; + constructor({ directory = `${__dirname}/../../../sample-templates`, logger }: { directory?: string, logger?: Logger }) { + this.repoDir = directory; + this.logger = logger; } public async list(): Promise { @@ -81,7 +84,7 @@ export class DiskStorage implements Base { { location: currentFile.location, contents: parsed }, ]; } catch (ex) { - logger.error('Failure parsing JSON for template', { + this.logger?.error('Failure parsing JSON for template', { path: currentFile.location, }); } diff --git a/plugins/scaffolder-backend/src/lib/storage/index.test.ts b/plugins/scaffolder-backend/src/scaffolder/storage/index.test.ts similarity index 85% rename from plugins/scaffolder-backend/src/lib/storage/index.test.ts rename to plugins/scaffolder-backend/src/scaffolder/storage/index.test.ts index 2f44936023..fa3967f30a 100644 --- a/plugins/scaffolder-backend/src/lib/storage/index.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/storage/index.test.ts @@ -14,6 +14,7 @@ * limitations under the License. */ import { StorageBase, createStorage } from '.'; +import winston from 'winston'; describe('Storage Interface Test', () => { const mockStore = new (class MockStorage implements StorageBase { @@ -28,17 +29,19 @@ describe('Storage Interface Test', () => { }; })(); + const logger = winston.createLogger(); + afterEach(() => mockStore.reset()); it('should call list of the set repo when calling list', async () => { - const store = createStorage({ store: mockStore }); + const store = createStorage({ store: mockStore, logger }); await store.list(); expect(mockStore.list).toHaveBeenCalled(); }); it('should reindex on the repo when calling reindex', async () => { - const store = createStorage({ store: mockStore }); + const store = createStorage({ store: mockStore, logger }); await store.reindex(); @@ -46,7 +49,7 @@ describe('Storage Interface Test', () => { }); it('should call prepare with the correct id when calling prepare', async () => { - const store = createStorage({ store: mockStore }); + const store = createStorage({ store: mockStore, logger }); await store.prepare('testid'); diff --git a/plugins/scaffolder-backend/src/lib/storage/index.ts b/plugins/scaffolder-backend/src/scaffolder/storage/index.ts similarity index 91% rename from plugins/scaffolder-backend/src/lib/storage/index.ts rename to plugins/scaffolder-backend/src/scaffolder/storage/index.ts index 20677614d6..45e7c038d7 100644 --- a/plugins/scaffolder-backend/src/lib/storage/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/storage/index.ts @@ -1,4 +1,4 @@ -import { DiskStorage } from './disk'; +import { Logger } from "winston"; /* * Copyright 2020 Spotify AB @@ -33,6 +33,7 @@ export abstract class StorageBase { export interface StorageConfig { store?: StorageBase; + logger?: Logger; } class Storage implements StorageBase { @@ -48,7 +49,7 @@ class Storage implements StorageBase { } export const createStorage = ( - config: StorageConfig = { store: new DiskStorage() }, + storageConfig: StorageConfig, ): StorageBase => { - return new Storage(config); + return new Storage(storageConfig); }; diff --git a/plugins/scaffolder-backend/src/lib/templater/cookiecutter.ts b/plugins/scaffolder-backend/src/scaffolder/templater/cookiecutter.ts similarity index 100% rename from plugins/scaffolder-backend/src/lib/templater/cookiecutter.ts rename to plugins/scaffolder-backend/src/scaffolder/templater/cookiecutter.ts diff --git a/plugins/scaffolder-backend/src/lib/templater/index.ts b/plugins/scaffolder-backend/src/scaffolder/templater/index.ts similarity index 88% rename from plugins/scaffolder-backend/src/lib/templater/index.ts rename to plugins/scaffolder-backend/src/scaffolder/templater/index.ts index b7d7edf243..21ea10db7e 100644 --- a/plugins/scaffolder-backend/src/lib/templater/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/templater/index.ts @@ -14,11 +14,10 @@ * limitations under the License. */ -import { CookieCutter } from './cookiecutter'; - export interface RequiredTemplateValues { componentId: string; } + export interface TemplaterRunOptions { directory: string; values: RequiredTemplateValues & object; @@ -45,8 +44,6 @@ class Templater implements TemplaterBase { } } -export const createTemplater = ( - config: TemplaterConfig = { templater: new CookieCutter() }, -): TemplaterBase => { - return new Templater(config); +export const createTemplater = (templaterConfig: TemplaterConfig): TemplaterBase => { + return new Templater(templaterConfig); }; diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts new file mode 100644 index 0000000000..f1bc9c0d8f --- /dev/null +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -0,0 +1,54 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import { Logger } from 'winston'; +import Router from 'express-promise-router'; +import express from 'express'; +import { StorageBase, TemplaterBase } from '../scaffolder'; + +export interface RouterOptions { + storage: StorageBase; + templater: TemplaterBase, + logger: Logger; +} + +export async function createRouter( + options: RouterOptions, +): Promise { + const router = Router(); + const {storage, templater, logger: parentLogger} = options; + const logger = parentLogger.child({ plugin: 'scaffolder' }); + + router + .get('/v1/templates', async (_, res) => { + const templates = await storage.list(); + res.status(200).json(templates); + }).post('/v1/job/create', async (_, res) => { + // TODO(blam): Actually make this function work + const mock = 'templateid'; + res.status(201).json({ accepted: true }); + + const path = await storage.prepare(mock); + await templater.run({ directory: path, values: { componentId: 'test' } }); + }); + + const app = express(); + app.set('logger', logger); + app.use('/', router); + + return app; +} diff --git a/plugins/scaffolder-backend/src/service/standaloneApplication.ts b/plugins/scaffolder-backend/src/service/standaloneApplication.ts new file mode 100644 index 0000000000..1b9f0f1e7b --- /dev/null +++ b/plugins/scaffolder-backend/src/service/standaloneApplication.ts @@ -0,0 +1,55 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + errorHandler, + notFoundHandler, + requestLoggingHandler, +} from '@backstage/backend-common'; +import compression from 'compression'; +import cors from 'cors'; +import express from 'express'; +import helmet from 'helmet'; +import { Logger } from 'winston'; +import { StorageBase, TemplaterBase } from '../scaffolder'; +import { createRouter } from './router'; + +export interface ApplicationOptions { + enableCors: boolean; + storage: StorageBase; + templater: TemplaterBase; + logger: Logger; +} + +export async function createStandaloneApplication( + options: ApplicationOptions, +): Promise { + const { enableCors, storage, templater, logger } = options; + const app = express(); + + app.use(helmet()); + if (enableCors) { + app.use(cors()); + } + app.use(compression()); + app.use(express.json()); + app.use(requestLoggingHandler()); + app.use('/', await createRouter({ templater, storage, logger })); + app.use(notFoundHandler()); + app.use(errorHandler()); + + return app; +} diff --git a/plugins/scaffolder-backend/src/service/standaloneServer.ts b/plugins/scaffolder-backend/src/service/standaloneServer.ts new file mode 100644 index 0000000000..fc980875bc --- /dev/null +++ b/plugins/scaffolder-backend/src/service/standaloneServer.ts @@ -0,0 +1,60 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Server } from 'http'; +import { Logger } from 'winston'; +import { + createStorage, + createTemplater, + DiskStorage, + CookieCutter, +} from '../scaffolder'; +import { createStandaloneApplication } from './standaloneApplication'; + +export interface ServerOptions { + port: number; + enableCors: boolean; + logger: Logger; +} + +export async function startStandaloneServer( + options: ServerOptions, +): Promise { + const logger = options.logger.child({ service: 'scaffolder-backend' }); + const store = new DiskStorage({ logger }); + const templater = new CookieCutter(); + logger.debug('Creating application...'); + + const app = await createStandaloneApplication({ + enableCors: options.enableCors, + storage: createStorage({ store, logger }), + templater: createTemplater({ templater }), + logger, + }); + + logger.debug('Starting application server...'); + return await new Promise((resolve, reject) => { + const server = app.listen(options.port, (err?: Error) => { + if (err) { + reject(err); + return; + } + + logger.info(`Listening on port ${options.port}`); + resolve(server); + }); + }); +} From e3ab86103852fa2a663b06379906ba492f4b234a Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 4 May 2020 20:54:59 +0200 Subject: [PATCH 4/5] chore: fixing eslint config so we can use some great optional?.chaining?.stuff --- packages/cli/config/eslint.backend.js | 2 ++ packages/cli/config/eslint.js | 2 ++ plugins/scaffolder-backend/.eslintrc.js | 3 ++- plugins/scaffolder-backend/src/scaffolder/storage/disk.test.ts | 2 +- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/cli/config/eslint.backend.js b/packages/cli/config/eslint.backend.js index ef6e513cf5..619d3c72e0 100644 --- a/packages/cli/config/eslint.backend.js +++ b/packages/cli/config/eslint.backend.js @@ -46,6 +46,8 @@ module.exports = { bundledDependencies: true, }, ], + 'no-unused-expressions': 'off', + '@typescript-eslint/no-unused-expressions': 'error', '@typescript-eslint/no-unused-vars': [ 'warn', { vars: 'all', args: 'after-used', ignoreRestSiblings: true }, diff --git a/packages/cli/config/eslint.js b/packages/cli/config/eslint.js index 230a95c324..6de2cf75d5 100644 --- a/packages/cli/config/eslint.js +++ b/packages/cli/config/eslint.js @@ -51,6 +51,8 @@ module.exports = { bundledDependencies: true, }, ], + 'no-unused-expressions': 'off', + '@typescript-eslint/no-unused-expressions': 'error', '@typescript-eslint/no-unused-vars': [ 'warn', { vars: 'all', args: 'after-used', ignoreRestSiblings: true }, diff --git a/plugins/scaffolder-backend/.eslintrc.js b/plugins/scaffolder-backend/.eslintrc.js index 56b9c0bb2e..8475cfd0b8 100644 --- a/plugins/scaffolder-backend/.eslintrc.js +++ b/plugins/scaffolder-backend/.eslintrc.js @@ -1,8 +1,9 @@ module.exports = { - extends: [require.resolve('@backstage/cli/config/eslint')], + extends: [require.resolve('@backstage/cli/config/eslint.backend')], ignorePatterns: ['sample-templates/'], rules: { 'no-console': 0, // Permitted in console programs 'new-cap': ['error', { capIsNew: false }], // Because Express constructs things e.g. like 'const r = express.Router()' + }, }; diff --git a/plugins/scaffolder-backend/src/scaffolder/storage/disk.test.ts b/plugins/scaffolder-backend/src/scaffolder/storage/disk.test.ts index 92c9d3c37f..a8120a1798 100644 --- a/plugins/scaffolder-backend/src/scaffolder/storage/disk.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/storage/disk.test.ts @@ -15,7 +15,7 @@ */ import { DiskStorage } from './disk'; import * as path from 'path'; -import { Logger } from 'winston'; + describe('Disk Storage', () => { it('should load a simple template from a simple directory', async () => { const testTemplateDir = path.resolve( From 26094f82e313846430c61c5376d7c661b4229fd4 Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 5 May 2020 10:22:27 +0200 Subject: [PATCH 5/5] chore: prettier is now automagically enabled, and fixing some pr review comments --- plugins/scaffolder-backend/.eslintrc.js | 1 - .../src/scaffolder/storage/disk.test.ts | 9 ++--- .../src/scaffolder/storage/disk.ts | 39 +++++++++---------- .../src/scaffolder/storage/index.ts | 6 +-- .../src/scaffolder/templater/index.ts | 4 +- .../scaffolder-backend/src/service/router.ts | 10 ++--- .../src/service/standaloneApplication.ts | 2 +- .../src/service/standaloneServer.ts | 2 +- prettier.config.js | 15 +++++++ 9 files changed, 50 insertions(+), 38 deletions(-) diff --git a/plugins/scaffolder-backend/.eslintrc.js b/plugins/scaffolder-backend/.eslintrc.js index 8475cfd0b8..19c9ad7395 100644 --- a/plugins/scaffolder-backend/.eslintrc.js +++ b/plugins/scaffolder-backend/.eslintrc.js @@ -4,6 +4,5 @@ module.exports = { rules: { 'no-console': 0, // Permitted in console programs 'new-cap': ['error', { capIsNew: false }], // Because Express constructs things e.g. like 'const r = express.Router()' - }, }; diff --git a/plugins/scaffolder-backend/src/scaffolder/storage/disk.test.ts b/plugins/scaffolder-backend/src/scaffolder/storage/disk.test.ts index a8120a1798..9cebb0d380 100644 --- a/plugins/scaffolder-backend/src/scaffolder/storage/disk.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/storage/disk.test.ts @@ -24,7 +24,7 @@ describe('Disk Storage', () => { ); const templateInfo = require(`${testTemplateDir}/mock-template/template-info.json`); - const repository = new DiskStorage({ directory: testTemplateDir}); + const repository = new DiskStorage({ directory: testTemplateDir }); await repository.reindex(); @@ -43,8 +43,7 @@ describe('Disk Storage', () => { '../../../test/mock-multiple-templates-dir', ); - const repository = new DiskStorage({ directory: testTemplateDir}); - + const repository = new DiskStorage({ directory: testTemplateDir }); await repository.reindex(); @@ -59,7 +58,7 @@ describe('Disk Storage', () => { '/some-folder-that-deffo-does-not-exist', ); - const repository = new DiskStorage({ directory: testTemplateDir}); + const repository = new DiskStorage({ directory: testTemplateDir }); await repository.reindex(); @@ -74,7 +73,7 @@ describe('Disk Storage', () => { '../../../test/mock-failing-template-dir', ); - const repository = new DiskStorage({ directory: testTemplateDir}); + const repository = new DiskStorage({ directory: testTemplateDir }); await repository.reindex(); diff --git a/plugins/scaffolder-backend/src/scaffolder/storage/disk.ts b/plugins/scaffolder-backend/src/scaffolder/storage/disk.ts index 860321d2e9..28236cb86f 100644 --- a/plugins/scaffolder-backend/src/scaffolder/storage/disk.ts +++ b/plugins/scaffolder-backend/src/scaffolder/storage/disk.ts @@ -30,7 +30,13 @@ export class DiskStorage implements Base { private repoDir: string; private logger?: Logger; - constructor({ directory = `${__dirname}/../../../sample-templates`, logger }: { directory?: string, logger?: Logger }) { + constructor({ + directory = `${__dirname}/../../../sample-templates`, + logger, + }: { + directory?: string; + logger?: Logger; + }) { this.repoDir = directory; this.logger = logger; } @@ -75,26 +81,19 @@ export class DiskStorage implements Base { })), ); - const validFiles = fileContents.reduce( - (diskIndexEntries: DiskIndexEntry[], currentFile) => { - try { - const parsed: Template = JSON.parse(currentFile.contents); - return [ - ...diskIndexEntries, - { location: currentFile.location, contents: parsed }, - ]; - } catch (ex) { - this.logger?.error('Failure parsing JSON for template', { - path: currentFile.location, - }); - } + const validFiles: DiskIndexEntry[] = []; + + for (const file of fileContents) { + try { + const contents: Template = JSON.parse(file.contents); + validFiles.push({ location: file.location, contents }); + } catch (ex) { + this.logger?.error('Failure parsing JSON for template', { + path: file.location, + }); + } + } - return diskIndexEntries; - }, - [], - ); - return validFiles; - } } diff --git a/plugins/scaffolder-backend/src/scaffolder/storage/index.ts b/plugins/scaffolder-backend/src/scaffolder/storage/index.ts index 45e7c038d7..4d16224ef7 100644 --- a/plugins/scaffolder-backend/src/scaffolder/storage/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/storage/index.ts @@ -1,4 +1,4 @@ -import { Logger } from "winston"; +import { Logger } from 'winston'; /* * Copyright 2020 Spotify AB @@ -48,8 +48,6 @@ class Storage implements StorageBase { reindex = () => this.store!.reindex(); } -export const createStorage = ( - storageConfig: StorageConfig, -): StorageBase => { +export const createStorage = (storageConfig: StorageConfig): StorageBase => { return new Storage(storageConfig); }; diff --git a/plugins/scaffolder-backend/src/scaffolder/templater/index.ts b/plugins/scaffolder-backend/src/scaffolder/templater/index.ts index 21ea10db7e..6f728d4829 100644 --- a/plugins/scaffolder-backend/src/scaffolder/templater/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/templater/index.ts @@ -44,6 +44,8 @@ class Templater implements TemplaterBase { } } -export const createTemplater = (templaterConfig: TemplaterConfig): TemplaterBase => { +export const createTemplater = ( + templaterConfig: TemplaterConfig, +): TemplaterBase => { return new Templater(templaterConfig); }; diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index f1bc9c0d8f..97c177b915 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -14,7 +14,6 @@ * limitations under the License. */ - import { Logger } from 'winston'; import Router from 'express-promise-router'; import express from 'express'; @@ -22,7 +21,7 @@ import { StorageBase, TemplaterBase } from '../scaffolder'; export interface RouterOptions { storage: StorageBase; - templater: TemplaterBase, + templater: TemplaterBase; logger: Logger; } @@ -30,21 +29,22 @@ export async function createRouter( options: RouterOptions, ): Promise { const router = Router(); - const {storage, templater, logger: parentLogger} = options; + const { storage, templater, logger: parentLogger } = options; const logger = parentLogger.child({ plugin: 'scaffolder' }); router .get('/v1/templates', async (_, res) => { const templates = await storage.list(); res.status(200).json(templates); - }).post('/v1/job/create', async (_, res) => { + }) + .post('/v1/jobs', async (_, res) => { // TODO(blam): Actually make this function work const mock = 'templateid'; res.status(201).json({ accepted: true }); const path = await storage.prepare(mock); await templater.run({ directory: path, values: { componentId: 'test' } }); - }); + }); const app = express(); app.set('logger', logger); diff --git a/plugins/scaffolder-backend/src/service/standaloneApplication.ts b/plugins/scaffolder-backend/src/service/standaloneApplication.ts index 1b9f0f1e7b..3ff1de01eb 100644 --- a/plugins/scaffolder-backend/src/service/standaloneApplication.ts +++ b/plugins/scaffolder-backend/src/service/standaloneApplication.ts @@ -30,7 +30,7 @@ import { createRouter } from './router'; export interface ApplicationOptions { enableCors: boolean; storage: StorageBase; - templater: TemplaterBase; + templater: TemplaterBase; logger: Logger; } diff --git a/plugins/scaffolder-backend/src/service/standaloneServer.ts b/plugins/scaffolder-backend/src/service/standaloneServer.ts index fc980875bc..b89e806f72 100644 --- a/plugins/scaffolder-backend/src/service/standaloneServer.ts +++ b/plugins/scaffolder-backend/src/service/standaloneServer.ts @@ -37,7 +37,7 @@ export async function startStandaloneServer( const store = new DiskStorage({ logger }); const templater = new CookieCutter(); logger.debug('Creating application...'); - + const app = await createStandaloneApplication({ enableCors: options.enableCors, storage: createStorage({ store, logger }), diff --git a/prettier.config.js b/prettier.config.js index 93df970dd6..e12d35a880 100644 --- a/prettier.config.js +++ b/prettier.config.js @@ -1 +1,16 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ module.exports = require('@spotify/web-scripts/config/prettier.config.js');