diff --git a/docs/features/software-templates/writing-custom-field-extensions.md b/docs/features/software-templates/writing-custom-field-extensions.md new file mode 100644 index 0000000000..e32aa4e78d --- /dev/null +++ b/docs/features/software-templates/writing-custom-field-extensions.md @@ -0,0 +1,34 @@ +--- +id: writing-custom-field-extensions +title: Writing Custom Field Extensions +description: How to write your own field extensions +--- + +Collecting input from the user is a very large part of the scaffolding process +and Software Templates as a whole. Sometimes the built in components and fields +just aren't good enough, and sometimes you want to enrich the form that the +users sees with better inputs that fit better. + +This is where `Custom Field Extensions` come in. + +With them you can show your own `React` Components and use them to control the +state of the JSON schema, as well as provide your own validation functions to +validate the data too. + +## Creating a Field Extension + +Field extensions are a way to combine an ID, a `React` Component and a +`validation` function together in a modular way that you can then use to pass to +the `Scaffolder` frontend plugin in your own `App.tsx`. + +You can create your own Field Extension by using the +`createScaffolderFieldExtension` `API` like below: + +```tsx +//packages/app/scaffolder/MyCustomExtension/MyCustomExtension.tsx +export const MyCustomExtension = () => {}; +``` + +```tsx +// packages/app/scaffolder/MyCustomExtension/validation.ts +``` diff --git a/packages/backend-common/src/reading/AzureUrlReader.ts b/packages/backend-common/src/reading/AzureUrlReader.ts index 910e8e04a5..5369306702 100644 --- a/packages/backend-common/src/reading/AzureUrlReader.ts +++ b/packages/backend-common/src/reading/AzureUrlReader.ts @@ -133,6 +133,7 @@ export class AzureUrlReader implements UrlReader { stream: archiveAzureResponse.body as unknown as Readable, etag: commitSha, filter: options?.filter, + stripFirstDirectory: true, }); } diff --git a/packages/backend-common/src/reading/tree/ReadTreeResponseFactory.ts b/packages/backend-common/src/reading/tree/ReadTreeResponseFactory.ts index 5fdd633102..70d8f63af8 100644 --- a/packages/backend-common/src/reading/tree/ReadTreeResponseFactory.ts +++ b/packages/backend-common/src/reading/tree/ReadTreeResponseFactory.ts @@ -55,6 +55,7 @@ export class DefaultReadTreeResponseFactory implements ReadTreeResponseFactory { this.workDir, options.etag, options.filter, + options.stripFirstDirectory, ); } } diff --git a/packages/backend-common/src/reading/types.ts b/packages/backend-common/src/reading/types.ts index b7e1ff823f..2d9c305b85 100644 --- a/packages/backend-common/src/reading/types.ts +++ b/packages/backend-common/src/reading/types.ts @@ -182,6 +182,9 @@ export type ReadTreeResponseFactoryOptions = { etag: string; // Filter passed on from the ReadTreeOptions filter?: (path: string, info?: { size: number }) => boolean; + + // Strip the first directory in the readTree response + stripFirstDirectory?: boolean; }; /** @public */ diff --git a/plugins/scaffolder-backend/src/test-integrations.ts b/plugins/scaffolder-backend/src/test-integrations.ts new file mode 100644 index 0000000000..65d84768aa --- /dev/null +++ b/plugins/scaffolder-backend/src/test-integrations.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + loadBackendConfig, + getRootLogger, + UrlReaders, +} from '@backstage/backend-common'; +// import { ScmIntegrations } from '@backstage/integration'; + +const run = async () => { + const root = getRootLogger(); + const config = await loadBackendConfig({ + argv: process.argv, + logger: root, + }); + + // const integrations = ScmIntegrations.fromConfig(config); + const reader = UrlReaders.default({ logger: root, config }); + + console.log( + await reader.readTree( + 'https://dev.azure.com/backstage-verification/test-template-fetch/_git/test-template-fetch', + ), + ); +}; + +run();