techdocs-node: do not export ContainerRunner definitions

Signed-off-by: Vincenzo Scamporlino <vincenzos@spotify.com>
This commit is contained in:
Vincenzo Scamporlino
2024-06-13 15:04:48 +02:00
parent 2110d76586
commit c674ffc164
8 changed files with 24 additions and 82 deletions
@@ -18,7 +18,6 @@ import fs from 'fs-extra';
import Stream, { PassThrough } from 'stream';
import { DockerContainerRunner, UserOptions } from './DockerContainerRunner';
import { createMockDirectory } from '@backstage/backend-test-utils';
import { ContainerRunner } from './types';
const mockPull = jest.fn();
const mockRun = jest.fn();
@@ -37,7 +36,7 @@ jest.mock(
);
describe('DockerContainerRunner', () => {
let containerTaskApi: ContainerRunner;
let containerTaskApi: DockerContainerRunner;
const inputDir = createMockDirectory();
const outputDir = createMockDirectory();
@@ -20,7 +20,7 @@ import { ForwardedError } from '@backstage/errors';
import { PassThrough } from 'stream';
import { pipeline as pipelineStream } from 'stream';
import { promisify } from 'util';
import { ContainerRunner, RunContainerOptions } from './types';
import { Writable } from 'stream';
const pipeline = promisify(pipelineStream);
@@ -29,18 +29,26 @@ export type UserOptions = {
};
/**
* A {@link ContainerRunner} for Docker containers.
*
* @public
* @internal
*/
export class DockerContainerRunner implements ContainerRunner {
export class DockerContainerRunner {
private readonly dockerClient: Docker;
constructor() {
this.dockerClient = new Docker();
}
async runContainer(options: RunContainerOptions) {
async runContainer(options: {
imageName: string;
command?: string | string[];
args: string[];
logStream?: Writable;
mountDirs?: Record<string, string>;
workingDir?: string;
envVars?: Record<string, string>;
pullImage?: boolean;
defaultUser?: boolean;
}) {
const {
imageName,
command,
@@ -14,10 +14,7 @@
* limitations under the License.
*/
import {
ContainerRunner,
loggerToWinstonLogger,
} from '@backstage/backend-common';
import { loggerToWinstonLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { Generators } from './generators';
import { TechdocsGenerator } from './techdocs';
@@ -34,10 +31,6 @@ const mockEntity = {
};
describe('generators', () => {
const containerRunner: jest.Mocked<ContainerRunner> = {
runContainer: jest.fn(),
};
it('should return error if no generator is registered', async () => {
const generators = new Generators();
@@ -50,7 +43,6 @@ describe('generators', () => {
const generators = new Generators();
const techdocs = TechdocsGenerator.fromConfig(new ConfigReader({}), {
logger,
containerRunner,
});
generators.register('techdocs', techdocs);
@@ -17,8 +17,6 @@ export { TechdocsGenerator } from './techdocs';
export { Generators } from './generators';
export { getMkdocsYml } from './helpers';
export type {
RunContainerOptions,
ContainerRunner,
GeneratorBase,
GeneratorOptions,
GeneratorBuilder,
@@ -35,7 +35,6 @@ import {
patchMkdocsYmlWithPlugins,
} from './mkdocsPatchers';
import {
ContainerRunner,
GeneratorBase,
GeneratorConfig,
GeneratorOptions,
@@ -58,18 +57,17 @@ export class TechdocsGenerator implements GeneratorBase {
private readonly logger: Logger;
private readonly options: GeneratorConfig;
private readonly scmIntegrations: ScmIntegrationRegistry;
private containerRunner?: ContainerRunner;
/**
* Returns a instance of TechDocs generator
* @param config - A Backstage configuration
* @param options - Options to configure the generator
*/
static fromConfig(config: Config, options: GeneratorOptions) {
const { containerRunner, logger } = options;
const { logger } = options;
const scmIntegrations = ScmIntegrations.fromConfig(config);
return new TechdocsGenerator({
logger,
containerRunner,
config,
scmIntegrations,
});
@@ -77,13 +75,11 @@ export class TechdocsGenerator implements GeneratorBase {
constructor(options: {
logger: Logger;
containerRunner?: ContainerRunner;
config: Config;
scmIntegrations: ScmIntegrationRegistry;
}) {
this.logger = options.logger;
this.options = readGeneratorConfig(options.config, options.logger);
this.containerRunner = options.containerRunner;
this.scmIntegrations = options.scmIntegrations;
}
@@ -155,11 +151,9 @@ export class TechdocsGenerator implements GeneratorBase {
`Successfully generated docs from ${inputDir} into ${outputDir} using local mkdocs`,
);
break;
case 'docker':
if (this.containerRunner === undefined) {
this.containerRunner = new DockerContainerRunner();
}
await this.containerRunner.runContainer({
case 'docker': {
const containerRunner = new DockerContainerRunner();
await containerRunner.runContainer({
imageName:
this.options.dockerImage ?? TechdocsGenerator.defaultDockerImage,
args: ['build', '-d', '/output'],
@@ -176,6 +170,7 @@ export class TechdocsGenerator implements GeneratorBase {
`Successfully generated docs from ${inputDir} into ${outputDir} using techdocs-container`,
);
break;
}
default:
throw new Error(
`Invalid config value "${this.options.runIn}" provided in 'techdocs.generators.techdocs'.`,
@@ -27,7 +27,6 @@ export type GeneratorRunInType = 'docker' | 'local';
* @public
*/
export type GeneratorOptions = {
containerRunner?: ContainerRunner;
logger: Logger;
};
@@ -98,32 +97,3 @@ export type DefaultMkdocsContent = {
docs_dir: string;
plugins: String[];
};
/**
* Options passed to the {@link ContainerRunner.runContainer} method.
*
* @public
*/
export type RunContainerOptions = {
imageName: string;
command?: string | string[];
args: string[];
logStream?: Writable;
mountDirs?: Record<string, string>;
workingDir?: string;
envVars?: Record<string, string>;
pullImage?: boolean;
defaultUser?: boolean;
};
/**
* Handles the running of containers, on behalf of others.
*
* @public
*/
export interface ContainerRunner {
/**
* Runs a container image to completion.
*/
runContainer(opts: RunContainerOptions): Promise<void>;
}