Catalog-model: Add getEntitySourceLocation helper

Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com>
Signed-off-by: Johan Haals <johan.haals@gmail.com>
This commit is contained in:
Johan Haals
2021-04-14 09:59:00 +02:00
parent 54a98a7663
commit bb5055aeea
4 changed files with 86 additions and 2 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/catalog-model': patch
---
Add getEntitySourceLocation helper
@@ -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`);
});
});
@@ -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);
}
+5 -1
View File
@@ -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,