diff --git a/workspaces/extensions/.changeset/loud-pugs-return.md b/workspaces/extensions/.changeset/loud-pugs-return.md new file mode 100644 index 0000000000..c658d758a8 --- /dev/null +++ b/workspaces/extensions/.changeset/loud-pugs-return.md @@ -0,0 +1,5 @@ +--- +'@red-hat-developer-hub/backstage-plugin-extensions': patch +--- + +Fix extension plugin Apply button to apply minimal YAML when the YAML section is empty diff --git a/workspaces/extensions/plugins/extensions/src/utils.test.ts b/workspaces/extensions/plugins/extensions/src/utils.test.ts index c5fadb8b03..aa27ebc31c 100644 --- a/workspaces/extensions/plugins/extensions/src/utils.test.ts +++ b/workspaces/extensions/plugins/extensions/src/utils.test.ts @@ -113,6 +113,37 @@ plugins: `, ); }); + + it('should create minimal YAML when editor is empty', () => { + const content = applyContent( + '', + 'backstage-community-plugin-quay', + packages, + mockNewContent, + ); + expect(content).toContain('plugins:'); + expect(content).toContain( + 'package: ./dynamic-plugins/dist/backstage-community-plugin-quay', + ); + expect(content).toContain('disabled: false'); + expect(content).toContain('pluginConfig:'); + expect(content).toContain('catalog:'); + }); + + it('should create minimal YAML when editor has only whitespace', () => { + const content = applyContent( + ' \n \t ', + 'backstage-community-plugin-quay', + packages, + mockNewContent, + ); + expect(content).toContain('plugins:'); + expect(content).toContain( + 'package: ./dynamic-plugins/dist/backstage-community-plugin-quay', + ); + expect(content).toContain('disabled: false'); + expect(content).toContain('pluginConfig:'); + }); }); describe('getExampleAsMarkdown', () => { diff --git a/workspaces/extensions/plugins/extensions/src/utils.ts b/workspaces/extensions/plugins/extensions/src/utils.ts index 3a8062756f..c0c9056fa8 100644 --- a/workspaces/extensions/plugins/extensions/src/utils.ts +++ b/workspaces/extensions/plugins/extensions/src/utils.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { Pair, parseDocument, Scalar, YAMLSeq, stringify } from 'yaml'; +import { Pair, parse, parseDocument, Scalar, YAMLSeq, stringify } from 'yaml'; import { JsonObject } from '@backstage/types'; import { ExtensionsPluginInstallStatus } from '@red-hat-developer-hub/backstage-plugin-extensions-common'; import { TranslationFunction } from '@backstage/core-plugin-api/alpha'; @@ -80,13 +80,29 @@ export const applyContent = ( otherPackageNames: { [key: string]: string }, newContent: string | JsonObject, ) => { - if (!editorContent) { - return null; + if (!editorContent || !editorContent.trim()) { + const packagePath = otherPackageNames[packageName]; + if (!packagePath) { + return null; + } + + const minimalYaml = { + plugins: [ + { + package: packagePath, + disabled: false, + pluginConfig: + typeof newContent === 'string' ? parse(newContent) : newContent, + }, + ], + }; + return stringify(minimalYaml); } const content = parseDocument(editorContent); const plugins = content.get('plugins'); if (plugins instanceof YAMLSeq && Array.isArray(plugins?.items)) { + let foundPackage = false; (plugins?.items || []).forEach((plugin: any) => { if (plugin instanceof Object) { const pluginPackage = plugin.items?.find((i: Pair) => { @@ -96,6 +112,7 @@ export const applyContent = ( ); }); if (pluginPackage) { + foundPackage = true; if (typeof newContent === 'string') { plugin.set('pluginConfig', parseDocument(newContent)); } else { @@ -104,6 +121,36 @@ export const applyContent = ( } } }); + + if (!foundPackage) { + const packagePath = otherPackageNames[packageName]; + if (packagePath) { + const newPlugin: any = { + package: packagePath, + disabled: false, + }; + if (typeof newContent === 'string') { + newPlugin.pluginConfig = parseDocument(newContent); + } else { + newPlugin.pluginConfig = newContent; + } + plugins.add(newPlugin); + } + } + } else { + const packagePath = otherPackageNames[packageName]; + if (packagePath) { + const newPlugin: any = { + package: packagePath, + disabled: false, + }; + if (typeof newContent === 'string') { + newPlugin.pluginConfig = parseDocument(newContent); + } else { + newPlugin.pluginConfig = newContent; + } + content.set('plugins', [newPlugin]); + } } return content.toString(); };