diff --git a/plugins/scaffolder-backend/src/scaffolder/prepare/file.test.ts b/plugins/scaffolder-backend/src/scaffolder/prepare/file.test.ts new file mode 100644 index 0000000000..6ab0aa3fb0 --- /dev/null +++ b/plugins/scaffolder-backend/src/scaffolder/prepare/file.test.ts @@ -0,0 +1,50 @@ +/* + * 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 fs from 'fs-extra'; +import YAML from 'yaml'; +import { FilePreparer } from './file'; +import path from 'path'; +import { + TemplateEntityV1alpha1, + LOCATION_ANNOTATION, +} from '@backstage/catalog-model'; + +describe('File preparer', () => { + it('resolves relative path from the template', async () => { + const locationForTemplateYaml = path.resolve( + __dirname, + '../../..', + 'test/test-simple-template/template.yaml', + ); + + const [parsedDocument] = YAML.parseAllDocuments( + await fs.readFile(locationForTemplateYaml, 'utf-8'), + ); + + const template: TemplateEntityV1alpha1 = parsedDocument.toJSON(); + + template.metadata.annotations = { + [LOCATION_ANNOTATION]: `file:${locationForTemplateYaml}`, + }; + + const filePreparer = new FilePreparer(); + const resultDir = await filePreparer.prepare(template); + + expect(fs.existsSync(`${resultDir}/expected_file.ts`)).toBe(true); + expect(fs.existsSync(`${resultDir}/template.yaml`)).toBe(false); + }); +}); diff --git a/plugins/scaffolder-backend/src/scaffolder/prepare/file.ts b/plugins/scaffolder-backend/src/scaffolder/prepare/file.ts index d7d21baa29..184e1a6b1f 100644 --- a/plugins/scaffolder-backend/src/scaffolder/prepare/file.ts +++ b/plugins/scaffolder-backend/src/scaffolder/prepare/file.ts @@ -13,8 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -// import fs from 'fs-extra'; -import fs from 'fs'; +import fs from 'fs-extra'; +import path from 'path'; +import os from 'os'; import { TemplateEntityV1alpha1, LOCATION_ANNOTATION, @@ -26,14 +27,16 @@ export class FilePreparer implements PreparerBase { async prepare(template: TemplateEntityV1alpha1): Promise { const location = template?.metadata?.annotations?.[LOCATION_ANNOTATION]; - const [locationType, actualLocation] = (location ?? '').split(/:(.+)/); + const [locationType, templateEntityLocation] = (location ?? '').split( + /:(.+)/, + ); if (locationType !== 'file') { throw new InputError( `Wrong location type: ${locationType}, should be 'file'`, ); } - if (!actualLocation) { + if (!templateEntityLocation) { throw new InputError( `Couldn't parse location for template: ${template.metadata.name}`, ); @@ -41,9 +44,18 @@ export class FilePreparer implements PreparerBase { const templateId = template.metadata.name; - const tempDir = await fs.promises.mkdtemp(templateId); + const tempDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), templateId), + ); + + const parentDirectory = path.dirname(templateEntityLocation); + + await fs.copy(parentDirectory, tempDir, { + filter: src => src !== templateEntityLocation, + }); + + // TODO(blam): Need to use the `spec.path` with path.resolve to ensure that the test case for test-nested-templates will work - // await fs.copy(actualLocation, tempDir); return tempDir; } } diff --git a/plugins/scaffolder-backend/src/scaffolder/prepare/preparers.test.ts b/plugins/scaffolder-backend/src/scaffolder/prepare/preparers.test.ts new file mode 100644 index 0000000000..96e6b7d5b9 --- /dev/null +++ b/plugins/scaffolder-backend/src/scaffolder/prepare/preparers.test.ts @@ -0,0 +1,52 @@ +/* + * 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 { Preparers } from '.'; +import { TemplateEntityV1alpha1 } from '@backstage/catalog-model'; + +describe('Preparers', () => { + it('should throw an error when the preparer for the source location is not registered', () => { + const preparers = new Preparers(); + const mockTemplate: TemplateEntityV1alpha1 = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Template', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'file:/Users/blam/dev/spotify/backstage/plugins/scaffolder-backend/sample-templates/react-ssr-template/template.yaml', + }, + name: 'react-ssr-template', + title: 'React SSR Template', + description: + 'Next.js application skeleton for creating isomorphic web applications.', + uid: '7357f4c5-aa58-4a1e-9670-18931eef771f', + etag: 'YWUxZWQyY2EtZDkxMC00MDM0LWI0ODAtMDgwMWY0YzdlMWIw', + generation: 1, + }, + spec: { + type: 'cookiecutter', + path: '.', + }, + }; + + expect(() => preparers.get(mockTemplate)).toThrow( + expect.objectContaining({ + message: 'No preparer registered for type file', + }), + ); + }); + it('should return the correct preparer when the source matches'); + it('should throw an error if the srouce is not available'); +}); diff --git a/plugins/scaffolder-backend/test/test-nested-template/template-1/expected_file.ts b/plugins/scaffolder-backend/test/test-nested-template/template-1/expected_file.ts new file mode 100644 index 0000000000..19b0312029 --- /dev/null +++ b/plugins/scaffolder-backend/test/test-nested-template/template-1/expected_file.ts @@ -0,0 +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. + */ +console.warn('here!'); diff --git a/plugins/scaffolder-backend/test/test-nested-template/template.yaml b/plugins/scaffolder-backend/test/test-nested-template/template.yaml new file mode 100644 index 0000000000..713094defe --- /dev/null +++ b/plugins/scaffolder-backend/test/test-nested-template/template.yaml @@ -0,0 +1,9 @@ +apiVersion: backstage.io/v1alpha1 +kind: Template +metadata: + name: react-ssr-template + title: React SSR Template + description: Next.js application skeleton for creating isomorphic web applications. +spec: + type: cookiecutter + path: ./template-1 diff --git a/plugins/scaffolder-backend/test/test-simple-template/expected_file.ts b/plugins/scaffolder-backend/test/test-simple-template/expected_file.ts new file mode 100644 index 0000000000..19b0312029 --- /dev/null +++ b/plugins/scaffolder-backend/test/test-simple-template/expected_file.ts @@ -0,0 +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. + */ +console.warn('here!'); diff --git a/plugins/scaffolder-backend/test/test-simple-template/template.yaml b/plugins/scaffolder-backend/test/test-simple-template/template.yaml new file mode 100644 index 0000000000..7ee2132d59 --- /dev/null +++ b/plugins/scaffolder-backend/test/test-simple-template/template.yaml @@ -0,0 +1,8 @@ +apiVersion: backstage.io/v1alpha1 +kind: Template +metadata: + name: react-ssr-template + title: React SSR Template + description: Next.js application skeleton for creating isomorphic web applications. +spec: + type: cookiecutter