Add util function and related tests

Signed-off-by: Brian Hudson <brian.r.hudson@gmail.com>
This commit is contained in:
Brian Hudson
2024-01-30 07:34:38 -05:00
parent aa91cd69ac
commit a245fad6c7
3 changed files with 57 additions and 25 deletions
@@ -33,6 +33,7 @@ import {
isFulfilled,
readFile,
writeFile,
safeEntityName,
} from './utils';
import { CodeOwnersEntry } from 'codeowners-utils';
@@ -164,18 +165,7 @@ async function fixCatalogInfoYaml(options: FixOptions) {
codeowners,
relativePath('.', yamlPath),
);
const safeName = packageJson.name
.replace(/^[^\w\s]|[^a-z0-9]$/g, '')
.replace(/[^A-Za-z0-9_\-.]+/g, '-')
.replace(/([A-Z])/g, (_, letter, index, original) => {
if (index !== 0) {
const previousChar = original[index - 1];
if (previousChar !== '-') {
return `-${letter.toLowerCase()}`;
}
}
return letter.toLowerCase();
});
const safeName = safeEntityName(packageJson.name);
let yamlJson: BackstagePackageEntity;
try {
@@ -249,18 +239,7 @@ function createOrMergeEntity(
owner: string,
existingEntity: BackstagePackageEntity | Record<string, any> = {},
): BackstagePackageEntity {
const safeEntityName = packageJson.name
.replace(/^[^\w\s]|[^a-z0-9]$/g, '')
.replace(/[^A-Za-z0-9_\-.]+/g, '-')
.replace(/([A-Z])/g, (_, letter, index, original) => {
if (index !== 0) {
const previousChar = original[index - 1];
if (previousChar !== '-') {
return `-${letter.toLowerCase()}`;
}
}
return letter.toLowerCase();
});
const entityName = safeEntityName(packageJson.name);
return {
...existingEntity,
@@ -269,7 +248,7 @@ function createOrMergeEntity(
metadata: {
...existingEntity.metadata,
// Provide default name/title/description values.
name: safeEntityName,
name: entityName,
title: packageJson.name,
...(packageJson.description && !existingEntity.metadata?.description
? { description: packageJson.description }
@@ -0,0 +1,36 @@
/*
* Copyright 2024 The Backstage Authors
*
* 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 { safeEntityName } from './utils';
describe('utils', () => {
describe('safeEntityName', () => {
it('should remove non-alphanumeric characters at the start and end', () => {
const result = safeEntityName('%entityname$');
expect(result).toBe('entityname');
});
it('should replace non-alphanumeric characters, except - and _, with -', () => {
const result = safeEntityName('entity@#name$');
expect(result).toBe('entity-name');
});
it('should replace capital letters with - followed by the same letter in lowercase', () => {
const result = safeEntityName('EntityName');
expect(result).toBe('entity-name');
});
});
});
@@ -48,3 +48,20 @@ export const isRejected = (
export const isFulfilled = <T>(
input: PromiseSettledResult<T>,
): input is PromiseFulfilledResult<T> => input.status === 'fulfilled';
/**
* Generates a suitable entity name from a package name by slugifying the given package name.
*
* @param packageName - The package name to generate an entity name from.
* @returns The generated entity name, a slugified version of the package name.
*/
export const safeEntityName = (packageName: string): string => {
return packageName
.replace(/^[^\w\s]|[^a-z0-9]$/g, '')
.replace(/[^A-Za-z0-9_\-.]+/g, '-')
.replace(
/([a-z])([A-Z])/g,
(_, a, b) => `${a}-${b.toLocaleLowerCase('en-US')}`,
)
.replace(/^(.)/, (_, a) => a.toLocaleLowerCase('en-US'));
};