feat: support custom default plugins for techdocs
Signed-off-by: Dominik Schwank <dominik.schwank@sda.se>
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-backend': minor
|
||||
'@backstage/plugin-techdocs-node': minor
|
||||
---
|
||||
|
||||
Add support for default mkdocs plugins.
|
||||
|
||||
So far only `techdocs-core` was added as default to the list of mkdocs plugins. In case you use a
|
||||
custom image for techdocs, you also might want to add custom default plugins for mkdocs.
|
||||
With this change one can do that - example:
|
||||
|
||||
```yaml
|
||||
techdocs:
|
||||
generator:
|
||||
mkdocs:
|
||||
defaultPlugins:
|
||||
- section-index
|
||||
```
|
||||
@@ -49,6 +49,15 @@ techdocs:
|
||||
# will be broken in these scenarios.
|
||||
legacyCopyReadmeMdToIndexMd: false
|
||||
|
||||
# (Optional) Configures the default plugins which should be added
|
||||
# automatically to every mkdocs.yaml file. This simplifies the usage as
|
||||
# e.g. styling plugins can be added once for all.
|
||||
# Make sure that the defined plugins are installed locally / in the Docker
|
||||
# image.
|
||||
# By default, only the techdocs-core plugin will be added (except if
|
||||
# omitTechdocsCorePlugin: true).
|
||||
defaultPlugins: ['techdocs-core']
|
||||
|
||||
# techdocs.builder can be either 'local' or 'external'.
|
||||
# Using the default build strategy, if builder is set to 'local' and you open a TechDocs page,
|
||||
# techdocs-backend will try to generate the docs, publish to storage and show the generated docs afterwards.
|
||||
|
||||
Vendored
+5
@@ -57,6 +57,11 @@ export interface Config {
|
||||
* will be broken in these scenarios.
|
||||
*/
|
||||
legacyCopyReadmeMdToIndexMd?: boolean;
|
||||
|
||||
/**
|
||||
* List of mkdocs plugins which should be added as default to all mkdocs.yml files.
|
||||
*/
|
||||
defaultPlugins?: string[];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ import {
|
||||
} from './helpers';
|
||||
import {
|
||||
patchMkdocsYmlPreBuild,
|
||||
pathMkdocsYmlWithTechdocsPlugin,
|
||||
patchMkdocsYmlWithPlugins,
|
||||
} from './mkdocsPatchers';
|
||||
import yaml from 'js-yaml';
|
||||
|
||||
@@ -310,7 +310,7 @@ describe('helpers', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('pathMkdocsYmlWithTechdocsPlugin', () => {
|
||||
describe('patchMkdocsYmlWithPlugins', () => {
|
||||
beforeEach(() => {
|
||||
mockFs({
|
||||
'/mkdocs_with_techdocs_plugin.yml': mkdocsYmlWithTechdocsPlugins,
|
||||
@@ -319,7 +319,7 @@ describe('helpers', () => {
|
||||
});
|
||||
});
|
||||
it('should not add additional plugins if techdocs exists already in mkdocs file', async () => {
|
||||
await pathMkdocsYmlWithTechdocsPlugin(
|
||||
await patchMkdocsYmlWithPlugins(
|
||||
'/mkdocs_with_techdocs_plugin.yml',
|
||||
mockLogger,
|
||||
);
|
||||
@@ -334,7 +334,7 @@ describe('helpers', () => {
|
||||
expect(parsedYml.plugins).toContain('techdocs-core');
|
||||
});
|
||||
it("should add the needed plugin if it doesn't exist in mkdocs file", async () => {
|
||||
await pathMkdocsYmlWithTechdocsPlugin(
|
||||
await patchMkdocsYmlWithPlugins(
|
||||
'/mkdocs_without_plugins.yml',
|
||||
mockLogger,
|
||||
);
|
||||
@@ -347,7 +347,7 @@ describe('helpers', () => {
|
||||
expect(parsedYml.plugins).toContain('techdocs-core');
|
||||
});
|
||||
it('should not override existing plugins', async () => {
|
||||
await pathMkdocsYmlWithTechdocsPlugin(
|
||||
await patchMkdocsYmlWithPlugins(
|
||||
'/mkdocs_with_additional_plugins.yml',
|
||||
mockLogger,
|
||||
);
|
||||
@@ -362,6 +362,23 @@ describe('helpers', () => {
|
||||
expect(parsedYml.plugins).toContain('not-techdocs-core');
|
||||
expect(parsedYml.plugins).toContain('also-not-techdocs-core');
|
||||
});
|
||||
it('should add all provided default plugins', async () => {
|
||||
await patchMkdocsYmlWithPlugins(
|
||||
'/mkdocs_with_additional_plugins.yml',
|
||||
mockLogger,
|
||||
['techdocs-core', 'custom-plugin'],
|
||||
);
|
||||
|
||||
const updatedMkdocsYml = await fs.readFile(
|
||||
'/mkdocs_with_additional_plugins.yml',
|
||||
);
|
||||
const parsedYml = yaml.load(updatedMkdocsYml.toString()) as {
|
||||
plugins: string[];
|
||||
};
|
||||
expect(parsedYml.plugins).toHaveLength(4);
|
||||
expect(parsedYml.plugins).toContain('techdocs-core');
|
||||
expect(parsedYml.plugins).toContain('custom-plugin');
|
||||
});
|
||||
});
|
||||
|
||||
describe('patchIndexPreBuild', () => {
|
||||
|
||||
@@ -138,27 +138,34 @@ export const patchMkdocsYmlPreBuild = async (
|
||||
* Update the mkdocs.yml file before TechDocs generator uses it to generate docs site.
|
||||
*
|
||||
* List of tasks:
|
||||
* - Add techdocs-core plugin to mkdocs file if it doesn't exist
|
||||
* - Add all provided default plugins
|
||||
*
|
||||
* This function will not throw an error since this is not critical to the whole TechDocs pipeline.
|
||||
* Instead it will log warnings if there are any errors in reading, parsing or writing YAML.
|
||||
*
|
||||
* @param mkdocsYmlPath - Absolute path to mkdocs.yml or equivalent of a docs site
|
||||
* @param logger - A logger instance
|
||||
* @param defaultPlugins - List of default mkdocs plugins
|
||||
*/
|
||||
export const pathMkdocsYmlWithTechdocsPlugin = async (
|
||||
export const patchMkdocsYmlWithPlugins = async (
|
||||
mkdocsYmlPath: string,
|
||||
logger: Logger,
|
||||
defaultPlugins: string[] = ['techdocs-core'],
|
||||
) => {
|
||||
await patchMkdocsFile(mkdocsYmlPath, logger, mkdocsYml => {
|
||||
// Modify mkdocs.yaml to contain the needed techdocs-core plugin if it is not there
|
||||
// Modify mkdocs.yaml to contain the required default plugins
|
||||
if (!('plugins' in mkdocsYml)) {
|
||||
mkdocsYml.plugins = ['techdocs-core'];
|
||||
mkdocsYml.plugins = defaultPlugins;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mkdocsYml.plugins && !mkdocsYml.plugins.includes('techdocs-core')) {
|
||||
mkdocsYml.plugins.push('techdocs-core');
|
||||
if (
|
||||
mkdocsYml.plugins &&
|
||||
!defaultPlugins.every(plugin => mkdocsYml.plugins!.includes(plugin))
|
||||
) {
|
||||
mkdocsYml.plugins = [
|
||||
...new Set([...mkdocsYml.plugins, ...defaultPlugins]),
|
||||
];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -157,4 +157,24 @@ describe('readGeneratorConfig', () => {
|
||||
legacyCopyReadmeMdToIndexMd: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should read the default plugins config', () => {
|
||||
const config = new ConfigReader({
|
||||
techdocs: {
|
||||
generator: {
|
||||
runIn: 'docker',
|
||||
dockerImage: 'my-org/techdocs',
|
||||
pullImage: false,
|
||||
mkdocs: { defaultPlugins: ['mkdocs-custom-plugin'] },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(readGeneratorConfig(config, logger)).toEqual({
|
||||
runIn: 'docker',
|
||||
dockerImage: 'my-org/techdocs',
|
||||
pullImage: false,
|
||||
defaultPlugins: ['mkdocs-custom-plugin'],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -33,7 +33,7 @@ import {
|
||||
|
||||
import {
|
||||
patchMkdocsYmlPreBuild,
|
||||
pathMkdocsYmlWithTechdocsPlugin,
|
||||
patchMkdocsYmlWithPlugins,
|
||||
} from './mkdocsPatchers';
|
||||
import {
|
||||
GeneratorBase,
|
||||
@@ -121,10 +121,18 @@ export class TechdocsGenerator implements GeneratorBase {
|
||||
await patchIndexPreBuild({ inputDir, logger: childLogger, docsDir });
|
||||
}
|
||||
|
||||
if (!this.options.omitTechdocsCoreMkdocsPlugin) {
|
||||
await pathMkdocsYmlWithTechdocsPlugin(mkdocsYmlPath, childLogger);
|
||||
// patch the list of mkdocs plugins
|
||||
const defaultPlugins = this.options.defaultPlugins ?? [];
|
||||
|
||||
if (
|
||||
!this.options.omitTechdocsCoreMkdocsPlugin &&
|
||||
!defaultPlugins.includes('techdocs-core')
|
||||
) {
|
||||
defaultPlugins.push('techdocs-core');
|
||||
}
|
||||
|
||||
await patchMkdocsYmlWithPlugins(mkdocsYmlPath, childLogger, defaultPlugins);
|
||||
|
||||
// Directories to bind on container
|
||||
const mountDirs = {
|
||||
[inputDir]: '/input',
|
||||
@@ -233,5 +241,8 @@ export function readGeneratorConfig(
|
||||
legacyCopyReadmeMdToIndexMd: config.getOptionalBoolean(
|
||||
'techdocs.generator.mkdocs.legacyCopyReadmeMdToIndexMd',
|
||||
),
|
||||
defaultPlugins: config.getOptionalStringArray(
|
||||
'techdocs.generator.mkdocs.defaultPlugins',
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ export type GeneratorConfig = {
|
||||
pullImage?: boolean;
|
||||
omitTechdocsCoreMkdocsPlugin?: boolean;
|
||||
legacyCopyReadmeMdToIndexMd?: boolean;
|
||||
defaultPlugins?: string[];
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user