Skip to content

Commit c0ef923

Browse files
mmalerbakirjs
authored andcommitted
docs: Restructure example build rules (angular#60778)
Restructures the examples build rules so that all examples are exposed through a single file group in adev/src/content/examples. Also adds a separate filegroup in the same location for just the embeddable examples and adds it to the APPLICATION_FILES for the docs app. This uncovered the fact that some of our examples have broken non-compiling code. I've excluded these ones from being embeddable for now, until the breakages can be addressed PR Close angular#60778
1 parent 427bb5a commit c0ef923

File tree

53 files changed

+81
-643
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+81
-643
lines changed

adev/BUILD.bazel

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ APPLICATION_FILES = [
2323
exclude = [
2424
"src/**/*.spec.ts",
2525
],
26-
)
26+
) + [
27+
"//adev/src/content/examples:embeddable",
28+
]
2729

2830
TEST_FILES = APPLICATION_FILES + [
2931
"karma.conf.js",
@@ -40,7 +42,6 @@ APPLICATION_ASSETS = [
4042
"//adev/src/assets/icons",
4143
"//adev/src/assets:api",
4244
"//adev/src/assets:content",
43-
"//adev/src/content/examples/accessibility:example",
4445
]
4546

4647
APPLICATION_DEPS = [

adev/shared-docs/pipeline/_previews.bzl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
load("@build_bazel_rules_nodejs//:providers.bzl", "run_node")
22

3-
def _generate_previews(ctx):
3+
def _generate_previews_impl(ctx):
44
"""Implementation of the previews generator rule"""
55

66
# File declaration of the generated ts file
@@ -13,16 +13,16 @@ def _generate_previews(ctx):
1313
args.add(ctx.attr.example_srcs.label.package)
1414

1515
# Path to the preview map template.
16-
args.add(ctx.file.template_src)
16+
args.add(ctx.file._template_src)
1717

1818
# Path to the ts output file to write to.
1919
args.add(ts_output.path)
2020

21-
ctx.runfiles(files = ctx.files.template_src)
21+
ctx.runfiles(files = ctx.files._template_src)
2222

2323
run_node(
2424
ctx = ctx,
25-
inputs = depset(ctx.files.example_srcs + ctx.files.template_src),
25+
inputs = depset(ctx.files.example_srcs + ctx.files._template_src),
2626
executable = "_generate_previews",
2727
outputs = [ts_output],
2828
arguments = [args],
@@ -34,15 +34,15 @@ def _generate_previews(ctx):
3434

3535
generate_previews = rule(
3636
# Point to the starlark function that will execute for this rule.
37-
implementation = _generate_previews,
37+
implementation = _generate_previews_impl,
3838
doc = """Rule that generates a map of example previews to their component""",
3939

4040
# The attributes that can be set to this rule.
4141
attrs = {
4242
"example_srcs": attr.label(
4343
doc = """Files used for the previews map generation.""",
4444
),
45-
"template_src": attr.label(
45+
"_template_src": attr.label(
4646
doc = """The previews map template file to base the generated file on.""",
4747
default = Label("//adev/shared-docs/pipeline/examples/previews:template"),
4848
allow_single_file = True,

adev/shared-docs/pipeline/examples/previews/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ ts_library(
1212
],
1313
deps = [
1414
"@npm//@types/node",
15+
"@npm//tinyglobby",
1516
"@npm//typescript",
1617
],
1718
)

adev/shared-docs/pipeline/examples/previews/index.ts

Lines changed: 32 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,11 @@
99
import * as fs from 'fs';
1010
import {readFile, writeFile} from 'fs/promises';
1111
import {join, relative} from 'path';
12+
import {glob} from 'tinyglobby';
1213
import ts from 'typescript';
1314

1415
const [examplesDir, templateFilePath, outputFilePath] = process.argv.slice(2);
1516

16-
const TYPESCRIPT_EXTENSION = '.ts';
17-
const SKIP_FILES_WITH_EXTENSIONS = ['.e2e-spec.ts', '.spec.ts', '.po.ts'];
1817
const EXAMPLES_PATH = `../../content/examples`;
1918

2019
interface File {
@@ -29,10 +28,38 @@ interface AnalyzedFiles {
2928

3029
main();
3130

31+
/**
32+
* Creates a map of example path to dynamic component import for loading embedded examples.
33+
*
34+
* For example, given the following inputs:
35+
* examplesDir: 'adev/src/content/examples',
36+
* templateFilePath: 'adev/shared-docs/pipeline/examples/previews/previews.template',
37+
* outputFilePath: 'bazel-out/k8-fastbuild/bin/adev/src/assets/previews/previews.ts'
38+
*
39+
* The script will generate a mapping of all example components under adev/src/content/examples and
40+
* fill them into the given template file, writing the result to the output file.
41+
*
42+
* It will replace the placeholder text `${previewsComponents}` in the template with mappings like:
43+
* ['adev/src/content/examples/accessibility/src/app/app.component.ts']:
44+
* () => import('../../content/examples/accessibility/src/app/app.component').then(c => c.AppComponent),
45+
* ['adev/src/content/examples/accessibility/src/app/progress-bar.component.ts']:
46+
* () => import('../../content/examples/accessibility/src/app/progress-bar.component').then(c => c.ExampleProgressbarComponent),
47+
* ...
48+
*/
3249
async function main() {
33-
const files = await retrieveAllTypescriptFiles(
34-
examplesDir,
35-
(path) => !SKIP_FILES_WITH_EXTENSIONS.some((extensionToSkip) => path.endsWith(extensionToSkip)),
50+
const files = await glob(join(examplesDir, '**/*.ts'), {
51+
ignore: ['**/*.e2e-spec.ts', '**/*.spec.ts', '**/*.po.ts'],
52+
}).then((paths) =>
53+
Promise.all(
54+
paths.map((path) =>
55+
readFile(path, {encoding: 'utf-8'}).then((fileContent) => {
56+
return {
57+
path: relative(examplesDir, path),
58+
content: fileContent,
59+
};
60+
}),
61+
),
62+
),
3663
);
3764

3865
const filesWithComponent = files
@@ -47,43 +74,6 @@ async function main() {
4774
await writeFile(outputFilePath, previewsComponentMap);
4875
}
4976

50-
/** Recursively search the provided directory for all typescript files and asynchronously load them. */
51-
function retrieveAllTypescriptFiles(
52-
baseDir: string,
53-
predicateFn: (path: string) => boolean,
54-
): Promise<File[]> {
55-
const typescriptFiles: Promise<File>[] = [];
56-
57-
const checkFilesInDirectory = (dir: string) => {
58-
const files = fs.readdirSync(dir, {withFileTypes: true});
59-
for (const file of files) {
60-
const fullPathToFile = join(dir, file.name);
61-
const relativeFilePath = relative(baseDir, fullPathToFile);
62-
63-
if (
64-
file.isFile() &&
65-
file.name.endsWith(TYPESCRIPT_EXTENSION) &&
66-
predicateFn(relativeFilePath)
67-
) {
68-
typescriptFiles.push(
69-
readFile(fullPathToFile, {encoding: 'utf-8'}).then((fileContent) => {
70-
return {
71-
path: relativeFilePath,
72-
content: fileContent,
73-
};
74-
}),
75-
);
76-
} else if (file.isDirectory()) {
77-
checkFilesInDirectory(fullPathToFile);
78-
}
79-
}
80-
};
81-
82-
checkFilesInDirectory(baseDir);
83-
84-
return Promise.all(typescriptFiles);
85-
}
86-
8777
/** Returns list of the `Standalone` @Component class names for given file */
8878
function analyzeFile(file: File): string[] {
8979
const componentClassNames: string[] = [];

adev/src/assets/previews/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ load("//adev/shared-docs:index.bzl", "generate_previews")
22

33
generate_previews(
44
name = "previews",
5-
example_srcs = "//adev/src/content/examples",
5+
example_srcs = "//adev/src/content/examples:embeddable",
66
visibility = ["//visibility:public"],
77
)

adev/src/content/best-practices/BUILD.bazel

Lines changed: 1 addition & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -7,70 +7,7 @@ generate_guides(
77
]),
88
data = [
99
"//adev/src/assets/images:components.svg",
10-
"//adev/src/content/examples/accessibility:src/app/app.component.html",
11-
"//adev/src/content/examples/accessibility:src/app/app.component.ts",
12-
"//adev/src/content/examples/accessibility:src/app/progress-bar.component.ts",
13-
"//adev/src/content/examples/dependency-injection:src/app/tree-shaking/service.ts",
14-
"//adev/src/content/examples/styleguide:src/01-01/app/app.component.ts",
15-
"//adev/src/content/examples/styleguide:src/01-01/app/app.module.ts",
16-
"//adev/src/content/examples/styleguide:src/01-01/app/heroes/hero.component.avoid.ts",
17-
"//adev/src/content/examples/styleguide:src/01-01/app/heroes/heroes.component.ts",
18-
"//adev/src/content/examples/styleguide:src/01-01/app/heroes/shared/hero.model.ts",
19-
"//adev/src/content/examples/styleguide:src/01-01/app/heroes/shared/hero.service.ts",
20-
"//adev/src/content/examples/styleguide:src/01-01/app/heroes/shared/mock-heroes.ts",
21-
"//adev/src/content/examples/styleguide:src/01-01/main.ts",
22-
"//adev/src/content/examples/styleguide:src/02-05/main.ts",
23-
"//adev/src/content/examples/styleguide:src/02-07/app/heroes/hero.component.avoid.ts",
24-
"//adev/src/content/examples/styleguide:src/02-07/app/heroes/hero.component.ts",
25-
"//adev/src/content/examples/styleguide:src/02-07/app/users/users.component.avoid.ts",
26-
"//adev/src/content/examples/styleguide:src/02-07/app/users/users.component.ts",
27-
"//adev/src/content/examples/styleguide:src/02-08/app/shared/validate.directive.avoid.ts",
28-
"//adev/src/content/examples/styleguide:src/02-08/app/shared/validate.directive.ts",
29-
"//adev/src/content/examples/styleguide:src/04-08/app/app.module.ts",
30-
"//adev/src/content/examples/styleguide:src/04-10/app/heroes/heroes.component.html",
31-
"//adev/src/content/examples/styleguide:src/04-10/app/heroes/heroes.component.ts",
32-
"//adev/src/content/examples/styleguide:src/04-10/app/shared/filter-text/filter-text.component.ts",
33-
"//adev/src/content/examples/styleguide:src/04-10/app/shared/filter-text/filter-text.service.ts",
34-
"//adev/src/content/examples/styleguide:src/04-10/app/shared/init-caps.pipe.ts",
35-
"//adev/src/content/examples/styleguide:src/04-10/app/shared/shared.module.ts",
36-
"//adev/src/content/examples/styleguide:src/05-02/app/app.component.html",
37-
"//adev/src/content/examples/styleguide:src/05-02/app/heroes/shared/hero-button/hero-button.component.avoid.ts",
38-
"//adev/src/content/examples/styleguide:src/05-02/app/heroes/shared/hero-button/hero-button.component.ts",
39-
"//adev/src/content/examples/styleguide:src/05-03/app/app.component.avoid.html",
40-
"//adev/src/content/examples/styleguide:src/05-03/app/app.component.html",
41-
"//adev/src/content/examples/styleguide:src/05-03/app/heroes/shared/hero-button/hero-button.component.avoid.ts",
42-
"//adev/src/content/examples/styleguide:src/05-03/app/heroes/shared/hero-button/hero-button.component.ts",
43-
"//adev/src/content/examples/styleguide:src/05-04/app/heroes/heroes.component.avoid.ts",
44-
"//adev/src/content/examples/styleguide:src/05-04/app/heroes/heroes.component.css",
45-
"//adev/src/content/examples/styleguide:src/05-04/app/heroes/heroes.component.html",
46-
"//adev/src/content/examples/styleguide:src/05-04/app/heroes/heroes.component.ts",
47-
"//adev/src/content/examples/styleguide:src/05-12/app/heroes/shared/hero-button/hero-button.component.avoid.ts",
48-
"//adev/src/content/examples/styleguide:src/05-12/app/heroes/shared/hero-button/hero-button.component.ts",
49-
"//adev/src/content/examples/styleguide:src/05-13/app/app.component.avoid.html",
50-
"//adev/src/content/examples/styleguide:src/05-13/app/app.component.html",
51-
"//adev/src/content/examples/styleguide:src/05-13/app/heroes/shared/hero-button/hero-button.component.avoid.ts",
52-
"//adev/src/content/examples/styleguide:src/05-13/app/heroes/shared/hero-button/hero-button.component.ts",
53-
"//adev/src/content/examples/styleguide:src/05-13/app/heroes/shared/hero-highlight.directive.ts",
54-
"//adev/src/content/examples/styleguide:src/05-15/app/heroes/hero-list/hero-list.component.avoid.ts",
55-
"//adev/src/content/examples/styleguide:src/05-15/app/heroes/hero-list/hero-list.component.ts",
56-
"//adev/src/content/examples/styleguide:src/05-16/app/app.component.avoid.html",
57-
"//adev/src/content/examples/styleguide:src/05-16/app/app.component.html",
58-
"//adev/src/content/examples/styleguide:src/05-16/app/heroes/hero.component.avoid.ts",
59-
"//adev/src/content/examples/styleguide:src/05-16/app/heroes/hero.component.ts",
60-
"//adev/src/content/examples/styleguide:src/05-17/app/heroes/hero-list/hero-list.component.avoid.ts",
61-
"//adev/src/content/examples/styleguide:src/05-17/app/heroes/hero-list/hero-list.component.ts",
62-
"//adev/src/content/examples/styleguide:src/05-18/app/heroes/hero/hero.component.avoid.ts",
63-
"//adev/src/content/examples/styleguide:src/05-18/app/heroes/hero/hero.component.optional.ts",
64-
"//adev/src/content/examples/styleguide:src/05-18/app/heroes/hero/hero.component.ts",
65-
"//adev/src/content/examples/styleguide:src/06-01/app/app.component.html",
66-
"//adev/src/content/examples/styleguide:src/06-01/app/shared/highlight.directive.ts",
67-
"//adev/src/content/examples/styleguide:src/06-03/app/shared/validator.directive.ts",
68-
"//adev/src/content/examples/styleguide:src/06-03/app/shared/validator2.directive.ts",
69-
"//adev/src/content/examples/styleguide:src/07-01/app/heroes/shared/hero.service.ts",
70-
"//adev/src/content/examples/styleguide:src/07-04/app/heroes/shared/hero-arena.service.avoid.ts",
71-
"//adev/src/content/examples/styleguide:src/07-04/app/heroes/shared/hero-arena.service.ts",
72-
"//adev/src/content/examples/styleguide:src/09-01/app/heroes/shared/hero-button/hero-button.component.avoid.ts",
73-
"//adev/src/content/examples/styleguide:src/09-01/app/heroes/shared/hero-button/hero-button.component.ts",
10+
"//adev/src/content/examples",
7411
],
7512
visibility = ["//adev:__subpackages__"],
7613
)

adev/src/content/ecosystem/service-workers/BUILD.bazel

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ generate_guides(
66
"*.md",
77
]),
88
data = [
9-
"//adev/src/content/examples/service-worker-getting-started:src/app/check-for-update.service.ts",
10-
"//adev/src/content/examples/service-worker-getting-started:src/app/handle-unrecoverable-state.service.ts",
11-
"//adev/src/content/examples/service-worker-getting-started:src/app/log-update.service.ts",
12-
"//adev/src/content/examples/service-worker-getting-started:src/app/prompt-update.service.ts",
9+
"//adev/src/content/examples",
1310
],
1411
visibility = ["//adev:__subpackages__"],
1512
)

adev/src/content/examples/BUILD.bazel

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,27 @@
1+
# All example files.
12
filegroup(
23
name = "examples",
3-
srcs = [
4-
"//adev/src/content/examples/accessibility:ts_files",
5-
],
4+
srcs = glob(["**"]),
5+
visibility = ["//visibility:public"],
6+
)
7+
8+
# Example files that can be embedded as preview components.
9+
filegroup(
10+
name = "embeddable",
11+
srcs = glob(
12+
["*/src/app/**"],
13+
exclude = [
14+
"testing/**", # Can't embed test code
15+
"i18n/**", # @angular/localize/init not available in docs app
16+
"elements/**", # @angular/elements not available in docs app
17+
"service-worker-getting-started/**", # @angular/service-worker not available in docs app
18+
# TODO: The following examples have broken code that does not compile, fix them and remove them from this list.
19+
"ssr/**",
20+
"resolution-modifiers/**",
21+
"reactive-forms/**",
22+
"form-validation/**",
23+
"dependency-injection/**",
24+
],
25+
),
626
visibility = ["//visibility:public"],
727
)

adev/src/content/examples/accessibility/BUILD.bazel

Lines changed: 0 additions & 28 deletions
This file was deleted.

adev/src/content/examples/angular-compiler-options/BUILD.bazel

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)