Skip to content

Commit 717b02f

Browse files
alan-agius4vikerman
authored andcommitted
ci: add ts api guardian (#12010)
* refactor: fix `import` and `export` paths to work with classic resolution `ts-api-guardian` only support classic module resolution which means that we need to specify `index` so that the resolution works. * build: add `npm_package` to packages * build: add ts-api-guardian to repo * test: add api golden files * refactor: use proper namespace instead of alias export * refactor: use proper namspace einstead of alias export * build: add `_golden_api` files At the moment ts api guardian doesn't support aliased symbols as namespaces, this is a workaround to still have namespaced symbols in the final golden file. * build: update angular archive for workspace * test: fix reference to `TestHost` to use namespace * refactor: create `fs` namespace instead of aliased export * test: update api golden file for `@angular-devkit/core/node`
1 parent 508d4df commit 717b02f

File tree

39 files changed

+2698
-215
lines changed

39 files changed

+2698
-215
lines changed

.circleci/config.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ jobs:
126126
steps:
127127
- attach_workspace: *attach_options
128128
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
129-
- run: bazel test //packages/...
129+
- run: bazel test ...
130130

131131
snapshot_publish:
132132
<<: *defaults

WORKSPACE

+21-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
workspace(name = "angular_cli")
22

3+
# This is required by Angular Workspace
4+
http_archive(
5+
name = "bazel_skylib",
6+
url = "https://github.com/bazelbuild/bazel-skylib/archive/0.5.0.zip",
7+
strip_prefix = "bazel-skylib-0.5.0",
8+
sha256 = "ca4e3b8e4da9266c3a9101c8f4704fe2e20eb5625b2a6a7d2d7d45e3dd4efffd",
9+
)
10+
311
# We get Buildifier from here.
412
http_archive(
513
name = "com_github_bazelbuild_buildtools",
@@ -11,8 +19,8 @@ http_archive(
1119
# Load the TypeScript rules, its dependencies, and setup the workspace.
1220
http_archive(
1321
name = "build_bazel_rules_typescript",
14-
url = "https://github.com/bazelbuild/rules_typescript/archive/0.20.3.zip",
15-
strip_prefix = "rules_typescript-0.20.3",
22+
url = "https://github.com/bazelbuild/rules_typescript/archive/8ea1a55cf5cf8be84ddfeefc0940769b80da792f.zip",
23+
strip_prefix = "rules_typescript-8ea1a55cf5cf8be84ddfeefc0940769b80da792f",
1624
)
1725

1826
load("@build_bazel_rules_typescript//:package.bzl", "rules_typescript_dependencies")
@@ -26,6 +34,17 @@ load("@io_bazel_rules_go//go:def.bzl", "go_register_toolchains", "go_rules_depen
2634
go_rules_dependencies()
2735
go_register_toolchains()
2836

37+
# TS API Guardian resides in Angular
38+
http_archive(
39+
name = "angular",
40+
url = "https://github.com/angular/angular/archive/7.1.0-rc.0.zip",
41+
strip_prefix = "angular-7.1.0-rc.0",
42+
sha256 = "dbf3ae2d60b5384715bc002c695be0141f8c9219396ac1edbdc7023bd400c8a1",
43+
)
44+
45+
load("@angular//:index.bzl", "ng_setup_workspace")
46+
ng_setup_workspace()
47+
2948
load("@build_bazel_rules_typescript//:defs.bzl", "ts_setup_workspace")
3049
ts_setup_workspace()
3150

etc/api/BUILD

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
load("@angular//tools/ts-api-guardian:index.bzl", "ts_api_guardian_test")
2+
3+
[ts_api_guardian_test(
4+
name = "%s_%s_%sapi" % (
5+
bundle[0],
6+
bundle[1],
7+
bundle[2].replace("src/", "").replace("index", "").replace("_golden-api", "").replace("/", "_"),
8+
),
9+
actual = "angular_cli/packages/%s/%s/npm_package/%s.d.ts" % (
10+
bundle[0],
11+
bundle[1],
12+
bundle[2],
13+
),
14+
data = glob([
15+
"%s/%s/**/*.d.ts" % (
16+
bundle[0],
17+
bundle[1],
18+
),
19+
]) + [
20+
"//packages/%s/%s:npm_package" % (
21+
bundle[0],
22+
bundle[1],
23+
),
24+
],
25+
golden = "angular_cli/etc/api/%s/%s/%s.d.ts" % (
26+
bundle[0],
27+
bundle[1],
28+
bundle[2],
29+
),
30+
# We don't want to analyse these exports nor add them to the golden files
31+
# in most cases it's because Ts API Guardian doesn't support Symbol Aliases.
32+
strip_export_pattern = [
33+
# @angular-devkit/schematics
34+
"^workflow$",
35+
"^formats$",
36+
# @angular-devkit/build-optimizer
37+
"^buildOptimizerLoader$",
38+
],
39+
allow_module_identifiers = [
40+
"fs",
41+
"ts",
42+
"ajv",
43+
"Symbol",
44+
"webpack",
45+
],
46+
# At the moment using this will ignore a big change
47+
use_angular_tag_rules = False,
48+
) for bundle in [b[:-len(".d.ts")].split("/", 2) for b in glob(
49+
["**/*.d.ts"],
50+
)]]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
export declare class Architect {
2+
constructor(_workspace: experimental.workspace.Workspace);
3+
getBuilder<OptionsT>(builderDescription: BuilderDescription, context: BuilderContext): Builder<OptionsT>;
4+
getBuilderConfiguration<OptionsT>(targetSpec: TargetSpecifier): BuilderConfiguration<OptionsT>;
5+
getBuilderDescription<OptionsT>(builderConfig: BuilderConfiguration<OptionsT>): Observable<BuilderDescription>;
6+
listProjectTargets(projectName: string): string[];
7+
loadArchitect(): Observable<this>;
8+
run<OptionsT>(builderConfig: BuilderConfiguration<OptionsT>, partialContext?: Partial<BuilderContext>): Observable<BuildEvent>;
9+
validateBuilderOptions<OptionsT>(builderConfig: BuilderConfiguration<OptionsT>, builderDescription: BuilderDescription): Observable<BuilderConfiguration<OptionsT>>;
10+
}
11+
12+
export declare class ArchitectNotYetLoadedException extends BaseException {
13+
constructor();
14+
}
15+
16+
export interface Builder<OptionsT> {
17+
run(builderConfig: BuilderConfiguration<Partial<OptionsT>>): Observable<BuildEvent>;
18+
}
19+
20+
export declare class BuilderCannotBeResolvedException extends BaseException {
21+
constructor(builder: string);
22+
}
23+
24+
export interface BuilderConfiguration<OptionsT = {}> {
25+
builder: string;
26+
options: OptionsT;
27+
projectType: string;
28+
root: Path;
29+
sourceRoot?: Path;
30+
}
31+
32+
export interface BuilderConstructor<OptionsT> {
33+
new (context: BuilderContext): Builder<OptionsT>;
34+
}
35+
36+
export interface BuilderContext {
37+
architect: Architect;
38+
host: virtualFs.Host<{}>;
39+
logger: logging.Logger;
40+
workspace: experimental.workspace.Workspace;
41+
}
42+
43+
export interface BuilderDescription {
44+
description: string;
45+
name: string;
46+
schema: JsonObject;
47+
}
48+
49+
export declare class BuilderNotFoundException extends BaseException {
50+
constructor(builder: string);
51+
}
52+
53+
export interface BuilderPaths {
54+
class: Path;
55+
description: string;
56+
schema: Path;
57+
}
58+
59+
export interface BuilderPathsMap {
60+
builders: {
61+
[k: string]: BuilderPaths;
62+
};
63+
}
64+
65+
export interface BuildEvent {
66+
success: boolean;
67+
}
68+
69+
export declare class ConfigurationNotFoundException extends BaseException {
70+
constructor(projectName: string, configurationName: string);
71+
}
72+
73+
export declare class ProjectNotFoundException extends BaseException {
74+
constructor(projectName: string);
75+
}
76+
77+
export interface Target<T = JsonObject> {
78+
builder: string;
79+
configurations?: {
80+
[k: string]: TargetConfiguration<T>;
81+
};
82+
options: TargetOptions<T>;
83+
}
84+
85+
export declare type TargetConfiguration<T = JsonObject> = Partial<T>;
86+
87+
export interface TargetMap {
88+
[k: string]: Target;
89+
}
90+
91+
export declare class TargetNotFoundException extends BaseException {
92+
constructor(projectName: string, targetName: string);
93+
}
94+
95+
export declare type TargetOptions<T = JsonObject> = T;
96+
97+
export interface TargetSpecifier<OptionsT = {}> {
98+
configuration?: string;
99+
overrides?: Partial<OptionsT>;
100+
project: string;
101+
target: string;
102+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
export declare const DefaultTimeout = 45000;
2+
3+
export declare function request(url: string, headers?: {}): Promise<string>;
4+
5+
export declare function runTargetSpec(host: TestProjectHost, targetSpec: TargetSpecifier, overrides?: {}, timeout?: number, logger?: logging.Logger): Observable<BuildEvent>;
6+
7+
export declare class TestLogger extends logging.Logger {
8+
constructor(name: string, parent?: logging.Logger | null);
9+
clear(): void;
10+
includes(message: string): boolean;
11+
test(re: RegExp): boolean;
12+
}
13+
14+
export declare class TestProjectHost extends NodeJsSyncHost {
15+
protected _templateRoot: Path;
16+
constructor(_templateRoot: Path);
17+
appendToFile(path: string, str: string): void;
18+
copyFile(from: string, to: string): void;
19+
fileMatchExists(dir: string, regex: RegExp): PathFragment | undefined;
20+
initialize(): Observable<void>;
21+
replaceInFile(path: string, match: RegExp | string, replacement: string): void;
22+
restore(): Observable<void>;
23+
root(): Path;
24+
scopedSync(): virtualFs.SyncDelegateHost<Stats>;
25+
writeMultipleFiles(files: {
26+
[path: string]: string | ArrayBufferLike | Buffer;
27+
}): void;
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
export interface AggregatedMetric extends Metric {
2+
componentValues: number[];
3+
}
4+
5+
export interface AggregatedProcessStats {
6+
cpu: number;
7+
ctime: number;
8+
elapsed: number;
9+
memory: number;
10+
pid: number;
11+
ppid: number;
12+
processes: number;
13+
timestamp: number;
14+
}
15+
16+
export declare const aggregateMetricGroups: (g1: MetricGroup, g2: MetricGroup) => MetricGroup;
17+
18+
export declare const aggregateMetrics: (m1: Metric | AggregatedMetric, m2: Metric | AggregatedMetric) => AggregatedMetric;
19+
20+
export declare type BenchmarkReporter = (command: Command, groups: MetricGroup[]) => void;
21+
22+
export declare type Capture = (process: MonitoredProcess) => Observable<MetricGroup>;
23+
24+
export declare class Command {
25+
args: string[];
26+
cmd: string;
27+
cwd: string;
28+
expectedExitCode: number;
29+
constructor(cmd: string, args?: string[], cwd?: string, expectedExitCode?: number);
30+
toString(): string;
31+
}
32+
33+
export declare const cumulativeMovingAverage: (acc: number, val: number, accSize: number) => number;
34+
35+
export declare const defaultReporter: (logger: logging.Logger) => BenchmarkReporter;
36+
37+
export declare const defaultStatsCapture: Capture;
38+
39+
export declare class LocalMonitoredProcess implements MonitoredProcess {
40+
stats$: Observable<AggregatedProcessStats>;
41+
stderr$: Observable<Buffer>;
42+
stdout$: Observable<Buffer>;
43+
constructor(command: Command);
44+
run(): Observable<number>;
45+
}
46+
47+
export declare function main({ args, stdout, stderr, }: MainOptions): Promise<0 | 1>;
48+
49+
export interface MainOptions {
50+
args: string[];
51+
stderr?: ProcessOutput;
52+
stdout?: ProcessOutput;
53+
}
54+
55+
export declare const max: (v1: number, v2: number) => number;
56+
57+
export declare class MaximumRetriesExceeded extends BaseException {
58+
constructor(retries: number);
59+
}
60+
61+
export interface Metric {
62+
componentValues?: number[];
63+
name: string;
64+
unit: string;
65+
value: number;
66+
}
67+
68+
export interface MetricGroup {
69+
metrics: (Metric | AggregatedMetric)[];
70+
name: string;
71+
}
72+
73+
export interface MonitoredProcess {
74+
stats$: Observable<AggregatedProcessStats>;
75+
stderr$: Observable<Buffer>;
76+
stdout$: Observable<Buffer>;
77+
run(): Observable<number>;
78+
toString(): string;
79+
}
80+
81+
export declare function runBenchmark({ command, captures, reporters, iterations, retries, logger, }: RunBenchmarkOptions): Observable<MetricGroup[]>;
82+
83+
export interface RunBenchmarkOptions {
84+
captures: Capture[];
85+
command: Command;
86+
expectedExitCode?: number;
87+
iterations?: number;
88+
logger?: logging.Logger;
89+
reporters: BenchmarkReporter[];
90+
retries?: number;
91+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
export declare function buildOptimizer(options: BuildOptimizerOptions): TransformJavascriptOutput;
2+
3+
export default function buildOptimizerLoader(this: webpack.loader.LoaderContext, content: string, previousSourceMap: RawSourceMap): void;
4+
5+
export declare function getFoldFileTransformer(program: ts.Program): ts.TransformerFactory<ts.SourceFile>;
6+
7+
export declare function getImportTslibTransformer(): ts.TransformerFactory<ts.SourceFile>;
8+
9+
export declare function getPrefixClassesTransformer(): ts.TransformerFactory<ts.SourceFile>;
10+
11+
export declare function getPrefixFunctionsTransformer(): ts.TransformerFactory<ts.SourceFile>;
12+
13+
export declare function getScrubFileTransformer(program: ts.Program): ts.TransformerFactory<ts.SourceFile>;
14+
15+
export declare function getWrapEnumsTransformer(): ts.TransformerFactory<ts.SourceFile>;
16+
17+
export declare function testImportTslib(content: string): boolean;
18+
19+
export declare function testPrefixClasses(content: string): boolean;
20+
21+
export declare function testScrubFile(content: string): boolean;
22+
23+
export declare function transformJavascript(options: TransformJavascriptOptions): TransformJavascriptOutput;

0 commit comments

Comments
 (0)