From 1a92f17fa537b55529adbec80203bd99afd8cd24 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Tue, 23 Jul 2024 10:48:29 -0700 Subject: [PATCH] [api-extractor] Clarify "reportFileName" semantics (#4846) * Update api-extractor-template.json to document reportVariants; clarify associated docs * Fix an edge case where indexOf() would incorrectly match the middle of a string * rush change --- apps/api-extractor/src/api/ExtractorConfig.ts | 5 +-- apps/api-extractor/src/api/IConfigFile.ts | 34 +++++++-------- .../src/schemas/api-extractor-template.json | 42 +++++++++++++------ .../src/schemas/api-extractor.schema.json | 28 ++++++------- ...rtfilename-extension_2024-07-22-22-08.json | 10 +++++ 5 files changed, 71 insertions(+), 48 deletions(-) create mode 100644 common/changes/@microsoft/api-extractor/octogonz-ae-reportfilename-extension_2024-07-22-22-08.json diff --git a/apps/api-extractor/src/api/ExtractorConfig.ts b/apps/api-extractor/src/api/ExtractorConfig.ts index 7d0fb3c7319..1cdf8c96eb2 100644 --- a/apps/api-extractor/src/api/ExtractorConfig.ts +++ b/apps/api-extractor/src/api/ExtractorConfig.ts @@ -931,8 +931,7 @@ export class ExtractorConfig { ); } - const suffixIndex: number = apiReportConfig.reportFileName.indexOf(reportFileNameSuffix); - if (suffixIndex < 0) { + if (!apiReportConfig.reportFileName.endsWith(reportFileNameSuffix)) { // `.api.md` extension was not specified. Use provided file name base as is. reportFileNameBase = apiReportConfig.reportFileName; } else { @@ -941,7 +940,7 @@ export class ExtractorConfig { // that ends with the `.api.md` extension specially, by stripping it out. // This should be removed in version 8, possibly replaced with an explicit error to help users // migrate their configs. - reportFileNameBase = apiReportConfig.reportFileName.slice(0, suffixIndex); + reportFileNameBase = apiReportConfig.reportFileName.slice(0, -reportFileNameSuffix.length); } } else { // Default value diff --git a/apps/api-extractor/src/api/IConfigFile.ts b/apps/api-extractor/src/api/IConfigFile.ts index e60def3af7e..1a0884d1af0 100644 --- a/apps/api-extractor/src/api/IConfigFile.ts +++ b/apps/api-extractor/src/api/IConfigFile.ts @@ -70,21 +70,20 @@ export interface IConfigApiReport { enabled: boolean; /** - * The base component of API report filenames. + * The base filename for the API report files, to be combined with {@link IConfigApiReport.reportFolder} or + * {@link IConfigApiReport.reportTempFolder} to produce the full file path. * * @remarks - * It will be combined with the specified {@link IConfigApiReport.reportVariants}, and {@link IConfigApiReport.reportFolder} and {@link IConfigApiReport.reportTempFolder} to - * produce a full output filenames in the form `..api.md`. + * The `reportFileName` should not include any path separators such as `\` or `/`. The `reportFileName` should + * not include a file extension, since API Extractor will automatically append an appropriate file extension such + * as `.api.md`. If the {@link IConfigApiReport.reportVariants} setting is used, then the file extension includes + * the variant name, for example `my-report.public.api.md` or `my-report.beta.api.md`. The `complete` variant always + * uses the simple extension `my-report.api.md`. * - * The string should not contain a file extension. - * Note: previous guidance noted that this should be specified in a form including the `.api.md` extension. - * This is no longer recommended, and support for this will be removed in a future release. - * For example, if you were previously specifying `Foo.api.md`, you should now specify `Foo`. - * The `.api.md` extension will be added automatically to the resulting filename. + * Previous versions of API Extractor required `reportFileName` to include the `.api.md` extension explicitly; + * for backwards compatibility, that is still accepted but will be discarded before applying the above rules. * - * The string must not contain a path separator such as `\` or `/`. - * - * @defaultValue `.api.md` will be used if this argument is not specified or if it is empty. + * @defaultValue `` */ reportFileName?: string; @@ -92,16 +91,15 @@ export interface IConfigApiReport { * The set of report variants to generate. * * @remarks - * Each variant corresponds to a minimal release level, denoted by release tag in the TSDoc comment for each API item. - * E.g., the `beta` report variant will include all API items tagged `@beta` or higher (i.e. `@beta` and `@public`). + * To support different approval requirements for different API levels, multiple "variants" of the API report can + * be generated. The `reportVariants` setting specifies a list of variants to be generated. If omitted, + * by default only the `complete` variant will be generated, which includes all `@internal`, `@alpha`, `@beta`, + * and `@public` items. Other possible variants are `alpha` (`@alpha` + `@beta` + `@public`), + * `beta` (`@beta` + `@public`), and `public` (`@public only`). * * The resulting API report file names will be derived from the {@link IConfigApiReport.reportFileName}. - * E.g., `foo.beta.api.md`. - * The only exception to this is the `complete` variant. - * This variant name will not be contained in the corresponding file name. - * I.e., `foo.api.md`. * - * @defaultValue `['complete']` + * @defaultValue `[ "complete" ]` */ reportVariants?: ApiReportVariant[]; diff --git a/apps/api-extractor/src/schemas/api-extractor-template.json b/apps/api-extractor/src/schemas/api-extractor-template.json index 5af76783896..a2716e5d88b 100644 --- a/apps/api-extractor/src/schemas/api-extractor-template.json +++ b/apps/api-extractor/src/schemas/api-extractor-template.json @@ -78,14 +78,6 @@ */ // "newlineKind": "crlf", - /** - * Set to true when invoking API Extractor's test harness. When `testMode` is true, the `toolVersion` field in the - * .api.json file is assigned an empty string to prevent spurious diffs in output files tracked for tests. - * - * DEFAULT VALUE: "false" - */ - // "testMode": false, - /** * Specifies how API Extractor sorts members of an enum when generating the .api.json file. By default, the output * files will be sorted alphabetically, which is "by-name". To keep the ordering in the source code, specify @@ -95,6 +87,14 @@ */ // "enumMemberOrder": "by-name", + /** + * Set to true when invoking API Extractor's test harness. When `testMode` is true, the `toolVersion` field in the + * .api.json file is assigned an empty string to prevent spurious diffs in output files tracked for tests. + * + * DEFAULT VALUE: "false" + */ + // "testMode": false, + /** * Determines how the TypeScript compiler engine will be invoked by API Extractor. */ @@ -145,15 +145,31 @@ "enabled": true /** - * The filename for the API report files. It will be combined with "reportFolder" or "reportTempFolder" to produce - * a full file path. + * The base filename for the API report files, to be combined with "reportFolder" or "reportTempFolder" + * to produce the full file path. The "reportFileName" should not include any path separators such as + * "\" or "/". The "reportFileName" should not include a file extension, since API Extractor will automatically + * append an appropriate file extension such as ".api.md". If the "reportVariants" setting is used, then the + * file extension includes the variant name, for example "my-report.public.api.md" or "my-report.beta.api.md". + * The "complete" variant always uses the simple extension "my-report.api.md". * - * The file extension should be ".api.md", and the string should not contain a path separator such as "\" or "/". + * Previous versions of API Extractor required "reportFileName" to include the ".api.md" extension explicitly; + * for backwards compatibility, that is still accepted but will be discarded before applying the above rules. * * SUPPORTED TOKENS: , - * DEFAULT VALUE: ".api.md" + * DEFAULT VALUE: "" + */ + // "reportFileName": "", + + /** + * To support different approval requirements for different API levels, multiple "variants" of the API report can + * be generated. The "reportVariants" setting specifies a list of variants to be generated. If omitted, + * by default only the "complete" variant will be generated, which includes all @internal, @alpha, @beta, + * and @public items. Other possible variants are "alpha" (@alpha + @beta + @public), "beta" (@beta + @public), + * and "public" (@public only). + * + * DEFAULT VALUE: [ "complete" ] */ - // "reportFileName": ".api.md", + // "reportVariants": ["public", "beta"], /** * Specifies the folder where the API report file is written. The file name portion is determined by diff --git a/apps/api-extractor/src/schemas/api-extractor.schema.json b/apps/api-extractor/src/schemas/api-extractor.schema.json index 219b337e537..a8ce1970267 100644 --- a/apps/api-extractor/src/schemas/api-extractor.schema.json +++ b/apps/api-extractor/src/schemas/api-extractor.schema.json @@ -31,6 +31,13 @@ } }, + "newlineKind": { + "description": "Specifies what type of newlines API Extractor should use when writing output files. By default, the output files will be written with Windows-style newlines. To use POSIX-style newlines, specify \"lf\" instead. To use the OS's default newline kind, specify \"os\".", + "type": "string", + "enum": ["crlf", "lf", "os"], + "default": "crlf" + }, + "enumMemberOrder": { "description": "Specifies how API Extractor sorts the members of an enum when generating the .api.json doc model. \n 'by-name': sort the items according to the enum member name \n 'preserve': keep the original order that items appear in the source code", "type": "string", @@ -38,6 +45,11 @@ "default": "by-name" }, + "testMode": { + "description": "Set to true invoking API Extractor's test harness. When \"testMode\" is true, the \"toolVersion\" field in the .api.json file is assigned an empty string to prevent spurious diffs in output files tracked for tests.", + "type": "boolean" + }, + "compiler": { "description": "Determines how the TypeScript compiler engine will be invoked by API Extractor.", "type": "object", @@ -68,12 +80,12 @@ }, "reportFileName": { - "description": "The base filename for the API report files. It will be combined with \"reportFolder\" or \"reportTempFolder\" to produce a full file path. It should not contain a file extension, nor a path separator such as \"\\\" or \"/\". The resulting file with have the extension \"api.md\". The \"complete\" report variant uses this base filename directly; other variants insert a name such as \"my-report.alpha.api.md\" or \"my-report.beta.api.md\" for alpha and beta variants.", + "description": "The base filename for the API report files, to be combined with \"reportFolder\" or \"reportTempFolder\" to produce the full file path. The \"reportFileName\" should not include any path separators such as \"\\\" or \"/\". The \"reportFileName\" should not include a file extension, since API Extractor will automatically append an appropriate file extension such as \".api.md\". If the \"reportVariants\" setting is used, then the file extension includes the variant name, for example \"my-report.public.api.md\" or \"my-report.beta.api.md\". The \"complete\" variant always uses the simple extension \"my-report.api.md\".\n\nPrevious versions of API Extractor required \"reportFileName\" to include the \".api.md\" extension explicitly; for backwards compatibility, that is still accepted but will be discarded before applying the above rules.", "type": ["string"] }, "reportVariants": { - "description": "To support different approval requirements for different API levels, multiple variants of the API report can be generated. The \"reportVariants\" setting specifies a list of variants to be generated. If omitted, by default only the \"complete\" variant will be generated, which includes all @alpha, @beta, and @public items. Other possible variants are \"alpha\" (@alpha + @beta + @public), \"beta\" (@beta + @public), and \"public\" (@public only). If you are leveraging API-Extractor's trimmed roll-ups feature, these reports will match the contents of each corresponding roll-up.", + "description": "To support different approval requirements for different API levels, multiple \"variants\" of the API report can be generated. The \"reportVariants\" setting specifies a list of variants to be generated. If omitted, by default only the \"complete\" variant will be generated, which includes all @internal, @alpha, @beta, and @public items. Other possible variants are \"alpha\" (@alpha + @beta + @public), \"beta\" (@beta + @public), and \"public\" (@public only).", "type": "array", "items": { "type": "string", @@ -174,13 +186,6 @@ "additionalProperties": false }, - "newlineKind": { - "description": "Specifies what type of newlines API Extractor should use when writing output files. By default, the output files will be written with Windows-style newlines. To use POSIX-style newlines, specify \"lf\" instead. To use the OS's default newline kind, specify \"os\".", - "type": "string", - "enum": ["crlf", "lf", "os"], - "default": "crlf" - }, - "messages": { "description": "Configures how API Extractor reports error and warning messages produced during analysis.", "type": "object", @@ -199,11 +204,6 @@ } }, "additionalProperties": false - }, - - "testMode": { - "description": "Set to true invoking API Extractor's test harness. When \"testMode\" is true, the \"toolVersion\" field in the .api.json file is assigned an empty string to prevent spurious diffs in output files tracked for tests.", - "type": "boolean" } }, "required": ["mainEntryPointFilePath"], diff --git a/common/changes/@microsoft/api-extractor/octogonz-ae-reportfilename-extension_2024-07-22-22-08.json b/common/changes/@microsoft/api-extractor/octogonz-ae-reportfilename-extension_2024-07-22-22-08.json new file mode 100644 index 00000000000..3e8bbfd758e --- /dev/null +++ b/common/changes/@microsoft/api-extractor/octogonz-ae-reportfilename-extension_2024-07-22-22-08.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@microsoft/api-extractor", + "comment": "Fix an edge case when discarding the file extension from the \"reportFileName\" setting and improve its documentation", + "type": "patch" + } + ], + "packageName": "@microsoft/api-extractor" +} \ No newline at end of file