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

ci: add ts api guardian #12010

Merged
merged 11 commits into from
Nov 30, 2018
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ jobs:
steps:
- attach_workspace: *attach_options
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
- run: bazel test //packages/...
- run: bazel test ...

snapshot_publish:
<<: *defaults
Expand Down
23 changes: 21 additions & 2 deletions WORKSPACE
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
workspace(name = "angular_cli")

# This is required by Angular Workspace
http_archive(
name = "bazel_skylib",
url = "https://github.com/bazelbuild/bazel-skylib/archive/0.5.0.zip",
strip_prefix = "bazel-skylib-0.5.0",
sha256 = "ca4e3b8e4da9266c3a9101c8f4704fe2e20eb5625b2a6a7d2d7d45e3dd4efffd",
)

# We get Buildifier from here.
http_archive(
name = "com_github_bazelbuild_buildtools",
Expand All @@ -11,8 +19,8 @@ http_archive(
# Load the TypeScript rules, its dependencies, and setup the workspace.
http_archive(
name = "build_bazel_rules_typescript",
url = "https://github.com/bazelbuild/rules_typescript/archive/0.20.3.zip",
strip_prefix = "rules_typescript-0.20.3",
url = "https://github.com/bazelbuild/rules_typescript/archive/8ea1a55cf5cf8be84ddfeefc0940769b80da792f.zip",
strip_prefix = "rules_typescript-8ea1a55cf5cf8be84ddfeefc0940769b80da792f",
)

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

# TS API Guardian resides in Angular
http_archive(
name = "angular",
url = "https://github.com/angular/angular/archive/7.1.0-rc.0.zip",
strip_prefix = "angular-7.1.0-rc.0",
sha256 = "dbf3ae2d60b5384715bc002c695be0141f8c9219396ac1edbdc7023bd400c8a1",
)

load("@angular//:index.bzl", "ng_setup_workspace")
ng_setup_workspace()

load("@build_bazel_rules_typescript//:defs.bzl", "ts_setup_workspace")
ts_setup_workspace()

Expand Down
50 changes: 50 additions & 0 deletions etc/api/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
load("@angular//tools/ts-api-guardian:index.bzl", "ts_api_guardian_test")

[ts_api_guardian_test(
name = "%s_%s_%sapi" % (
bundle[0],
bundle[1],
bundle[2].replace("src/", "").replace("index", "").replace("_golden-api", "").replace("/", "_"),
),
actual = "angular_cli/packages/%s/%s/npm_package/%s.d.ts" % (
bundle[0],
bundle[1],
bundle[2],
),
data = glob([
"%s/%s/**/*.d.ts" % (
bundle[0],
bundle[1],
),
]) + [
"//packages/%s/%s:npm_package" % (
bundle[0],
bundle[1],
),
],
golden = "angular_cli/etc/api/%s/%s/%s.d.ts" % (
bundle[0],
bundle[1],
bundle[2],
),
# We don't want to analyse these exports nor add them to the golden files
# in most cases it's because Ts API Guardian doesn't support Symbol Aliases.
strip_export_pattern = [
# @angular-devkit/schematics
"^workflow$",
"^formats$",
# @angular-devkit/build-optimizer
"^buildOptimizerLoader$",
],
allow_module_identifiers = [
"fs",
"ts",
"ajv",
"Symbol",
"webpack",
],
# At the moment using this will ignore a big change
use_angular_tag_rules = False,
) for bundle in [b[:-len(".d.ts")].split("/", 2) for b in glob(
["**/*.d.ts"],
)]]
102 changes: 102 additions & 0 deletions etc/api/angular_devkit/architect/src/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
export declare class Architect {
alan-agius4 marked this conversation as resolved.
Show resolved Hide resolved
constructor(_workspace: experimental.workspace.Workspace);
getBuilder<OptionsT>(builderDescription: BuilderDescription, context: BuilderContext): Builder<OptionsT>;
getBuilderConfiguration<OptionsT>(targetSpec: TargetSpecifier): BuilderConfiguration<OptionsT>;
getBuilderDescription<OptionsT>(builderConfig: BuilderConfiguration<OptionsT>): Observable<BuilderDescription>;
listProjectTargets(projectName: string): string[];
loadArchitect(): Observable<this>;
run<OptionsT>(builderConfig: BuilderConfiguration<OptionsT>, partialContext?: Partial<BuilderContext>): Observable<BuildEvent>;
validateBuilderOptions<OptionsT>(builderConfig: BuilderConfiguration<OptionsT>, builderDescription: BuilderDescription): Observable<BuilderConfiguration<OptionsT>>;
}

export declare class ArchitectNotYetLoadedException extends BaseException {
constructor();
}

export interface Builder<OptionsT> {
run(builderConfig: BuilderConfiguration<Partial<OptionsT>>): Observable<BuildEvent>;
}

export declare class BuilderCannotBeResolvedException extends BaseException {
constructor(builder: string);
}

export interface BuilderConfiguration<OptionsT = {}> {
builder: string;
options: OptionsT;
projectType: string;
root: Path;
sourceRoot?: Path;
}

export interface BuilderConstructor<OptionsT> {
new (context: BuilderContext): Builder<OptionsT>;
}

export interface BuilderContext {
architect: Architect;
host: virtualFs.Host<{}>;
logger: logging.Logger;
workspace: experimental.workspace.Workspace;
}

export interface BuilderDescription {
description: string;
name: string;
schema: JsonObject;
}

export declare class BuilderNotFoundException extends BaseException {
constructor(builder: string);
}

export interface BuilderPaths {
class: Path;
description: string;
schema: Path;
}

export interface BuilderPathsMap {
builders: {
[k: string]: BuilderPaths;
};
}

export interface BuildEvent {
success: boolean;
}

export declare class ConfigurationNotFoundException extends BaseException {
constructor(projectName: string, configurationName: string);
}

export declare class ProjectNotFoundException extends BaseException {
constructor(projectName: string);
}

export interface Target<T = JsonObject> {
builder: string;
configurations?: {
[k: string]: TargetConfiguration<T>;
};
options: TargetOptions<T>;
}

export declare type TargetConfiguration<T = JsonObject> = Partial<T>;

export interface TargetMap {
[k: string]: Target;
}

export declare class TargetNotFoundException extends BaseException {
constructor(projectName: string, targetName: string);
}

export declare type TargetOptions<T = JsonObject> = T;

export interface TargetSpecifier<OptionsT = {}> {
configuration?: string;
overrides?: Partial<OptionsT>;
project: string;
target: string;
}
28 changes: 28 additions & 0 deletions etc/api/angular_devkit/architect/testing/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export declare const DefaultTimeout = 45000;

export declare function request(url: string, headers?: {}): Promise<string>;

export declare function runTargetSpec(host: TestProjectHost, targetSpec: TargetSpecifier, overrides?: {}, timeout?: number, logger?: logging.Logger): Observable<BuildEvent>;

export declare class TestLogger extends logging.Logger {
constructor(name: string, parent?: logging.Logger | null);
clear(): void;
includes(message: string): boolean;
test(re: RegExp): boolean;
}

export declare class TestProjectHost extends NodeJsSyncHost {
protected _templateRoot: Path;
constructor(_templateRoot: Path);
appendToFile(path: string, str: string): void;
copyFile(from: string, to: string): void;
fileMatchExists(dir: string, regex: RegExp): PathFragment | undefined;
initialize(): Observable<void>;
replaceInFile(path: string, match: RegExp | string, replacement: string): void;
restore(): Observable<void>;
root(): Path;
scopedSync(): virtualFs.SyncDelegateHost<Stats>;
writeMultipleFiles(files: {
[path: string]: string | ArrayBufferLike | Buffer;
}): void;
}
91 changes: 91 additions & 0 deletions etc/api/angular_devkit/benchmark/src/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
export interface AggregatedMetric extends Metric {
componentValues: number[];
}

export interface AggregatedProcessStats {
cpu: number;
ctime: number;
elapsed: number;
memory: number;
pid: number;
ppid: number;
processes: number;
timestamp: number;
}

export declare const aggregateMetricGroups: (g1: MetricGroup, g2: MetricGroup) => MetricGroup;

export declare const aggregateMetrics: (m1: Metric | AggregatedMetric, m2: Metric | AggregatedMetric) => AggregatedMetric;

export declare type BenchmarkReporter = (command: Command, groups: MetricGroup[]) => void;

export declare type Capture = (process: MonitoredProcess) => Observable<MetricGroup>;

export declare class Command {
args: string[];
cmd: string;
cwd: string;
expectedExitCode: number;
constructor(cmd: string, args?: string[], cwd?: string, expectedExitCode?: number);
toString(): string;
}

export declare const cumulativeMovingAverage: (acc: number, val: number, accSize: number) => number;

export declare const defaultReporter: (logger: logging.Logger) => BenchmarkReporter;

export declare const defaultStatsCapture: Capture;

export declare class LocalMonitoredProcess implements MonitoredProcess {
stats$: Observable<AggregatedProcessStats>;
stderr$: Observable<Buffer>;
stdout$: Observable<Buffer>;
constructor(command: Command);
run(): Observable<number>;
}

export declare function main({ args, stdout, stderr, }: MainOptions): Promise<0 | 1>;

export interface MainOptions {
args: string[];
stderr?: ProcessOutput;
stdout?: ProcessOutput;
}

export declare const max: (v1: number, v2: number) => number;

export declare class MaximumRetriesExceeded extends BaseException {
constructor(retries: number);
}

export interface Metric {
componentValues?: number[];
name: string;
unit: string;
value: number;
}

export interface MetricGroup {
metrics: (Metric | AggregatedMetric)[];
name: string;
}

export interface MonitoredProcess {
stats$: Observable<AggregatedProcessStats>;
stderr$: Observable<Buffer>;
stdout$: Observable<Buffer>;
run(): Observable<number>;
toString(): string;
}

export declare function runBenchmark({ command, captures, reporters, iterations, retries, logger, }: RunBenchmarkOptions): Observable<MetricGroup[]>;

export interface RunBenchmarkOptions {
captures: Capture[];
command: Command;
expectedExitCode?: number;
iterations?: number;
logger?: logging.Logger;
reporters: BenchmarkReporter[];
retries?: number;
}
23 changes: 23 additions & 0 deletions etc/api/angular_devkit/build_optimizer/src/_golden-api.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export declare function buildOptimizer(options: BuildOptimizerOptions): TransformJavascriptOutput;

export default function buildOptimizerLoader(this: webpack.loader.LoaderContext, content: string, previousSourceMap: RawSourceMap): void;

export declare function getFoldFileTransformer(program: ts.Program): ts.TransformerFactory<ts.SourceFile>;

export declare function getImportTslibTransformer(): ts.TransformerFactory<ts.SourceFile>;

export declare function getPrefixClassesTransformer(): ts.TransformerFactory<ts.SourceFile>;

export declare function getPrefixFunctionsTransformer(): ts.TransformerFactory<ts.SourceFile>;

export declare function getScrubFileTransformer(program: ts.Program): ts.TransformerFactory<ts.SourceFile>;

export declare function getWrapEnumsTransformer(): ts.TransformerFactory<ts.SourceFile>;

export declare function testImportTslib(content: string): boolean;

export declare function testPrefixClasses(content: string): boolean;

export declare function testScrubFile(content: string): boolean;

export declare function transformJavascript(options: TransformJavascriptOptions): TransformJavascriptOutput;