@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { NotModifiedError } from '@backstage/backend-common';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { Entity, serializeEntityRef } from '@backstage/catalog-model';
|
||||
import {
|
||||
GeneratorBase,
|
||||
GeneratorBuilder,
|
||||
@@ -31,12 +31,6 @@ import path from 'path';
|
||||
import { Logger } from 'winston';
|
||||
import { BuildMetadataStorage } from '.';
|
||||
|
||||
const getEntityId = (entity: Entity) => {
|
||||
return `${entity.kind}:${entity.metadata.namespace ?? ''}:${
|
||||
entity.metadata.name
|
||||
}`;
|
||||
};
|
||||
|
||||
type DocsBuilderArguments = {
|
||||
preparers: PreparerBuilder;
|
||||
generators: GeneratorBuilder;
|
||||
@@ -78,9 +72,15 @@ export class DocsBuilder {
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare and cache check
|
||||
* Prepare (and cache check)
|
||||
*/
|
||||
|
||||
this.logger.info(
|
||||
`Step 1 of 3: Preparing docs for entity ${serializeEntityRef(
|
||||
this.entity,
|
||||
)}`,
|
||||
);
|
||||
|
||||
// Use the in-memory storage for setting and getting etag for this entity.
|
||||
const buildMetadataStorage = new BuildMetadataStorage(
|
||||
this.entity.metadata.uid,
|
||||
@@ -92,6 +92,7 @@ export class DocsBuilder {
|
||||
// make sure to limit checking for cache invalidation to once per minute or so.
|
||||
let preparedDir: string;
|
||||
let etag: string;
|
||||
|
||||
try {
|
||||
const preparerResponse = await this.preparer.prepare(this.entity, {
|
||||
etag: buildMetadataStorage.getEtag(),
|
||||
@@ -102,21 +103,32 @@ export class DocsBuilder {
|
||||
} catch (err) {
|
||||
if (err instanceof NotModifiedError) {
|
||||
// No need to prepare anymore since cache is valid.
|
||||
this.logger.debug(
|
||||
`Docs for ${serializeEntityRef(
|
||||
this.entity,
|
||||
)} are unmodified. Using cache, skipping generate and prepare`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
throw new Error(err.message);
|
||||
}
|
||||
|
||||
this.logger.info(
|
||||
`TechDocs prepare step completed for entity ${getEntityId(this.entity)}.`,
|
||||
`Prepare step completed for entity ${serializeEntityRef(
|
||||
this.entity,
|
||||
)}, stored at ${preparedDir}`,
|
||||
);
|
||||
this.logger.debug(`Prepared files temporarily stored at ${preparedDir}`);
|
||||
|
||||
/**
|
||||
* Generate
|
||||
*/
|
||||
|
||||
this.logger.info(`Running generator on entity ${getEntityId(this.entity)}`);
|
||||
this.logger.info(
|
||||
`Step 2 of 3: Generating docs for entity ${serializeEntityRef(
|
||||
this.entity,
|
||||
)}`,
|
||||
);
|
||||
|
||||
// Create a temporary directory to store the generated files in.
|
||||
const tmpdirPath = os.tmpdir();
|
||||
// Fixes a problem with macOS returning a path that is a symlink
|
||||
@@ -133,13 +145,12 @@ export class DocsBuilder {
|
||||
etag,
|
||||
});
|
||||
|
||||
this.logger.debug(`Generated files temporarily stored at ${outputDir}`);
|
||||
// Remove Prepared directory since it is no longer needed.
|
||||
// Caveat: Can not remove prepared directory in case of git preparer since the
|
||||
// local git repository is used to get etag on subsequent requests.
|
||||
if (this.preparer instanceof UrlPreparer) {
|
||||
this.logger.debug(
|
||||
`Removing prepared directory ${preparedDir} since the site has been generated.`,
|
||||
`Removing prepared directory ${preparedDir} since the site has been generated`,
|
||||
);
|
||||
try {
|
||||
// Not a blocker hence no need to await this.
|
||||
@@ -153,17 +164,23 @@ export class DocsBuilder {
|
||||
* Publish
|
||||
*/
|
||||
|
||||
this.logger.info(`Running publisher on entity ${getEntityId(this.entity)}`);
|
||||
this.logger.info(
|
||||
`Step 3 of 3: Publishing docs for entity ${serializeEntityRef(
|
||||
this.entity,
|
||||
)}`,
|
||||
);
|
||||
|
||||
await this.publisher.publish({
|
||||
entity: this.entity,
|
||||
directory: outputDir,
|
||||
});
|
||||
this.logger.debug(
|
||||
`Removing generated directory ${outputDir} since the site has been published`,
|
||||
);
|
||||
|
||||
try {
|
||||
// Not a blocker hence no need to await this.
|
||||
fs.remove(outputDir);
|
||||
this.logger.debug(
|
||||
`Removing generated directory ${outputDir} since the site has been published`,
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.debug(`Error removing generated directory ${error.message}`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user