refactor(techdocs-node): remove dependency on backend-common
Signed-off-by: Camila Belo <camilaibs@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-node': patch
|
||||
---
|
||||
|
||||
As the `@backstage/backend-common` package is deprecated, we have updated the `techdocs-node` package to stop depending on it.
|
||||
@@ -7,13 +7,12 @@
|
||||
|
||||
import { CompoundEntityRef } from '@backstage/catalog-model';
|
||||
import { Config } from '@backstage/config';
|
||||
import { ContainerRunner } from '@backstage/backend-common';
|
||||
import { DiscoveryService } from '@backstage/backend-plugin-api';
|
||||
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 { Logger } from 'winston';
|
||||
import { PluginEndpointDiscovery } from '@backstage/backend-common';
|
||||
import { LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { ScmIntegrationRegistry } from '@backstage/integration';
|
||||
import { UrlReaderService } from '@backstage/backend-plugin-api';
|
||||
import * as winston from 'winston';
|
||||
@@ -48,8 +47,8 @@ export type GeneratorBuilder = {
|
||||
|
||||
// @public
|
||||
export type GeneratorOptions = {
|
||||
logger: Logger;
|
||||
containerRunner?: ContainerRunner;
|
||||
logger: LoggerService;
|
||||
containerRunner?: TechDocsContainerRunner;
|
||||
};
|
||||
|
||||
// @public
|
||||
@@ -58,7 +57,7 @@ export type GeneratorRunOptions = {
|
||||
outputDir: string;
|
||||
parsedLocationAnnotation?: ParsedLocationAnnotation;
|
||||
etag?: string;
|
||||
logger: Logger;
|
||||
logger: LoggerService;
|
||||
logStream?: Writable;
|
||||
siteOptions?: {
|
||||
name?: string;
|
||||
@@ -71,8 +70,8 @@ export class Generators implements GeneratorBuilder {
|
||||
static fromConfig(
|
||||
config: Config,
|
||||
options: {
|
||||
logger: Logger;
|
||||
containerRunner?: ContainerRunner;
|
||||
logger: LoggerService;
|
||||
containerRunner?: TechDocsContainerRunner;
|
||||
customGenerator?: TechdocsGenerator;
|
||||
},
|
||||
): Promise<GeneratorBuilder>;
|
||||
@@ -86,7 +85,7 @@ export const getDocFilesFromRepository: (
|
||||
entity: Entity,
|
||||
opts?: {
|
||||
etag?: string;
|
||||
logger?: Logger;
|
||||
logger?: LoggerService;
|
||||
},
|
||||
) => Promise<PreparerResponse>;
|
||||
|
||||
@@ -156,13 +155,13 @@ export type PreparerBuilder = {
|
||||
|
||||
// @public
|
||||
export type PreparerConfig = {
|
||||
logger: Logger;
|
||||
logger: LoggerService;
|
||||
reader: UrlReaderService;
|
||||
};
|
||||
|
||||
// @public
|
||||
export type PreparerOptions = {
|
||||
logger?: Logger;
|
||||
logger?: LoggerService;
|
||||
etag?: ETag;
|
||||
};
|
||||
|
||||
@@ -214,8 +213,8 @@ export type PublisherBuilder = {
|
||||
|
||||
// @public
|
||||
export type PublisherFactory = {
|
||||
logger: Logger;
|
||||
discovery: PluginEndpointDiscovery;
|
||||
logger: LoggerService;
|
||||
discovery: DiscoveryService;
|
||||
customPublisher?: PublisherBase | undefined;
|
||||
};
|
||||
|
||||
@@ -261,6 +260,32 @@ export interface TechdocsBuildsExtensionPoint {
|
||||
// @public
|
||||
export const techdocsBuildsExtensionPoint: ExtensionPoint<TechdocsBuildsExtensionPoint>;
|
||||
|
||||
// @public
|
||||
export interface TechDocsContainerRunner {
|
||||
runContainer(opts: {
|
||||
imageName: string;
|
||||
command?: string | string[];
|
||||
args: string[];
|
||||
logStream?: Writable;
|
||||
mountDirs?: Record<string, string>;
|
||||
workingDir?: string;
|
||||
envVars?: Record<string, string>;
|
||||
pullImage?: boolean;
|
||||
defaultUser?: boolean;
|
||||
pullOptions?: {
|
||||
authconfig?: {
|
||||
username?: string;
|
||||
password?: string;
|
||||
auth?: string;
|
||||
email?: string;
|
||||
serveraddress?: string;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
[key: string]: unknown;
|
||||
};
|
||||
}): Promise<void>;
|
||||
}
|
||||
|
||||
// @public
|
||||
export interface TechDocsDocument extends IndexableDocument {
|
||||
kind: string;
|
||||
@@ -274,8 +299,8 @@ export interface TechDocsDocument extends IndexableDocument {
|
||||
// @public
|
||||
export class TechdocsGenerator implements GeneratorBase {
|
||||
constructor(options: {
|
||||
logger: Logger;
|
||||
containerRunner?: ContainerRunner;
|
||||
logger: LoggerService;
|
||||
containerRunner?: TechDocsContainerRunner;
|
||||
config: Config;
|
||||
scmIntegrations: ScmIntegrationRegistry;
|
||||
});
|
||||
|
||||
@@ -14,8 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { UrlReaderService } from '@backstage/backend-plugin-api';
|
||||
import { resolveSafeChildPath } from '@backstage/backend-plugin-api';
|
||||
import {
|
||||
LoggerService,
|
||||
UrlReaderService,
|
||||
resolveSafeChildPath,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import {
|
||||
Entity,
|
||||
getEntitySourceLocation,
|
||||
@@ -25,7 +28,6 @@ import { InputError } from '@backstage/errors';
|
||||
import { ScmIntegrationRegistry } from '@backstage/integration';
|
||||
import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common';
|
||||
import path from 'path';
|
||||
import { Logger } from 'winston';
|
||||
import { PreparerResponse, RemoteProtocol } from './stages/prepare/types';
|
||||
|
||||
/**
|
||||
@@ -145,7 +147,7 @@ export const getLocationForEntity = (
|
||||
export const getDocFilesFromRepository = async (
|
||||
reader: UrlReaderService,
|
||||
entity: Entity,
|
||||
opts?: { etag?: string; logger?: Logger },
|
||||
opts?: { etag?: string; logger?: LoggerService },
|
||||
): Promise<PreparerResponse> => {
|
||||
const { target } = parseReferenceAnnotation(TECHDOCS_ANNOTATION, entity);
|
||||
|
||||
|
||||
@@ -14,13 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { loggerToWinstonLogger } from '@backstage/backend-common';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { Generators } from './generators';
|
||||
import { TechdocsGenerator } from './techdocs';
|
||||
import { mockServices } from '@backstage/backend-test-utils';
|
||||
|
||||
const logger = loggerToWinstonLogger(mockServices.logger.mock());
|
||||
const logger = mockServices.logger.mock();
|
||||
|
||||
const mockEntity = {
|
||||
apiVersion: 'version',
|
||||
|
||||
@@ -14,10 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
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 {
|
||||
@@ -25,6 +23,8 @@ import {
|
||||
GeneratorBuilder,
|
||||
SupportedGeneratorKey,
|
||||
} from './types';
|
||||
import { LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { TechDocsContainerRunner } from '../publish/types';
|
||||
|
||||
/**
|
||||
* Collection of docs generators
|
||||
@@ -41,8 +41,8 @@ export class Generators implements GeneratorBuilder {
|
||||
static async fromConfig(
|
||||
config: Config,
|
||||
options: {
|
||||
logger: Logger;
|
||||
containerRunner?: ContainerRunner;
|
||||
logger: LoggerService;
|
||||
containerRunner?: TechDocsContainerRunner;
|
||||
customGenerator?: TechdocsGenerator;
|
||||
},
|
||||
): Promise<GeneratorBuilder> {
|
||||
|
||||
@@ -37,7 +37,6 @@ import {
|
||||
patchMkdocsYmlWithPlugins,
|
||||
} from './mkdocsPatchers';
|
||||
import yaml from 'js-yaml';
|
||||
import { loggerToWinstonLogger } from '@backstage/backend-common';
|
||||
|
||||
const mockEntity = {
|
||||
apiVersion: 'version',
|
||||
@@ -93,7 +92,7 @@ const mkdocsYmlWithAdditionalPluginsWithConfig = fs.readFileSync(
|
||||
const mkdocsYmlWithEnvTag = fs.readFileSync(
|
||||
resolvePath(__filename, '../__fixtures__/mkdocs_with_env_tag.yml'),
|
||||
);
|
||||
const mockLogger = loggerToWinstonLogger(mockServices.logger.mock());
|
||||
const mockLogger = mockServices.logger.mock();
|
||||
const warn = jest.spyOn(mockLogger, 'warn');
|
||||
|
||||
const scmIntegrations = ScmIntegrations.fromConfig(new ConfigReader({}));
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { isChildPath } from '@backstage/backend-plugin-api';
|
||||
import { isChildPath, LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { assertError, ForwardedError } from '@backstage/errors';
|
||||
import { ScmIntegrationRegistry } from '@backstage/integration';
|
||||
@@ -24,7 +24,6 @@ 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';
|
||||
@@ -298,7 +297,7 @@ export const patchIndexPreBuild = async ({
|
||||
docsDir = 'docs',
|
||||
}: {
|
||||
inputDir: string;
|
||||
logger: Logger;
|
||||
logger: LoggerService;
|
||||
docsDir?: string;
|
||||
}) => {
|
||||
const docsPath = path.join(inputDir, docsDir);
|
||||
@@ -342,7 +341,7 @@ export const patchIndexPreBuild = async ({
|
||||
*/
|
||||
export const createOrUpdateMetadata = async (
|
||||
techdocsMetadataPath: string,
|
||||
logger: Logger,
|
||||
logger: LoggerService,
|
||||
): 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: Logger,
|
||||
logger: LoggerService,
|
||||
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: Logger,
|
||||
logger: LoggerService,
|
||||
parsedLocationAnnotation: ParsedLocationAnnotation,
|
||||
scmIntegrations: ScmIntegrationRegistry,
|
||||
) => {
|
||||
@@ -149,7 +149,7 @@ export const patchMkdocsYmlPreBuild = async (
|
||||
*/
|
||||
export const patchMkdocsYmlWithPlugins = async (
|
||||
mkdocsYmlPath: string,
|
||||
logger: Logger,
|
||||
logger: LoggerService,
|
||||
defaultPlugins: string[] = ['techdocs-core'],
|
||||
) => {
|
||||
await patchMkdocsFile(mkdocsYmlPath, logger, mkdocsYml => {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
import { Config } from '@backstage/config';
|
||||
import path from 'path';
|
||||
import { Logger } from 'winston';
|
||||
import {
|
||||
ScmIntegrationRegistry,
|
||||
ScmIntegrations,
|
||||
@@ -43,7 +42,8 @@ import {
|
||||
} from './types';
|
||||
import { ForwardedError } from '@backstage/errors';
|
||||
import { DockerContainerRunner } from './DockerContainerRunner';
|
||||
import { ContainerRunner } from '@backstage/backend-common';
|
||||
import { LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { TechDocsContainerRunner } from '../publish/types';
|
||||
|
||||
/**
|
||||
* Generates documentation files
|
||||
@@ -55,8 +55,8 @@ 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.4';
|
||||
private readonly logger: Logger;
|
||||
private readonly containerRunner?: ContainerRunner;
|
||||
private readonly logger: LoggerService;
|
||||
private readonly containerRunner?: TechDocsContainerRunner;
|
||||
private readonly options: GeneratorConfig;
|
||||
private readonly scmIntegrations: ScmIntegrationRegistry;
|
||||
|
||||
@@ -77,8 +77,8 @@ export class TechdocsGenerator implements GeneratorBase {
|
||||
}
|
||||
|
||||
constructor(options: {
|
||||
logger: Logger;
|
||||
containerRunner?: ContainerRunner;
|
||||
logger: LoggerService;
|
||||
containerRunner?: TechDocsContainerRunner;
|
||||
config: Config;
|
||||
scmIntegrations: ScmIntegrationRegistry;
|
||||
}) {
|
||||
@@ -216,7 +216,7 @@ export class TechdocsGenerator implements GeneratorBase {
|
||||
|
||||
export function readGeneratorConfig(
|
||||
config: Config,
|
||||
logger: Logger,
|
||||
logger: LoggerService,
|
||||
): GeneratorConfig {
|
||||
const legacyGeneratorType = config.getOptionalString(
|
||||
'techdocs.generators.techdocs',
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { Writable } from 'stream';
|
||||
import { Logger } from 'winston';
|
||||
import { ParsedLocationAnnotation } from '../../helpers';
|
||||
import { ContainerRunner } from '@backstage/backend-common';
|
||||
import { LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { TechDocsContainerRunner } from '../publish/types';
|
||||
|
||||
// Determines where the generator will be run
|
||||
export type GeneratorRunInType = 'docker' | 'local';
|
||||
@@ -28,12 +28,12 @@ export type GeneratorRunInType = 'docker' | 'local';
|
||||
* @public
|
||||
*/
|
||||
export type GeneratorOptions = {
|
||||
logger: Logger;
|
||||
logger: LoggerService;
|
||||
/**
|
||||
* @deprecated containerRunner is now instantiated in
|
||||
* the generator and this option will be removed in the future
|
||||
*/
|
||||
containerRunner?: ContainerRunner;
|
||||
containerRunner?: TechDocsContainerRunner;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -65,7 +65,7 @@ export type GeneratorRunOptions = {
|
||||
outputDir: string;
|
||||
parsedLocationAnnotation?: ParsedLocationAnnotation;
|
||||
etag?: string;
|
||||
logger: Logger;
|
||||
logger: LoggerService;
|
||||
logStream?: Writable;
|
||||
siteOptions?: { name?: string };
|
||||
runAsDefaultUser?: boolean;
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { loggerToWinstonLogger } from '@backstage/backend-common';
|
||||
import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { DirectoryPreparer } from './dir';
|
||||
@@ -31,7 +30,7 @@ jest.mock('../../helpers', () => ({
|
||||
...jest.requireActual<{}>('../../helpers'),
|
||||
}));
|
||||
|
||||
const logger = loggerToWinstonLogger(mockServices.logger.mock());
|
||||
const logger = mockServices.logger.mock();
|
||||
|
||||
const createMockEntity = (annotations: {}) => {
|
||||
return {
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { UrlReaderService } from '@backstage/backend-plugin-api';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { Config } from '@backstage/config';
|
||||
import { InputError } from '@backstage/errors';
|
||||
@@ -23,7 +22,6 @@ import {
|
||||
ScmIntegrations,
|
||||
} from '@backstage/integration';
|
||||
import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common';
|
||||
import { Logger } from 'winston';
|
||||
import { parseReferenceAnnotation, transformDirLocation } from '../../helpers';
|
||||
import {
|
||||
PreparerBase,
|
||||
@@ -31,6 +29,7 @@ import {
|
||||
PreparerOptions,
|
||||
PreparerResponse,
|
||||
} from './types';
|
||||
import { LoggerService, UrlReaderService } from '@backstage/backend-plugin-api';
|
||||
|
||||
/**
|
||||
* Preparer used to retrieve documentation files from a local directory
|
||||
@@ -54,7 +53,7 @@ export class DirectoryPreparer implements PreparerBase {
|
||||
|
||||
private constructor(
|
||||
config: Config,
|
||||
_logger: Logger | null,
|
||||
_logger: LoggerService | null,
|
||||
reader: UrlReaderService,
|
||||
) {
|
||||
this.reader = reader;
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
*/
|
||||
|
||||
import type { Entity } from '@backstage/catalog-model';
|
||||
import { UrlReaderService } from '@backstage/backend-plugin-api';
|
||||
import { Logger } from 'winston';
|
||||
import { LoggerService, UrlReaderService } from '@backstage/backend-plugin-api';
|
||||
|
||||
/**
|
||||
* A unique identifier of the tree blob, usually the commit SHA or etag from the target.
|
||||
@@ -29,7 +28,7 @@ export type ETag = string;
|
||||
* @public
|
||||
*/
|
||||
export type PreparerConfig = {
|
||||
logger: Logger;
|
||||
logger: LoggerService;
|
||||
reader: UrlReaderService;
|
||||
};
|
||||
|
||||
@@ -41,7 +40,7 @@ export type PreparerOptions = {
|
||||
/**
|
||||
* An instance of the logger
|
||||
*/
|
||||
logger?: Logger;
|
||||
logger?: LoggerService;
|
||||
/**
|
||||
* see {@link ETag}
|
||||
*/
|
||||
|
||||
@@ -15,9 +15,7 @@
|
||||
*/
|
||||
|
||||
import { assertError } from '@backstage/errors';
|
||||
import { UrlReaderService } from '@backstage/backend-plugin-api';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { Logger } from 'winston';
|
||||
import { getDocFilesFromRepository } from '../../helpers';
|
||||
import {
|
||||
PreparerBase,
|
||||
@@ -25,13 +23,14 @@ import {
|
||||
PreparerOptions,
|
||||
PreparerResponse,
|
||||
} from './types';
|
||||
import { LoggerService, UrlReaderService } from '@backstage/backend-plugin-api';
|
||||
|
||||
/**
|
||||
* Preparer used to retrieve documentation files from a remote repository
|
||||
* @public
|
||||
*/
|
||||
export class UrlPreparer implements PreparerBase {
|
||||
private readonly logger: Logger;
|
||||
private readonly logger: LoggerService;
|
||||
private readonly reader: UrlReaderService;
|
||||
|
||||
/**
|
||||
@@ -42,7 +41,7 @@ export class UrlPreparer implements PreparerBase {
|
||||
return new UrlPreparer(options.reader, options.logger);
|
||||
}
|
||||
|
||||
private constructor(reader: UrlReaderService, logger: Logger) {
|
||||
private constructor(reader: UrlReaderService, logger: LoggerService) {
|
||||
this.logger = logger;
|
||||
this.reader = reader;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ import {
|
||||
createMockDirectory,
|
||||
mockServices,
|
||||
} from '@backstage/backend-test-utils';
|
||||
import { loggerToWinstonLogger } from '@backstage/backend-common';
|
||||
|
||||
const env = process.env;
|
||||
let s3Mock: AwsClientStub<S3Client>;
|
||||
@@ -90,7 +89,7 @@ class ErrorReadable extends Readable {
|
||||
}
|
||||
}
|
||||
|
||||
const logger = loggerToWinstonLogger(mockServices.logger.mock());
|
||||
const logger = mockServices.logger.mock();
|
||||
const loggerInfoSpy = jest.spyOn(logger, 'info');
|
||||
const loggerErrorSpy = jest.spyOn(logger, 'error');
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ import JSON5 from 'json5';
|
||||
import createLimiter from 'p-limit';
|
||||
import path from 'path';
|
||||
import { Readable } from 'stream';
|
||||
import { Logger } from 'winston';
|
||||
import {
|
||||
bulkStorageOperation,
|
||||
getCloudPathForLocalPath,
|
||||
@@ -60,6 +59,7 @@ 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: Logger;
|
||||
private readonly logger: LoggerService;
|
||||
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: Logger;
|
||||
logger: LoggerService;
|
||||
bucketRootPath: string;
|
||||
sse?: 'aws:kms' | 'AES256';
|
||||
}) {
|
||||
@@ -102,7 +102,7 @@ export class AwsS3Publish implements PublisherBase {
|
||||
|
||||
static async fromConfig(
|
||||
config: Config,
|
||||
logger: Logger,
|
||||
logger: LoggerService,
|
||||
): Promise<PublisherBase> {
|
||||
let bucketName = '';
|
||||
try {
|
||||
@@ -524,7 +524,7 @@ export class AwsS3Publish implements PublisherBase {
|
||||
}
|
||||
|
||||
try {
|
||||
this.logger.verbose(`Migrating ${file}`);
|
||||
this.logger.debug(`Migrating ${file}`);
|
||||
await this.storageClient.send(
|
||||
new CopyObjectCommand({
|
||||
Bucket: this.bucketName,
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { loggerToWinstonLogger } from '@backstage/backend-common';
|
||||
import { Entity, DEFAULT_NAMESPACE } from '@backstage/catalog-model';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import express from 'express';
|
||||
@@ -224,8 +223,8 @@ const getEntityRootDir = (entity: Entity) => {
|
||||
return mockDir.resolve(namespace || DEFAULT_NAMESPACE, kind, name);
|
||||
};
|
||||
|
||||
const logger = loggerToWinstonLogger(mockServices.logger.mock());
|
||||
jest.spyOn(logger, 'error').mockReturnValue(logger);
|
||||
const logger = mockServices.logger.mock();
|
||||
jest.spyOn(logger, 'error');
|
||||
|
||||
const createPublisherFromConfig = ({
|
||||
accountName = 'accountName',
|
||||
|
||||
@@ -26,7 +26,6 @@ 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,
|
||||
@@ -43,6 +42,7 @@ 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: Logger;
|
||||
private readonly logger: LoggerService;
|
||||
|
||||
constructor(options: {
|
||||
storageClient: BlobServiceClient;
|
||||
containerName: string;
|
||||
legacyPathCasing: boolean;
|
||||
logger: Logger;
|
||||
logger: LoggerService;
|
||||
}) {
|
||||
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: Logger): PublisherBase {
|
||||
static fromConfig(config: Config, logger: LoggerService): PublisherBase {
|
||||
let storageClient: BlobServiceClient;
|
||||
let containerName = '';
|
||||
try {
|
||||
@@ -421,7 +421,7 @@ export class AzureBlobStoragePublish implements PublisherBase {
|
||||
|
||||
if (originalPath === newPath) return;
|
||||
try {
|
||||
this.logger.verbose(`Migrating ${originalPath}`);
|
||||
this.logger.debug(`Migrating ${originalPath}`);
|
||||
await this.renameBlob(originalPath, newPath, removeOriginal);
|
||||
} catch (e) {
|
||||
assertError(e);
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { loggerToWinstonLogger } from '@backstage/backend-common';
|
||||
import { Entity, DEFAULT_NAMESPACE } from '@backstage/catalog-model';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import express from 'express';
|
||||
@@ -139,9 +138,9 @@ const getEntityRootDir = (entity: Entity) => {
|
||||
return mockDir.resolve(namespace || DEFAULT_NAMESPACE, kind, name);
|
||||
};
|
||||
|
||||
const logger = loggerToWinstonLogger(mockServices.logger.mock());
|
||||
jest.spyOn(logger, 'info').mockReturnValue(logger);
|
||||
jest.spyOn(logger, 'error').mockReturnValue(logger);
|
||||
const logger = mockServices.logger.mock();
|
||||
jest.spyOn(logger, 'info');
|
||||
jest.spyOn(logger, 'error');
|
||||
|
||||
const createPublisherFromConfig = ({
|
||||
bucketName = 'bucketName',
|
||||
|
||||
@@ -26,7 +26,6 @@ import express from 'express';
|
||||
import JSON5 from 'json5';
|
||||
import path from 'path';
|
||||
import { Readable } from 'stream';
|
||||
import { Logger } from 'winston';
|
||||
import {
|
||||
getFileTreeRecursively,
|
||||
getHeadersForFileExtension,
|
||||
@@ -45,19 +44,20 @@ 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: Logger;
|
||||
private readonly logger: LoggerService;
|
||||
private readonly bucketRootPath: string;
|
||||
|
||||
constructor(options: {
|
||||
storageClient: Storage;
|
||||
bucketName: string;
|
||||
legacyPathCasing: boolean;
|
||||
logger: Logger;
|
||||
logger: LoggerService;
|
||||
bucketRootPath: string;
|
||||
}) {
|
||||
this.storageClient = options.storageClient;
|
||||
@@ -67,7 +67,7 @@ export class GoogleGCSPublish implements PublisherBase {
|
||||
this.bucketRootPath = options.bucketRootPath;
|
||||
}
|
||||
|
||||
static fromConfig(config: Config, logger: Logger): PublisherBase {
|
||||
static fromConfig(config: Config, logger: LoggerService): PublisherBase {
|
||||
let bucketName = '';
|
||||
try {
|
||||
bucketName = config.getString('techdocs.publisher.googleGcs.bucketName');
|
||||
|
||||
@@ -18,10 +18,11 @@ export type {
|
||||
PublisherBase,
|
||||
PublisherType,
|
||||
PublisherFactory,
|
||||
PublisherBuilder,
|
||||
PublishRequest,
|
||||
PublishResponse,
|
||||
MigrateRequest,
|
||||
ReadinessResponse,
|
||||
TechDocsMetadata,
|
||||
PublisherBuilder,
|
||||
TechDocsContainerRunner,
|
||||
} from './types';
|
||||
|
||||
@@ -13,10 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {
|
||||
loggerToWinstonLogger,
|
||||
PluginEndpointDiscovery,
|
||||
} from '@backstage/backend-common';
|
||||
import { overridePackagePathResolution } from '@backstage/backend-plugin-api/testUtils';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import express from 'express';
|
||||
@@ -28,6 +24,7 @@ import {
|
||||
createMockDirectory,
|
||||
mockServices,
|
||||
} from '@backstage/backend-test-utils';
|
||||
import { DiscoveryService } from '@backstage/backend-plugin-api';
|
||||
|
||||
const createMockEntity = (annotations = {}, lowerCase = false) => {
|
||||
return {
|
||||
@@ -42,7 +39,7 @@ const createMockEntity = (annotations = {}, lowerCase = false) => {
|
||||
};
|
||||
};
|
||||
|
||||
const testDiscovery: jest.Mocked<PluginEndpointDiscovery> = {
|
||||
const testDiscovery: jest.Mocked<DiscoveryService> = {
|
||||
getBaseUrl: jest.fn().mockResolvedValue('http://localhost:7007/api/techdocs'),
|
||||
getExternalBaseUrl: jest.fn(),
|
||||
};
|
||||
@@ -56,7 +53,7 @@ overridePackagePathResolution({
|
||||
},
|
||||
});
|
||||
|
||||
const logger = loggerToWinstonLogger(mockServices.logger.mock());
|
||||
const logger = mockServices.logger.mock();
|
||||
|
||||
describe('local publisher', () => {
|
||||
const mockDir = createMockDirectory();
|
||||
|
||||
@@ -13,8 +13,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { PluginEndpointDiscovery } from '@backstage/backend-common';
|
||||
|
||||
import {
|
||||
DiscoveryService,
|
||||
LoggerService,
|
||||
resolvePackagePath,
|
||||
resolveSafeChildPath,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
@@ -29,7 +31,6 @@ 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,
|
||||
@@ -51,13 +52,13 @@ import { ForwardedError } from '@backstage/errors';
|
||||
*/
|
||||
export class LocalPublish implements PublisherBase {
|
||||
private readonly legacyPathCasing: boolean;
|
||||
private readonly logger: Logger;
|
||||
private readonly discovery: PluginEndpointDiscovery;
|
||||
private readonly logger: LoggerService;
|
||||
private readonly discovery: DiscoveryService;
|
||||
private readonly staticDocsDir: string;
|
||||
|
||||
constructor(options: {
|
||||
logger: Logger;
|
||||
discovery: PluginEndpointDiscovery;
|
||||
logger: LoggerService;
|
||||
discovery: DiscoveryService;
|
||||
legacyPathCasing: boolean;
|
||||
staticDocsDir: string;
|
||||
}) {
|
||||
@@ -69,8 +70,8 @@ export class LocalPublish implements PublisherBase {
|
||||
|
||||
static fromConfig(
|
||||
config: Config,
|
||||
logger: Logger,
|
||||
discovery: PluginEndpointDiscovery,
|
||||
logger: LoggerService,
|
||||
discovery: DiscoveryService,
|
||||
): PublisherBase {
|
||||
const legacyPathCasing =
|
||||
config.getOptionalBoolean(
|
||||
@@ -299,7 +300,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.verbose(`Migrating ${relativeFile}`);
|
||||
this.logger.debug(`Migrating ${relativeFile}`);
|
||||
migrate(file, newFile, err => {
|
||||
if (err) {
|
||||
this.logger.warn(
|
||||
|
||||
@@ -17,20 +17,24 @@
|
||||
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: Logger;
|
||||
protected logger: LoggerService;
|
||||
protected removeOriginal: boolean;
|
||||
protected maxConcurrency: number;
|
||||
protected inFlight = 0;
|
||||
|
||||
constructor(logger: Logger, removeOriginal: boolean, concurrency: number) {
|
||||
constructor(
|
||||
logger: LoggerService,
|
||||
removeOriginal: boolean,
|
||||
concurrency: number,
|
||||
) {
|
||||
super({ objectMode: true });
|
||||
this.logger = logger;
|
||||
this.removeOriginal = removeOriginal;
|
||||
@@ -66,7 +70,7 @@ export class MigrateWriteStream extends Writable {
|
||||
const migrate = this.removeOriginal
|
||||
? file.move.bind(file)
|
||||
: file.copy.bind(file);
|
||||
this.logger.verbose(`Migrating ${file.name}`);
|
||||
this.logger.debug(`Migrating ${file.name}`);
|
||||
migrate(newFile)
|
||||
.catch(e =>
|
||||
this.logger.warn(`Unable to migrate ${file.name}: ${e.message}`),
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { loggerToWinstonLogger } from '@backstage/backend-common';
|
||||
import {
|
||||
Entity,
|
||||
CompoundEntityRef,
|
||||
@@ -172,7 +171,7 @@ const getPosixEntityRootDir = (entity: Entity) => {
|
||||
);
|
||||
};
|
||||
|
||||
const logger = loggerToWinstonLogger(mockServices.logger.mock());
|
||||
const logger = mockServices.logger.mock();
|
||||
|
||||
let publisher: PublisherBase;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import path from 'path';
|
||||
import { SwiftClient } from '@trendyol-js/openstack-swift-sdk';
|
||||
import { NotFound } from '@trendyol-js/openstack-swift-sdk/lib/types';
|
||||
import { Stream, Readable } from 'stream';
|
||||
import { Logger } from 'winston';
|
||||
|
||||
import {
|
||||
getFileTreeRecursively,
|
||||
getHeadersForFileExtension,
|
||||
@@ -37,6 +37,7 @@ 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 +62,19 @@ const bufferToStream = (buffer: Buffer): Readable => {
|
||||
export class OpenStackSwiftPublish implements PublisherBase {
|
||||
private readonly storageClient: SwiftClient;
|
||||
private readonly containerName: string;
|
||||
private readonly logger: Logger;
|
||||
private readonly logger: LoggerService;
|
||||
|
||||
constructor(options: {
|
||||
storageClient: SwiftClient;
|
||||
containerName: string;
|
||||
logger: Logger;
|
||||
logger: LoggerService;
|
||||
}) {
|
||||
this.storageClient = options.storageClient;
|
||||
this.containerName = options.containerName;
|
||||
this.logger = options.logger;
|
||||
}
|
||||
|
||||
static fromConfig(config: Config, logger: Logger): PublisherBase {
|
||||
static fromConfig(config: Config, logger: LoggerService): PublisherBase {
|
||||
let containerName = '';
|
||||
try {
|
||||
containerName = config.getString(
|
||||
@@ -326,7 +327,7 @@ export class OpenStackSwiftPublish implements PublisherBase {
|
||||
}
|
||||
|
||||
try {
|
||||
this.logger.verbose(`Migrating ${file} to ${newPath}`);
|
||||
this.logger.debug(`Migrating ${file} to ${newPath}`);
|
||||
await this.storageClient.copy(
|
||||
this.containerName,
|
||||
file,
|
||||
|
||||
@@ -13,10 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {
|
||||
PluginEndpointDiscovery,
|
||||
loggerToWinstonLogger,
|
||||
} from '@backstage/backend-common';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { Publisher } from './publish';
|
||||
import { LocalPublish } from './local';
|
||||
@@ -26,9 +22,10 @@ import { AzureBlobStoragePublish } from './azureBlobStorage';
|
||||
import { OpenStackSwiftPublish } from './openStackSwift';
|
||||
import { mockServices } from '@backstage/backend-test-utils';
|
||||
import { PublisherBase } from './types';
|
||||
import { DiscoveryService } from '@backstage/backend-plugin-api';
|
||||
|
||||
const logger = loggerToWinstonLogger(mockServices.logger.mock());
|
||||
const discovery: jest.Mocked<PluginEndpointDiscovery> = {
|
||||
const logger = mockServices.logger.mock();
|
||||
const discovery: jest.Mocked<DiscoveryService> = {
|
||||
getBaseUrl: jest.fn().mockResolvedValueOnce('http://localhost:7007'),
|
||||
getExternalBaseUrl: jest.fn(),
|
||||
};
|
||||
|
||||
@@ -13,19 +13,19 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Entity, CompoundEntityRef } from '@backstage/catalog-model';
|
||||
import { PluginEndpointDiscovery } from '@backstage/backend-common';
|
||||
import { Logger } from 'winston';
|
||||
import { Writable } from 'stream';
|
||||
import express from 'express';
|
||||
import { Config } from '@backstage/config';
|
||||
import { DiscoveryService, LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { Entity, CompoundEntityRef } from '@backstage/catalog-model';
|
||||
|
||||
/**
|
||||
* Options for building publishers
|
||||
* @public
|
||||
*/
|
||||
export type PublisherFactory = {
|
||||
logger: Logger;
|
||||
discovery: PluginEndpointDiscovery;
|
||||
logger: LoggerService;
|
||||
discovery: DiscoveryService;
|
||||
customPublisher?: PublisherBase | undefined;
|
||||
};
|
||||
|
||||
@@ -168,3 +168,36 @@ export type PublisherBuilder = {
|
||||
register(type: PublisherType, publisher: PublisherBase): void;
|
||||
get(config: Config): PublisherBase;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the running of containers, on behalf of others.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface TechDocsContainerRunner {
|
||||
/**
|
||||
* Runs a container image to completion.
|
||||
*/
|
||||
runContainer(opts: {
|
||||
imageName: string;
|
||||
command?: string | string[];
|
||||
args: string[];
|
||||
logStream?: Writable;
|
||||
mountDirs?: Record<string, string>;
|
||||
workingDir?: string;
|
||||
envVars?: Record<string, string>;
|
||||
pullImage?: boolean;
|
||||
defaultUser?: boolean;
|
||||
pullOptions?: {
|
||||
authconfig?: {
|
||||
username?: string;
|
||||
password?: string;
|
||||
auth?: string;
|
||||
email?: string;
|
||||
serveraddress?: string;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
[key: string]: unknown;
|
||||
};
|
||||
}): Promise<void>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user