From dd35e9e59f11cddedcfa4d519f689f46ed3c6a4b Mon Sep 17 00:00:00 2001 From: Eric Peterson Date: Mon, 30 Aug 2021 18:36:23 +0200 Subject: [PATCH] Make local publisher respect case expectations/configs. Signed-off-by: Eric Peterson --- .../src/stages/publish/local.test.ts | 35 +++++++++++++++++-- .../src/stages/publish/local.ts | 33 +++++++++++++---- 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/packages/techdocs-common/src/stages/publish/local.test.ts b/packages/techdocs-common/src/stages/publish/local.test.ts index 0ced296a88..9609e4f12d 100644 --- a/packages/techdocs-common/src/stages/publish/local.test.ts +++ b/packages/techdocs-common/src/stages/publish/local.test.ts @@ -25,10 +25,10 @@ import mockFs from 'mock-fs'; import * as os from 'os'; import { LocalPublish } from './local'; -const createMockEntity = (annotations = {}) => { +const createMockEntity = (annotations = {}, lowerCase = false) => { return { apiVersion: 'version', - kind: 'TestKind', + kind: lowerCase ? 'testkind' : 'TestKind', metadata: { name: 'test-component-name', annotations: { @@ -65,11 +65,42 @@ describe('local publisher', () => { const publisher = new LocalPublish(mockConfig, logger, testDiscovery); const mockEntity = createMockEntity(); + const lowerMockEntity = createMockEntity(undefined, true); await publisher.publish({ entity: mockEntity, directory: tmpDir }); expect(await publisher.hasDocsBeenGenerated(mockEntity)).toBe(true); + // Lower/upper should be treated the same. + expect(await publisher.hasDocsBeenGenerated(lowerMockEntity)).toBe(true); + + mockFs.restore(); + }); + + it('should respect legacy casing', async () => { + mockFs({ + [tmpDir]: { + 'index.html': '', + }, + }); + + const mockConfig = new ConfigReader({ + techdocs: { + legacyUseCaseSensitiveTripletPaths: true, + }, + }); + + const publisher = new LocalPublish(mockConfig, logger, testDiscovery); + const mockEntity = createMockEntity(); + const lowerMockEntity = createMockEntity(undefined, true); + + await publisher.publish({ entity: mockEntity, directory: tmpDir }); + + expect(await publisher.hasDocsBeenGenerated(mockEntity)).toBe(true); + + // Lower/upper should be treated differently. + expect(await publisher.hasDocsBeenGenerated(lowerMockEntity)).toBe(false); + mockFs.restore(); }); diff --git a/packages/techdocs-common/src/stages/publish/local.ts b/packages/techdocs-common/src/stages/publish/local.ts index 24af34932f..b59bae88bb 100644 --- a/packages/techdocs-common/src/stages/publish/local.ts +++ b/packages/techdocs-common/src/stages/publish/local.ts @@ -58,6 +58,8 @@ try { * called "static" at the root of techdocs-backend plugin. */ export class LocalPublish implements PublisherBase { + private legacyPathCasing: boolean; + // TODO: Use a static fromConfig method to create a LocalPublish instance, similar to aws/gcs publishers. // Move the logic of setting staticDocsDir based on config over to fromConfig, // and set the value as a class parameter. @@ -70,6 +72,10 @@ export class LocalPublish implements PublisherBase { this.config = config; this.logger = logger; this.discovery = discovery; + this.legacyPathCasing = + config.getOptionalBoolean( + 'techdocs.legacyUseCaseSensitiveTripletPaths', + ) || false; } async getReadiness(): Promise { @@ -81,8 +87,7 @@ export class LocalPublish implements PublisherBase { publish({ entity, directory }: PublishRequest): Promise { const entityNamespace = entity.metadata.namespace ?? 'default'; - const publishDir = path.join( - staticDocsDir, + const publishDir = this.staticEntityPathJoin( entityNamespace, entity.kind, entity.metadata.name, @@ -119,8 +124,7 @@ export class LocalPublish implements PublisherBase { async fetchTechDocsMetadata( entityName: EntityName, ): Promise { - const metadataPath = path.join( - staticDocsDir, + const metadataPath = this.staticEntityPathJoin( entityName.namespace, entityName.kind, entityName.name, @@ -153,8 +157,7 @@ export class LocalPublish implements PublisherBase { async hasDocsBeenGenerated(entity: Entity): Promise { const namespace = entity.metadata.namespace ?? 'default'; - const indexHtmlPath = path.join( - staticDocsDir, + const indexHtmlPath = this.staticEntityPathJoin( namespace, entity.kind, entity.metadata.name, @@ -210,4 +213,22 @@ export class LocalPublish implements PublisherBase { ), ); } + + /** + * Utility wrapper around path.join(), used to control legacy case logic. + */ + protected staticEntityPathJoin(...allParts: string[]): string { + if (this.legacyPathCasing) { + const [namespace, kind, name, ...parts] = allParts; + return path.join(staticDocsDir, namespace, kind, name, ...parts); + } + const [namespace, kind, name, ...parts] = allParts; + return path.join( + staticDocsDir, + namespace.toLowerCase(), + kind.toLowerCase(), + name.toLowerCase(), + ...parts, + ); + } }