From bb5055aeea70f4463c00392e57a3f2465541959b Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 14 Apr 2021 09:59:00 +0200 Subject: [PATCH] Catalog-model: Add getEntitySourceLocation helper Co-authored-by: Patrik Oldsberg Signed-off-by: Johan Haals --- .changeset/metal-foxes-speak.md | 5 ++ .../src/location/helpers.test.ts | 51 ++++++++++++++++++- .../catalog-model/src/location/helpers.ts | 26 ++++++++++ packages/catalog-model/src/location/index.ts | 6 ++- 4 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 .changeset/metal-foxes-speak.md diff --git a/.changeset/metal-foxes-speak.md b/.changeset/metal-foxes-speak.md new file mode 100644 index 0000000000..45b8ae3c7c --- /dev/null +++ b/.changeset/metal-foxes-speak.md @@ -0,0 +1,5 @@ +--- +'@backstage/catalog-model': patch +--- + +Add getEntitySourceLocation helper diff --git a/packages/catalog-model/src/location/helpers.test.ts b/packages/catalog-model/src/location/helpers.test.ts index 888c79b328..3b5994b956 100644 --- a/packages/catalog-model/src/location/helpers.test.ts +++ b/packages/catalog-model/src/location/helpers.test.ts @@ -14,7 +14,11 @@ * limitations under the License. */ -import { parseLocationReference, stringifyLocationReference } from './helpers'; +import { + getEntitySourceLocation, + parseLocationReference, + stringifyLocationReference, +} from './helpers'; describe('parseLocationReference', () => { it('works for the simple case', () => { @@ -68,3 +72,48 @@ describe('stringifyLocationReference', () => { ).toThrow('Unable to stringify location reference, empty target'); }); }); + +describe('getEntitySourceLocation', () => { + it('returns the source-location', () => { + expect( + getEntitySourceLocation({ + apiVersion: 'backstage.io/v1alpha1', + kind: 'Location', + metadata: { + name: 'test', + namespace: 'default', + annotations: { + 'backstage.io/source-location': 'url:https://backstage.io/foo.yaml', + 'backstage.io/managed-by-location': 'url:https://spotify.com', + }, + }, + }), + ).toEqual({ target: 'https://backstage.io/foo.yaml', type: 'url' }); + }); + + it('returns the managed-by-location', () => { + expect( + getEntitySourceLocation({ + apiVersion: 'backstage.io/v1alpha1', + kind: 'Location', + metadata: { + name: 'test', + namespace: 'default', + annotations: { + 'backstage.io/managed-by-location': 'url:https://spotify.com', + }, + }, + }), + ).toEqual({ target: 'https://spotify.com', type: 'url' }); + }); + + it('rejects missing location annotation', () => { + expect(() => + getEntitySourceLocation({ + apiVersion: 'backstage.io/v1alpha1', + kind: 'Location', + metadata: { name: 'test', namespace: 'default' }, + }), + ).toThrow(`Entity 'location:default/test' is missing location`); + }); +}); diff --git a/packages/catalog-model/src/location/helpers.ts b/packages/catalog-model/src/location/helpers.ts index fb1be5abad..9dce67d054 100644 --- a/packages/catalog-model/src/location/helpers.ts +++ b/packages/catalog-model/src/location/helpers.ts @@ -14,6 +14,9 @@ * limitations under the License. */ +import { Entity, stringifyEntityRef } from '../entity'; +import { LOCATION_ANNOTATION, SOURCE_LOCATION_ANNOTATION } from './annotation'; + /** * Parses a string form location reference. * @@ -80,3 +83,26 @@ export function stringifyLocationReference(ref: { return `${type}:${target}`; } + +/** + * Returns the source code location of the Entity, to the extend which one exists. + * + * If the returned location type is of type 'url', the target should be readable at least + * using the UrlReader from @backstage/backend-common. If it is not of type 'url', the caller + * needs to have explicit handling of each location type or signal that it is not supported. + */ +export function getEntitySourceLocation( + entity: Entity, +): { type: string; target: string } { + const locationRef = + entity.metadata?.annotations?.[SOURCE_LOCATION_ANNOTATION] ?? + entity.metadata?.annotations?.[LOCATION_ANNOTATION]; + + if (!locationRef) { + throw new Error( + `Entity '${stringifyEntityRef(entity)}' is missing location`, + ); + } + + return parseLocationReference(locationRef); +} diff --git a/packages/catalog-model/src/location/index.ts b/packages/catalog-model/src/location/index.ts index fddc8bde37..751172c6ba 100644 --- a/packages/catalog-model/src/location/index.ts +++ b/packages/catalog-model/src/location/index.ts @@ -19,7 +19,11 @@ export { ORIGIN_LOCATION_ANNOTATION, SOURCE_LOCATION_ANNOTATION, } from './annotation'; -export { parseLocationReference, stringifyLocationReference } from './helpers'; +export { + parseLocationReference, + stringifyLocationReference, + getEntitySourceLocation, +} from './helpers'; export type { Location, LocationSpec } from './types'; export { analyzeLocationSchema,