chore(scaffolder): Updating typescript issues by making the templater a required key

This commit is contained in:
blam
2020-07-13 11:53:10 +02:00
parent 87698e2fe6
commit 46c60cb54a
9 changed files with 218 additions and 9 deletions
@@ -47,7 +47,8 @@ describe('GitHubPreparer', () => {
generation: 1,
},
spec: {
type: 'cookiecutter',
type: 'website',
templater: 'cookiecutter',
path: './template',
schema: {
$schema: 'http://json-schema.org/draft-07/schema#',
@@ -39,7 +39,8 @@ describe('Helpers', () => {
generation: 1,
},
spec: {
type: 'cookiecutter',
type: 'website',
templater: 'cookiecutter',
path: './template',
schema: {
$schema: 'http://json-schema.org/draft-07/schema#',
@@ -86,7 +87,8 @@ describe('Helpers', () => {
generation: 1,
},
spec: {
type: 'cookiecutter',
type: 'website',
templater: 'cookiecutter',
path: './template',
schema: {
$schema: 'http://json-schema.org/draft-07/schema#',
@@ -131,7 +133,8 @@ describe('Helpers', () => {
generation: 1,
},
spec: {
type: 'cookiecutter',
type: 'website',
templater: 'cookiecutter',
path: './template',
schema: {
$schema: 'http://json-schema.org/draft-07/schema#',
@@ -177,7 +180,8 @@ describe('Helpers', () => {
generation: 1,
},
spec: {
type: 'cookiecutter',
type: 'website',
templater: 'cookiecutter',
path: './template',
schema: {
$schema: 'http://json-schema.org/draft-07/schema#',
@@ -221,7 +225,8 @@ describe('Helpers', () => {
generation: 1,
},
spec: {
type: 'cookiecutter',
type: 'website',
templater: 'cookiecutter',
path: './template',
schema: {
$schema: 'http://json-schema.org/draft-07/schema#',
@@ -35,8 +35,9 @@ describe('Preparers', () => {
generation: 1,
},
spec: {
type: 'cookiecutter',
templater: 'cookiecutter',
path: '.',
type: 'website',
schema: {
$schema: 'http://json-schema.org/draft-07/schema#',
required: ['storePath', 'owner'],
@@ -88,7 +89,8 @@ describe('Preparers', () => {
generation: 1,
},
spec: {
type: 'cookiecutter',
type: 'website',
templater: 'cookiecutter',
path: '.',
schema: {
$schema: 'http://json-schema.org/draft-07/schema#',
@@ -14,3 +14,4 @@
* limitations under the License.
*/
export * from './github';
export * from './types';
@@ -16,6 +16,8 @@
import { Writable, PassThrough } from 'stream';
import Docker from 'dockerode';
import fs from 'fs';
import { TemplateEntityV1alpha1 } from '@backstage/catalog-model';
import { InputError } from '@backstage/backend-common';
export type RunDockerContainerOptions = {
imageName: string;
@@ -26,6 +28,20 @@ export type RunDockerContainerOptions = {
dockerClient: Docker;
};
/**
* Gets the templater key to use for templating from the entity
* @param entity Template entity
*/
export const getTemplaterKey = (entity: TemplateEntityV1alpha1): string => {
const { templater } = entity.spec;
if (!templater) {
throw new InputError('Template does not have a required templating key');
}
return templater;
};
/**
*
* @param options the options object
@@ -16,3 +16,4 @@
export * from './cookiecutter';
export * from './types';
export * from './helpers';
export * from './templaters';
@@ -0,0 +1,125 @@
/*
* 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 { Templaters } from '.';
import { TemplateEntityV1alpha1 } from '@backstage/catalog-model';
import { CookieCutter } from './cookiecutter';
describe('Templaters', () => {
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: {
templater: 'cookiecutter',
path: '.',
type: 'website',
schema: {
$schema: 'http://json-schema.org/draft-07/schema#',
required: ['storePath', 'owner'],
properties: {
owner: {
type: 'string',
title: 'Owner',
description: 'Who is going to own this component',
},
storePath: {
type: 'string',
title: 'Store path',
description: 'GitHub store path in org/repo format',
},
},
},
},
};
it('should throw an error when the templater is not registered', () => {
const templaters = new Templaters();
expect(() => templaters.get(mockTemplate)).toThrow(
expect.objectContaining({
message: 'No templater registered for template: "cookiecutter"',
}),
);
});
it('should return the correct templater when the templater matches', () => {
const templaters = new Templaters();
const templater = new CookieCutter();
templaters.register('cookiecutter', templater);
expect(templaters.get(mockTemplate)).toBe(templater);
});
it('should throw an error if the templater does not exist in the entity', () => {
const brokenTemplate: TemplateEntityV1alpha1 = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Template',
metadata: {
annotations: {},
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: 'website',
path: '.',
templater: '',
schema: {
$schema: 'http://json-schema.org/draft-07/schema#',
required: ['storePath', 'owner'],
properties: {
owner: {
type: 'string',
title: 'Owner',
description: 'Who is going to own this component',
},
storePath: {
type: 'string',
title: 'Store path',
description: 'GitHub store path in org/repo format',
},
},
},
},
};
const templaters = new Templaters();
expect(() => templaters.get(brokenTemplate)).toThrow(
expect.objectContaining({
name: 'InputError',
message: expect.stringContaining(
'Template does not have a required templating key',
),
}),
);
});
});
@@ -0,0 +1,45 @@
/*
* 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 {
TemplaterBase,
SupportedTemplatingKey,
TemplaterBuilder,
} from './types';
import { TemplateEntityV1alpha1 } from '@backstage/catalog-model';
import { getTemplaterKey } from './helpers';
export class Templaters implements TemplaterBuilder {
private preparerMap = new Map<SupportedTemplatingKey, TemplaterBase>();
register(templaterKey: SupportedTemplatingKey, templater: TemplaterBase) {
this.preparerMap.set(templaterKey, templater);
}
get(template: TemplateEntityV1alpha1): TemplaterBase {
const templaterKey = getTemplaterKey(template);
const preparer = this.preparerMap.get(templaterKey);
if (!preparer) {
throw new Error(
`No templater registered for template: "${templaterKey}"`,
);
}
return preparer;
}
}
@@ -13,10 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { Writable } from 'stream';
import Docker from 'dockerode';
import { JsonValue } from '@backstage/config';
import { TemplateEntityV1alpha1 } from '@backstage/catalog-model';
/**
* Currently the required template values. The owner
@@ -55,3 +55,16 @@ export type TemplaterBase = {
export type TemplaterConfig = {
templater?: TemplaterBase;
};
/**
* List of supported templating options
*/
export type SupportedTemplatingKey = 'cookiecutter' | string;
/**
* The templater builder holds the templaters ready for run time
*/
export type TemplaterBuilder = {
register(protocol: SupportedTemplatingKey, templater: TemplaterBase): void;
get(template: TemplateEntityV1alpha1): TemplaterBase;
};