Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automation: main-next integrate #18762

Merged
merged 5 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,3 @@ labels:
base-branch: "next"
- label: "base: release"
base-branch: "^release/.*"

# PRs from contributors without write access to the repo should be labeled
- label: "community-contribution"
author-can-merge: False
6 changes: 6 additions & 0 deletions common/build/eslint-config-fluid/.mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"recursive": true,
"reporter": "mocha-multi-reporters",
"reporter-options": "configFile=mocha-multi-reporter-config.json",
"timeout": 5000
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"reporterEnabled": "xunit,mocha-json-output-reporter,spec",
"xunitReporterOptions": {
"output": "nyc/junit-report.xml"
},
"mochaJsonOutputReporterReporterOptions": {
"output": "nyc/junit-report.json"
}
}
2 changes: 2 additions & 0 deletions common/build/eslint-config-fluid/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
"concurrently": "^8.2.1",
"eslint": "~8.49.0",
"mocha": "^10.2.0",
"mocha-json-output-reporter": "^2.1.0",
"mocha-multi-reporters": "^1.5.1",
"prettier": "~3.0.3",
"rimraf": "^4.4.1",
"sort-json": "^2.0.1",
Expand Down
30 changes: 28 additions & 2 deletions common/build/eslint-config-fluid/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 1 addition & 6 deletions experimental/dds/tree2/src/domains/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@
* Licensed under the MIT License.
*/

export {
SchemaBuilder,
FactoryObjectNodeSchema,
FactoryObjectNodeSchemaRecursive,
} from "./schemaBuilder";

export { SchemaBuilder } from "./schemaBuilder";
export {
cursorToJsonObject,
jsonArray,
Expand Down
6 changes: 0 additions & 6 deletions experimental/dds/tree2/src/domains/json/jsonDomainSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,14 @@ export const jsonRoot = [() => jsonObject, () => jsonArray, ...jsonPrimitives] a
type _check = requireAssignableTo<typeof jsonRoot, AllowedTypes>;
}

/**
*/
export const jsonObject = builder.mapRecursive(
"object",
TreeFieldSchema.createUnsafe(FieldKinds.optional, jsonRoot),
);

/**
*/
export const jsonArray = builder.fieldNodeRecursive(
"array",
TreeFieldSchema.createUnsafe(FieldKinds.sequence, jsonRoot),
);

/**
*/
export const jsonSchema = builder.intoLibrary();
3 changes: 2 additions & 1 deletion experimental/dds/tree2/src/domains/schemaBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ export type FactoryObjectNodeSchemaRecursive<
* TODO: Maybe rename to DefaultSchemaBuilder1 because of the versioning implications above.
* Same applies to SchemaBuilder.
* TODO: figure out a way to link `leaf` above without breaking API Extractor.
* @sealed @alpha
* @sealed
* @deprecated Users of this class should either use {@link SchemaBuilderBase} and explicitly work with {@link TreeFieldSchema}, or use SchemaFactory and work at its higher level of abstraction.
*/
export class SchemaBuilder<
TScope extends string = string,
Expand Down
18 changes: 7 additions & 11 deletions experimental/dds/tree2/src/domains/testRecursiveDomain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,22 @@
* Currently we do not have tooling in place to test this in our test suite, and exporting these types here is a temporary crutch to aid in diagnosing this issue.
*/

import { FieldKinds, TreeFieldSchema } from "../feature-libraries";
import { AllowedTypes, FieldKinds, SchemaBuilderBase, TreeFieldSchema } from "../feature-libraries";
import { areSafelyAssignable, isAny, requireFalse, requireTrue } from "../util";
import { leaf } from "./leafDomain";
import { SchemaBuilder } from "./schemaBuilder";

const builder = new SchemaBuilder({ scope: "Test Recursive Domain" });
const builder = new SchemaBuilderBase(FieldKinds.optional, { scope: "Test Recursive Domain" });

