fix: review findings

Signed-off-by: Heikki Hellgren <heikki.hellgren@op.fi>
This commit is contained in:
Heikki Hellgren
2024-04-15 08:12:46 +03:00
parent eabeac8f97
commit 5dd8177c79
24 changed files with 113 additions and 109 deletions
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-kubernetes-backend': patch
'@backstage/plugin-tech-insights-node': patch
---
**BREAKING** Winston logger has been replaced with `LoggerService`
-3
View File
@@ -22,10 +22,8 @@
'@backstage/plugin-azure-devops-backend': patch
'@backstage/plugin-azure-sites-backend': patch
'@backstage/plugin-search-backend-node': patch
'@backstage/plugin-kubernetes-backend': patch
'@backstage/plugin-lighthouse-backend': patch
'@backstage/plugin-permission-backend': patch
'@backstage/plugin-tech-insights-node': patch
'@backstage/plugin-sonarqube-backend': patch
'@backstage/backend-app-api': patch
'@backstage/plugin-airbrake-backend': patch
@@ -36,7 +34,6 @@
'@backstage/plugin-catalog-backend': patch
'@backstage/plugin-explore-backend': patch
'@backstage/plugin-jenkins-backend': patch
'@backstage/plugin-scaffolder-node': patch
'@backstage/backend-tasks': patch
'@backstage/plugin-badges-backend': patch
'@backstage/plugin-bazaar-backend': patch
+9 -8
View File
@@ -8,7 +8,7 @@
import { BackstageCredentials } from '@backstage/backend-plugin-api';
import { JsonObject } from '@backstage/types';
import { JsonValue } from '@backstage/types';
import { LoggerService } from '@backstage/backend-plugin-api';
import { Logger } from 'winston';
import { Observable } from '@backstage/types';
import { Schema } from 'jsonschema';
import { ScmIntegrationRegistry } from '@backstage/integration';
@@ -26,7 +26,8 @@ export type ActionContext<
TActionInput extends JsonObject,
TActionOutput extends JsonObject = JsonObject,
> = {
logger: LoggerService;
logger: Logger;
logStream: Writable;
secrets?: TaskSecrets;
workspacePath: string;
input: TActionInput;
@@ -62,7 +63,7 @@ export function addFiles(options: {
| {
token: string;
};
logger?: LoggerService | undefined;
logger?: Logger | undefined;
}): Promise<void>;
// @public (undocumented)
@@ -77,7 +78,7 @@ export function cloneRepo(options: {
| {
token: string;
};
logger?: LoggerService;
logger?: Logger | undefined;
ref?: string | undefined;
depth?: number | undefined;
noCheckout?: boolean | undefined;
@@ -94,7 +95,7 @@ export function commitAndPushBranch(options: {
| {
token: string;
};
logger?: LoggerService | undefined;
logger?: Logger | undefined;
commitMessage: string;
gitAuthorInfo?: {
name?: string;
@@ -118,7 +119,7 @@ export function commitAndPushRepo(input: {
| {
token: string;
};
logger: LoggerService;
logger: Logger;
commitMessage: string;
gitAuthorInfo?: {
name?: string;
@@ -142,7 +143,7 @@ export function createBranch(options: {
| {
token: string;
};
logger?: LoggerService;
logger?: Logger | undefined;
}): Promise<void>;
// @public
@@ -231,7 +232,7 @@ export function initRepoAndPush(input: {
| {
token: string;
};
logger: LoggerService;
logger: Logger;
defaultBranch?: string;
commitMessage?: string;
gitAuthorInfo?: {
+1
View File
@@ -57,6 +57,7 @@
"globby": "^11.0.0",
"jsonschema": "^1.2.6",
"p-limit": "^3.1.0",
"winston": "^3.2.1",
"zod": "^3.22.4",
"zod-to-json-schema": "^3.20.4"
},
@@ -15,7 +15,7 @@
*/
import { Git } from '@backstage/backend-common';
import { LoggerService } from '@backstage/backend-plugin-api';
import { Logger } from 'winston';
/**
* @public
@@ -27,7 +27,7 @@ export async function initRepoAndPush(input: {
// it has to be provided as password together with a username
// which may be a fixed value defined by the provider.
auth: { username: string; password: string } | { token: string };
logger: LoggerService;
logger: Logger;
defaultBranch?: string;
commitMessage?: string;
gitAuthorInfo?: { name?: string; email?: string };
@@ -88,7 +88,7 @@ export async function commitAndPushRepo(input: {
// it has to be provided as password together with a username
// which may be a fixed value defined by the provider.
auth: { username: string; password: string } | { token: string };
logger: LoggerService;
logger: Logger;
commitMessage: string;
gitAuthorInfo?: { name?: string; email?: string };
branch?: string;
@@ -145,7 +145,7 @@ export async function cloneRepo(options: {
// it has to be provided as password together with a username
// which may be a fixed value defined by the provider.
auth: { username: string; password: string } | { token: string };
logger?: LoggerService;
logger?: Logger | undefined;
ref?: string | undefined;
depth?: number | undefined;
noCheckout?: boolean | undefined;
@@ -170,7 +170,7 @@ export async function createBranch(options: {
// it has to be provided as password together with a username
// which may be a fixed value defined by the provider.
auth: { username: string; password: string } | { token: string };
logger?: LoggerService;
logger?: Logger | undefined;
}): Promise<void> {
const { dir, ref, auth, logger } = options;
const git = Git.fromAuth({
@@ -191,7 +191,7 @@ export async function addFiles(options: {
// it has to be provided as password together with a username
// which may be a fixed value defined by the provider.
auth: { username: string; password: string } | { token: string };
logger?: LoggerService | undefined;
logger?: Logger | undefined;
}): Promise<void> {
const { dir, filepath, auth, logger } = options;
const git = Git.fromAuth({
@@ -211,7 +211,7 @@ export async function commitAndPushBranch(options: {
// it has to be provided as password together with a username
// which may be a fixed value defined by the provider.
auth: { username: string; password: string } | { token: string };
logger?: LoggerService | undefined;
logger?: Logger | undefined;
commitMessage: string;
gitAuthorInfo?: { name?: string; email?: string };
branch?: string;
+7 -5
View File
@@ -14,15 +14,14 @@
* limitations under the License.
*/
import { Logger } from 'winston';
import { Writable } from 'stream';
import { JsonObject, JsonValue } from '@backstage/types';
import { TaskSecrets } from '../tasks';
import { TemplateInfo } from '@backstage/plugin-scaffolder-common';
import { UserEntity } from '@backstage/catalog-model';
import { Schema } from 'jsonschema';
import {
BackstageCredentials,
LoggerService,
} from '@backstage/backend-plugin-api';
import { BackstageCredentials } from '@backstage/backend-plugin-api';
/**
* ActionContext is passed into scaffolder actions.
@@ -32,7 +31,10 @@ export type ActionContext<
TActionInput extends JsonObject,
TActionOutput extends JsonObject = JsonObject,
> = {
logger: LoggerService;
// TODO(blam): move this to LoggerService
logger: Logger;
/** @deprecated - use `ctx.logger` instead */
logStream: Writable;
secrets?: TaskSecrets;
workspacePath: string;
input: TActionInput;
+9 -9
View File
@@ -12,7 +12,7 @@ import { Entity } from '@backstage/catalog-model';
import express from 'express';
import { ExtensionPoint } from '@backstage/backend-plugin-api';
import { IndexableDocument } from '@backstage/plugin-search-common';
import { LoggerService } from '@backstage/backend-plugin-api';
import { Logger } from 'winston';
import { PluginEndpointDiscovery } from '@backstage/backend-common';
import { ScmIntegrationRegistry } from '@backstage/integration';
import { UrlReader } from '@backstage/backend-common';
@@ -48,7 +48,7 @@ export type GeneratorBuilder = {
// @public
export type GeneratorOptions = {
containerRunner?: ContainerRunner;
logger: LoggerService;
logger: Logger;
};
// @public
@@ -57,7 +57,7 @@ export type GeneratorRunOptions = {
outputDir: string;
parsedLocationAnnotation?: ParsedLocationAnnotation;
etag?: string;
logger: LoggerService;
logger: Logger;
logStream?: Writable;
siteOptions?: {
name?: string;
@@ -70,7 +70,7 @@ export class Generators implements GeneratorBuilder {
static fromConfig(
config: Config,
options: {
logger: LoggerService;
logger: Logger;
containerRunner: ContainerRunner;
customGenerator?: TechdocsGenerator;
},
@@ -85,7 +85,7 @@ export const getDocFilesFromRepository: (
entity: Entity,
opts?: {
etag?: string;
logger?: LoggerService;
logger?: Logger;
},
) => Promise<PreparerResponse>;
@@ -155,13 +155,13 @@ export type PreparerBuilder = {
// @public
export type PreparerConfig = {
logger: LoggerService;
logger: Logger;
reader: UrlReader;
};
// @public
export type PreparerOptions = {
logger?: LoggerService;
logger?: Logger;
etag?: ETag;
};
@@ -203,7 +203,7 @@ export interface PublisherBase {
// @public
export type PublisherFactory = {
logger: LoggerService;
logger: Logger;
discovery: PluginEndpointDiscovery;
};
@@ -260,7 +260,7 @@ export interface TechDocsDocument extends IndexableDocument {
// @public
export class TechdocsGenerator implements GeneratorBase {
constructor(options: {
logger: LoggerService;
logger: Logger;
containerRunner?: ContainerRunner;
config: Config;
scmIntegrations: ScmIntegrationRegistry;
+2 -1
View File
@@ -65,7 +65,8 @@
"json5": "^2.1.3",
"mime-types": "^2.1.27",
"p-limit": "^3.1.0",
"recursive-readdir": "^2.2.2"
"recursive-readdir": "^2.2.2",
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/backend-test-utils": "workspace:^",
+2 -2
View File
@@ -23,8 +23,8 @@ import {
import { InputError } from '@backstage/errors';
import { ScmIntegrationRegistry } from '@backstage/integration';
import path from 'path';
import { Logger } from 'winston';
import { PreparerResponse, RemoteProtocol } from './stages/prepare/types';
import { LoggerService } from '@backstage/backend-plugin-api';
/**
* Parsed location annotation
@@ -146,7 +146,7 @@ export const getLocationForEntity = (
export const getDocFilesFromRepository = async (
reader: UrlReader,
entity: Entity,
opts?: { etag?: string; logger?: LoggerService },
opts?: { etag?: string; logger?: Logger },
): Promise<PreparerResponse> => {
const { target } = parseReferenceAnnotation(
'backstage.io/techdocs-ref',
@@ -17,6 +17,7 @@
import { ContainerRunner } from '@backstage/backend-common';
import { Entity } from '@backstage/catalog-model';
import { Config } from '@backstage/config';
import { Logger } from 'winston';
import { getGeneratorKey } from './helpers';
import { TechdocsGenerator } from './techdocs';
import {
@@ -24,7 +25,6 @@ import {
GeneratorBuilder,
SupportedGeneratorKey,
} from './types';
import { LoggerService } from '@backstage/backend-plugin-api';
/**
* Collection of docs generators
@@ -41,7 +41,7 @@ export class Generators implements GeneratorBuilder {
static async fromConfig(
config: Config,
options: {
logger: LoggerService;
logger: Logger;
containerRunner: ContainerRunner;
customGenerator?: TechdocsGenerator;
},
@@ -18,16 +18,16 @@ import { isChildPath } from '@backstage/backend-common';
import { Entity } from '@backstage/catalog-model';
import { assertError, ForwardedError } from '@backstage/errors';
import { ScmIntegrationRegistry } from '@backstage/integration';
import { spawn, SpawnOptionsWithoutStdio } from 'child_process';
import { SpawnOptionsWithoutStdio, spawn } from 'child_process';
import fs from 'fs-extra';
import gitUrlParse from 'git-url-parse';
import yaml, { DEFAULT_SCHEMA, Type } from 'js-yaml';
import path, { resolve as resolvePath } from 'path';
import { PassThrough, Writable } from 'stream';
import { Logger } from 'winston';
import { ParsedLocationAnnotation } from '../../helpers';
import { DefaultMkdocsContent, SupportedGeneratorKey } from './types';
import { getFileTreeRecursively } from '../publish/helpers';
import { LoggerService } from '@backstage/backend-plugin-api';
// TODO: Implement proper support for more generators.
export function getGeneratorKey(entity: Entity): SupportedGeneratorKey {
@@ -296,7 +296,7 @@ export const patchIndexPreBuild = async ({
docsDir = 'docs',
}: {
inputDir: string;
logger: LoggerService;
logger: Logger;
docsDir?: string;
}) => {
const docsPath = path.join(inputDir, docsDir);
@@ -340,7 +340,7 @@ export const patchIndexPreBuild = async ({
*/
export const createOrUpdateMetadata = async (
techdocsMetadataPath: string,
logger: LoggerService,
logger: Logger,
): Promise<void> => {
const techdocsMetadataDir = techdocsMetadataPath
.split(path.sep)
@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Logger } from 'winston';
import fs from 'fs-extra';
import yaml from 'js-yaml';
import { ParsedLocationAnnotation } from '../../helpers';
import { getRepoUrlFromLocationAnnotation, MKDOCS_SCHEMA } from './helpers';
import { assertError } from '@backstage/errors';
import { ScmIntegrationRegistry } from '@backstage/integration';
import { LoggerService } from '@backstage/backend-plugin-api';
type MkDocsObject = {
plugins?: string[];
@@ -30,7 +30,7 @@ type MkDocsObject = {
const patchMkdocsFile = async (
mkdocsYmlPath: string,
logger: LoggerService,
logger: Logger,
updateAction: (mkdocsYml: MkDocsObject) => boolean,
) => {
// We only want to override the mkdocs.yml if it has actually changed. This is relevant if
@@ -103,7 +103,7 @@ const patchMkdocsFile = async (
*/
export const patchMkdocsYmlPreBuild = async (
mkdocsYmlPath: string,
logger: LoggerService,
logger: Logger,
parsedLocationAnnotation: ParsedLocationAnnotation,
scmIntegrations: ScmIntegrationRegistry,
) => {
@@ -149,7 +149,7 @@ export const patchMkdocsYmlPreBuild = async (
*/
export const patchMkdocsYmlWithPlugins = async (
mkdocsYmlPath: string,
logger: LoggerService,
logger: Logger,
defaultPlugins: string[] = ['techdocs-core'],
) => {
await patchMkdocsFile(mkdocsYmlPath, logger, mkdocsYml => {
@@ -17,6 +17,7 @@
import { ContainerRunner } from '@backstage/backend-common';
import { Config } from '@backstage/config';
import path from 'path';
import { Logger } from 'winston';
import {
ScmIntegrationRegistry,
ScmIntegrations,
@@ -42,7 +43,6 @@ import {
GeneratorRunOptions,
} from './types';
import { ForwardedError } from '@backstage/errors';
import { LoggerService } from '@backstage/backend-plugin-api';
/**
* Generates documentation files
@@ -54,7 +54,7 @@ export class TechdocsGenerator implements GeneratorBase {
* and static so that techdocs-node consumers can use the same version.
*/
public static readonly defaultDockerImage = 'spotify/techdocs:v1.2.3';
private readonly logger: LoggerService;
private readonly logger: Logger;
private readonly containerRunner?: ContainerRunner;
private readonly options: GeneratorConfig;
private readonly scmIntegrations: ScmIntegrationRegistry;
@@ -76,7 +76,7 @@ export class TechdocsGenerator implements GeneratorBase {
}
constructor(options: {
logger: LoggerService;
logger: Logger;
containerRunner?: ContainerRunner;
config: Config;
scmIntegrations: ScmIntegrationRegistry;
@@ -217,7 +217,7 @@ export class TechdocsGenerator implements GeneratorBase {
export function readGeneratorConfig(
config: Config,
logger: LoggerService,
logger: Logger,
): GeneratorConfig {
const legacyGeneratorType = config.getOptionalString(
'techdocs.generators.techdocs',
@@ -17,8 +17,8 @@
import { ContainerRunner } from '@backstage/backend-common';
import { Entity } from '@backstage/catalog-model';
import { Writable } from 'stream';
import { Logger } from 'winston';
import { ParsedLocationAnnotation } from '../../helpers';
import { LoggerService } from '@backstage/backend-plugin-api';
// Determines where the generator will be run
export type GeneratorRunInType = 'docker' | 'local';
@@ -29,7 +29,7 @@ export type GeneratorRunInType = 'docker' | 'local';
*/
export type GeneratorOptions = {
containerRunner?: ContainerRunner;
logger: LoggerService;
logger: Logger;
};
/**
@@ -61,7 +61,7 @@ export type GeneratorRunOptions = {
outputDir: string;
parsedLocationAnnotation?: ParsedLocationAnnotation;
etag?: string;
logger: LoggerService;
logger: Logger;
logStream?: Writable;
siteOptions?: { name?: string };
runAsDefaultUser?: boolean;
@@ -22,6 +22,7 @@ import {
ScmIntegrationRegistry,
ScmIntegrations,
} from '@backstage/integration';
import { Logger } from 'winston';
import { parseReferenceAnnotation, transformDirLocation } from '../../helpers';
import {
PreparerBase,
@@ -29,7 +30,6 @@ import {
PreparerOptions,
PreparerResponse,
} from './types';
import { LoggerService } from '@backstage/backend-plugin-api';
/**
* Preparer used to retrieve documentation files from a local directory
@@ -53,7 +53,7 @@ export class DirectoryPreparer implements PreparerBase {
private constructor(
config: Config,
_logger: LoggerService | null,
_logger: Logger | null,
reader: UrlReader,
) {
this.reader = reader;
@@ -16,7 +16,7 @@
import type { Entity } from '@backstage/catalog-model';
import { UrlReader } from '@backstage/backend-common';
import { LoggerService } from '@backstage/backend-plugin-api';
import { Logger } from 'winston';
/**
* A unique identifier of the tree blob, usually the commit SHA or etag from the target.
@@ -29,7 +29,7 @@ export type ETag = string;
* @public
*/
export type PreparerConfig = {
logger: LoggerService;
logger: Logger;
reader: UrlReader;
};
@@ -41,7 +41,7 @@ export type PreparerOptions = {
/**
* An instance of the logger
*/
logger?: LoggerService;
logger?: Logger;
/**
* see {@link ETag}
*/
@@ -17,6 +17,7 @@
import { assertError } from '@backstage/errors';
import { UrlReader } from '@backstage/backend-common';
import { Entity } from '@backstage/catalog-model';
import { Logger } from 'winston';
import { getDocFilesFromRepository } from '../../helpers';
import {
PreparerBase,
@@ -24,14 +25,13 @@ import {
PreparerOptions,
PreparerResponse,
} from './types';
import { LoggerService } from '@backstage/backend-plugin-api';
/**
* Preparer used to retrieve documentation files from a remote repository
* @public
*/
export class UrlPreparer implements PreparerBase {
private readonly logger: LoggerService;
private readonly logger: Logger;
private readonly reader: UrlReader;
/**
@@ -42,7 +42,7 @@ export class UrlPreparer implements PreparerBase {
return new UrlPreparer(options.reader, options.logger);
}
private constructor(reader: UrlReader, logger: LoggerService) {
private constructor(reader: UrlReader, logger: Logger) {
this.logger = logger;
this.reader = reader;
}
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CompoundEntityRef, Entity } from '@backstage/catalog-model';
import { Entity, CompoundEntityRef } from '@backstage/catalog-model';
import { Config } from '@backstage/config';
import { assertError, ForwardedError } from '@backstage/errors';
import {
@@ -21,14 +21,14 @@ import {
DefaultAwsCredentialsManager,
} from '@backstage/integration-aws-node';
import {
GetObjectCommand,
CopyObjectCommand,
DeleteObjectCommand,
GetObjectCommand,
HeadBucketCommand,
HeadObjectCommand,
ListObjectsV2Command,
ListObjectsV2CommandOutput,
PutObjectCommandInput,
ListObjectsV2CommandOutput,
ListObjectsV2Command,
S3Client,
} from '@aws-sdk/client-s3';
import { fromTemporaryCredentials } from '@aws-sdk/credential-providers';
@@ -42,6 +42,7 @@ import JSON5 from 'json5';
import createLimiter from 'p-limit';
import path from 'path';
import { Readable } from 'stream';
import { Logger } from 'winston';
import {
bulkStorageOperation,
getCloudPathForLocalPath,
@@ -59,7 +60,6 @@ import {
ReadinessResponse,
TechDocsMetadata,
} from './types';
import { LoggerService } from '@backstage/backend-plugin-api';
const streamToBuffer = (stream: Readable): Promise<Buffer> => {
return new Promise((resolve, reject) => {
@@ -80,7 +80,7 @@ export class AwsS3Publish implements PublisherBase {
private readonly storageClient: S3Client;
private readonly bucketName: string;
private readonly legacyPathCasing: boolean;
private readonly logger: LoggerService;
private readonly logger: Logger;
private readonly bucketRootPath: string;
private readonly sse?: 'aws:kms' | 'AES256';
@@ -88,7 +88,7 @@ export class AwsS3Publish implements PublisherBase {
storageClient: S3Client;
bucketName: string;
legacyPathCasing: boolean;
logger: LoggerService;
logger: Logger;
bucketRootPath: string;
sse?: 'aws:kms' | 'AES256';
}) {
@@ -102,7 +102,7 @@ export class AwsS3Publish implements PublisherBase {
static async fromConfig(
config: Config,
logger: LoggerService,
logger: Logger,
): Promise<PublisherBase> {
let bucketName = '';
try {
@@ -524,7 +524,7 @@ export class AwsS3Publish implements PublisherBase {
}
try {
this.logger.debug(`Migrating ${file}`);
this.logger.verbose(`Migrating ${file}`);
await this.storageClient.send(
new CopyObjectCommand({
Bucket: this.bucketName,
@@ -19,20 +19,21 @@ import {
ContainerClient,
StorageSharedKeyCredential,
} from '@azure/storage-blob';
import { CompoundEntityRef, Entity } from '@backstage/catalog-model';
import { Entity, CompoundEntityRef } from '@backstage/catalog-model';
import { Config } from '@backstage/config';
import { assertError, ForwardedError } from '@backstage/errors';
import express from 'express';
import JSON5 from 'json5';
import limiterFactory from 'p-limit';
import { default as path, default as platformPath } from 'path';
import { Logger } from 'winston';
import {
bulkStorageOperation,
getCloudPathForLocalPath,
getFileTreeRecursively,
getHeadersForFileExtension,
getStaleFiles,
lowerCaseEntityTriplet,
getStaleFiles,
lowerCaseEntityTripletInStoragePath,
} from './helpers';
import {
@@ -42,7 +43,6 @@ import {
ReadinessResponse,
TechDocsMetadata,
} from './types';
import { LoggerService } from '@backstage/backend-plugin-api';
// The number of batches that may be ongoing at the same time.
const BATCH_CONCURRENCY = 3;
@@ -51,13 +51,13 @@ export class AzureBlobStoragePublish implements PublisherBase {
private readonly storageClient: BlobServiceClient;
private readonly containerName: string;
private readonly legacyPathCasing: boolean;
private readonly logger: LoggerService;
private readonly logger: Logger;
constructor(options: {
storageClient: BlobServiceClient;
containerName: string;
legacyPathCasing: boolean;
logger: LoggerService;
logger: Logger;
}) {
this.storageClient = options.storageClient;
this.containerName = options.containerName;
@@ -65,7 +65,7 @@ export class AzureBlobStoragePublish implements PublisherBase {
this.logger = options.logger;
}
static fromConfig(config: Config, logger: LoggerService): PublisherBase {
static fromConfig(config: Config, logger: Logger): PublisherBase {
let storageClient: BlobServiceClient;
let containerName = '';
try {
@@ -130,7 +130,7 @@ export class AzureBlobStoragePublish implements PublisherBase {
storageClient: storageClient,
containerName: containerName,
legacyPathCasing: legacyPathCasing,
logger,
logger: logger,
});
}
@@ -421,7 +421,7 @@ export class AzureBlobStoragePublish implements PublisherBase {
if (originalPath === newPath) return;
try {
this.logger.debug(`Migrating ${originalPath}`);
this.logger.verbose(`Migrating ${originalPath}`);
await this.renameBlob(originalPath, newPath, removeOriginal);
} catch (e) {
assertError(e);
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CompoundEntityRef, Entity } from '@backstage/catalog-model';
import { Entity, CompoundEntityRef } from '@backstage/catalog-model';
import { Config } from '@backstage/config';
import { assertError } from '@backstage/errors';
import {
@@ -26,14 +26,15 @@ import express from 'express';
import JSON5 from 'json5';
import path from 'path';
import { Readable } from 'stream';
import { Logger } from 'winston';
import {
bulkStorageOperation,
getCloudPathForLocalPath,
getFileTreeRecursively,
getHeadersForFileExtension,
getStaleFiles,
lowerCaseEntityTriplet,
lowerCaseEntityTripletInStoragePath,
bulkStorageOperation,
getCloudPathForLocalPath,
getStaleFiles,
normalizeExternalStorageRootPath,
} from './helpers';
import { MigrateWriteStream } from './migrations';
@@ -44,20 +45,19 @@ import {
ReadinessResponse,
TechDocsMetadata,
} from './types';
import { LoggerService } from '@backstage/backend-plugin-api';
export class GoogleGCSPublish implements PublisherBase {
private readonly storageClient: Storage;
private readonly bucketName: string;
private readonly legacyPathCasing: boolean;
private readonly logger: LoggerService;
private readonly logger: Logger;
private readonly bucketRootPath: string;
constructor(options: {
storageClient: Storage;
bucketName: string;
legacyPathCasing: boolean;
logger: LoggerService;
logger: Logger;
bucketRootPath: string;
}) {
this.storageClient = options.storageClient;
@@ -67,7 +67,7 @@ export class GoogleGCSPublish implements PublisherBase {
this.bucketRootPath = options.bucketRootPath;
}
static fromConfig(config: Config, logger: LoggerService): PublisherBase {
static fromConfig(config: Config, logger: Logger): PublisherBase {
let bucketName = '';
try {
bucketName = config.getString('techdocs.publisher.googleGcs.bucketName');
@@ -19,8 +19,8 @@ import {
resolveSafeChildPath,
} from '@backstage/backend-common';
import {
CompoundEntityRef,
Entity,
CompoundEntityRef,
stringifyEntityRef,
} from '@backstage/catalog-model';
import { Config } from '@backstage/config';
@@ -29,6 +29,7 @@ import fs from 'fs-extra';
import os from 'os';
import createLimiter from 'p-limit';
import path from 'path';
import { Logger } from 'winston';
import {
PublisherBase,
PublishRequest,
@@ -42,7 +43,6 @@ import {
lowerCaseEntityTripletInStoragePath,
} from './helpers';
import { ForwardedError } from '@backstage/errors';
import { LoggerService } from '@backstage/backend-plugin-api';
/**
* Local publisher which uses the local filesystem to store the generated static files. It uses by default a
@@ -51,12 +51,12 @@ import { LoggerService } from '@backstage/backend-plugin-api';
*/
export class LocalPublish implements PublisherBase {
private readonly legacyPathCasing: boolean;
private readonly logger: LoggerService;
private readonly logger: Logger;
private readonly discovery: PluginEndpointDiscovery;
private readonly staticDocsDir: string;
constructor(options: {
logger: LoggerService;
logger: Logger;
discovery: PluginEndpointDiscovery;
legacyPathCasing: boolean;
staticDocsDir: string;
@@ -69,7 +69,7 @@ export class LocalPublish implements PublisherBase {
static fromConfig(
config: Config,
logger: LoggerService,
logger: Logger,
discovery: PluginEndpointDiscovery,
): PublisherBase {
const legacyPathCasing =
@@ -299,7 +299,7 @@ export class LocalPublish implements PublisherBase {
// Otherwise, copy or move the file.
await new Promise<void>(resolve => {
const migrate = removeOriginal ? fs.move : fs.copyFile;
this.logger.debug(`Migrating ${relativeFile}`);
this.logger.verbose(`Migrating ${relativeFile}`);
migrate(file, newFile, err => {
if (err) {
this.logger.warn(
@@ -17,24 +17,20 @@
import { assertError } from '@backstage/errors';
import { File } from '@google-cloud/storage';
import { Writable } from 'stream';
import { Logger } from 'winston';
import { lowerCaseEntityTripletInStoragePath } from '../helpers';
import { LoggerService } from '@backstage/backend-plugin-api';
/**
* Writable stream to handle object copy/move operations. This implementation
* ensures we don't read in files from GCS faster than GCS can copy/move them.
*/
export class MigrateWriteStream extends Writable {
protected logger: LoggerService;
protected logger: Logger;
protected removeOriginal: boolean;
protected maxConcurrency: number;
protected inFlight = 0;
constructor(
logger: LoggerService,
removeOriginal: boolean,
concurrency: number,
) {
constructor(logger: Logger, removeOriginal: boolean, concurrency: number) {
super({ objectMode: true });
this.logger = logger;
this.removeOriginal = removeOriginal;
@@ -70,7 +66,7 @@ export class MigrateWriteStream extends Writable {
const migrate = this.removeOriginal
? file.move.bind(file)
: file.copy.bind(file);
this.logger.debug(`Migrating ${file.name}`);
this.logger.verbose(`Migrating ${file.name}`);
migrate(newFile)
.catch(e =>
this.logger.warn(`Unable to migrate ${file.name}: ${e.message}`),
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CompoundEntityRef, Entity } from '@backstage/catalog-model';
import { Entity, CompoundEntityRef } from '@backstage/catalog-model';
import { Config } from '@backstage/config';
import express from 'express';
import fs from 'fs-extra';
@@ -22,7 +22,8 @@ import createLimiter from 'p-limit';
import path from 'path';
import { SwiftClient } from '@trendyol-js/openstack-swift-sdk';
import { NotFound } from '@trendyol-js/openstack-swift-sdk/lib/types';
import { Readable, Stream } from 'stream';
import { Stream, Readable } from 'stream';
import { Logger } from 'winston';
import {
getFileTreeRecursively,
getHeadersForFileExtension,
@@ -36,7 +37,6 @@ import {
TechDocsMetadata,
} from './types';
import { assertError, ForwardedError } from '@backstage/errors';
import { LoggerService } from '@backstage/backend-plugin-api';
const streamToBuffer = (stream: Stream | Readable): Promise<Buffer> => {
return new Promise((resolve, reject) => {
@@ -61,19 +61,19 @@ const bufferToStream = (buffer: Buffer): Readable => {
export class OpenStackSwiftPublish implements PublisherBase {
private readonly storageClient: SwiftClient;
private readonly containerName: string;
private readonly logger: LoggerService;
private readonly logger: Logger;
constructor(options: {
storageClient: SwiftClient;
containerName: string;
logger: LoggerService;
logger: Logger;
}) {
this.storageClient = options.storageClient;
this.containerName = options.containerName;
this.logger = options.logger;
}
static fromConfig(config: Config, logger: LoggerService): PublisherBase {
static fromConfig(config: Config, logger: Logger): PublisherBase {
let containerName = '';
try {
containerName = config.getString(
@@ -326,7 +326,7 @@ export class OpenStackSwiftPublish implements PublisherBase {
}
try {
this.logger.debug(`Migrating ${file} to ${newPath}`);
this.logger.verbose(`Migrating ${file} to ${newPath}`);
await this.storageClient.copy(
this.containerName,
file,
@@ -13,17 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CompoundEntityRef, Entity } from '@backstage/catalog-model';
import { Entity, CompoundEntityRef } from '@backstage/catalog-model';
import { PluginEndpointDiscovery } from '@backstage/backend-common';
import { Logger } from 'winston';
import express from 'express';
import { LoggerService } from '@backstage/backend-plugin-api';
/**
* Options for building publishers
* @public
*/
export type PublisherFactory = {
logger: LoggerService;
logger: Logger;
discovery: PluginEndpointDiscovery;
};