/**
*/
export const recursiveObject = builder.objectRecursive("object", {
recursive: TreeFieldSchema.createUnsafe(FieldKinds.optional, [() => recursiveObject]),
number: leaf.number,
});

function fixRecursiveReference<T extends AllowedTypes>(...types: T): void {}

const recursiveReference = () => recursiveObject2;
builder.fixRecursiveReference(recursiveReference);
fixRecursiveReference(recursiveReference);

/**
*/
export const recursiveObject2 = builder.object("object2", {
recursive: TreeFieldSchema.create(FieldKinds.optional, [recursiveReference]),
number: leaf.number,
Expand All @@ -41,12 +38,11 @@ type _1 = requireTrue<
ReturnType<(typeof recursiveObject2.objectNodeFieldsObject.recursive.allowedTypes)[0]>
>
>;
/**
*/

export const library = builder.intoLibrary();

{
const b = new SchemaBuilder({ scope: "Test Recursive Domain" });
const b = new SchemaBuilderBase(FieldKinds.optional, { scope: "Test Recursive Domain" });
const node = b.objectRecursive("object", {
child: TreeFieldSchema.createUnsafe(FieldKinds.optional, [() => node]),
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ export interface DocumentationSuiteOptions {
hierarchyBoundaries?: HierarchyBoundaries;
includeBreadcrumb?: boolean;
includeTopLevelDocumentHeading?: boolean;
minimumReleaseLevel?: Omit<ReleaseTag, ReleaseTag.None>;
skipPackage?: (apiPackage: ApiPackage) => boolean;
}

Expand Down
2 changes: 1 addition & 1 deletion tools/api-markdown-documenter/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fluid-tools/api-markdown-documenter",
"version": "0.11.1",
"version": "0.11.2",
"description": "Processes .api.json files generated by API-Extractor and generates Markdown documentation from them.",
"homepage": "https://fluidframework.com",
"repository": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
*/
import * as Path from "node:path";

import { ApiItem, ApiItemKind } from "@microsoft/api-extractor-model";
import { type ApiItem, ApiItemKind, ReleaseTag } from "@microsoft/api-extractor-model";

import { Heading } from "../Heading";
import { Link } from "../Link";
import { getQualifiedApiItemName } from "../utilities";
import { getQualifiedApiItemName, getReleaseTag } from "../utilities";
import {
ApiItemTransformationConfiguration,
DocumentBoundaries,
HierarchyBoundaries,
type ApiItemTransformationConfiguration,
type DocumentBoundaries,
type HierarchyBoundaries,
} from "./configuration";

/**
Expand Down Expand Up @@ -459,3 +459,65 @@ function doesItemGenerateHierarchy(
): boolean {
return doesItemKindGenerateHierarchy(apiItem.kind, hierarchyBoundaries);
}

/**
* Determines whether or not the specified API item should have documentation generated for it.
* This is determined based on its release tag (or inherited release scope) compared to
* {@link ApiItemTransformationConfiguration.minimumReleaseLevel}.
*
* @remarks
*
* If an item does not have its own release tag, it will inherit its release scope from its nearest ancestor.
*
* Items without an associated release tag (directly or in their ancestry) will always be included as a precaution.
*
* @param apiItem - The API item being queried.
* @param config - See {@link ApiItemTransformationConfiguration}.
*
* @example Hierarchical inheritance
*
* Items with tagged ancestors inherit their release scope when one is not specified.
* This includes class/interface members...
*
* ```typescript
* // @public
* export interface Foo {
* // `@public` inherited from the interface
* bar: string;
* }
* ```
*
* This also includes scopes like namespaces, which can add further hierarchy...
*
* ```typescript
* // @public
* export namespace Foo {
* // `@public` inherited from the namespace
* export interface Bar {
* // `@public` inherited from the namespace
* baz: string;
* }
* }
* ```
*/
export function shouldItemBeIncluded(
apiItem: ApiItem,
config: Required<ApiItemTransformationConfiguration>,
): boolean {
const releaseTag = getReleaseTag(apiItem);
if (releaseTag === undefined || releaseTag === ReleaseTag.None) {
// If the item does not have a release tag, then it inherits the release scope of its ancestry.
const parent = getFilteredParent(apiItem);
if (parent === undefined) {
// If we encounter an item with no release tag in its ancestry, we can't make a determination as to whether
// or not it is intended to be included in the generated documentation suite.
// To be safe, log a warning but return true.
config.logger.warning("Encountered an API item with no release tag in ancestry.");
return true;
}

return shouldItemBeIncluded(parent, config);
}

return releaseTag >= (config.minimumReleaseLevel as ReleaseTag);
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
} from "@microsoft/api-extractor-model";

import { DocumentNode, SectionNode } from "../documentation-domain";
import { doesItemRequireOwnDocument } from "./ApiItemTransformUtilities";
import { doesItemRequireOwnDocument, shouldItemBeIncluded } from "./ApiItemTransformUtilities";
import { createDocument } from "./Utilities";
import { ApiItemTransformationConfiguration } from "./configuration";
import { createBreadcrumbParagraph, wrapInSection } from "./helpers";
Expand Down Expand Up @@ -53,7 +53,7 @@ export function apiItemToDocument(
config: Required<ApiItemTransformationConfiguration>,
): DocumentNode {
if (apiItem.kind === ApiItemKind.None) {
throw new Error(`Encountered API item with a kind of "None".`);
throw new Error(`Encountered API item "${apiItem.displayName}" with a kind of "None".`);
}

if (
Expand All @@ -64,6 +64,12 @@ export function apiItemToDocument(
throw new Error(`Provided API item kind must be handled specially: "${apiItem.kind}".`);
}

if (!shouldItemBeIncluded(apiItem, config)) {
throw new Error(
`Provided API item "${apiItem.displayName}" should not be included in documentation suite per configuration. Cannot generate a document for it.`,
);
}

if (!doesItemRequireOwnDocument(apiItem, config.documentBoundaries)) {
throw new Error(
`"renderApiDocument" called for an API item kind that is not intended to be rendered to its own document. Provided item kind: "${apiItem.kind}".`,
Expand Down Expand Up @@ -105,7 +111,7 @@ export function apiItemToSections(
config: Required<ApiItemTransformationConfiguration>,
): SectionNode[] {
if (apiItem.kind === ApiItemKind.None) {
throw new Error(`Encountered API item with a kind of "None".`);
throw new Error(`Encountered API item "${apiItem.displayName}" with a kind of "None".`);
}

if (
Expand All @@ -116,6 +122,12 @@ export function apiItemToSections(
throw new Error(`Provided API item kind must be handled specially: "${apiItem.kind}".`);
}

if (!shouldItemBeIncluded(apiItem, config)) {
// If a parent item has requested we render contents for an item not desired by the configuration,
// return an empty set of sections.
return [];
}

const logger = config.logger;

logger.verbose(`Rendering section for ${apiItem.displayName}...`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
ApiItemTransformationConfiguration,
getApiItemTransformationConfigurationWithDefaults,
} from "./configuration";
import { doesItemRequireOwnDocument } from "./ApiItemTransformUtilities";
import { doesItemRequireOwnDocument, shouldItemBeIncluded } from "./ApiItemTransformUtilities";
import { createBreadcrumbParagraph, createEntryPointList, wrapInSection } from "./helpers";
import { apiItemToDocument, apiItemToSections } from "./TransformApiItem";

Expand Down Expand Up @@ -140,7 +140,10 @@ function getDocumentItems(

const result: ApiItem[] = [];
for (const childItem of apiItem.members) {
if (doesItemRequireOwnDocument(childItem, documentBoundaries)) {
if (
shouldItemBeIncluded(childItem, config) &&
doesItemRequireOwnDocument(childItem, documentBoundaries)
) {
result.push(childItem);
}
result.push(...getDocumentItems(childItem, config));
Expand Down
Loading
Loading