mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-15 10:11:50 +08:00
ci: disable bazel in devkit-admin build
Replace the build step with a custom JSON schema output parallel to bazel.
This commit is contained in:
parent
30b0cbda0d
commit
c63b4d8d2b
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,6 +2,7 @@
|
|||||||
bazel-*
|
bazel-*
|
||||||
test-project-host-*
|
test-project-host-*
|
||||||
dist/
|
dist/
|
||||||
|
dist-schema/
|
||||||
|
|
||||||
# IDEs
|
# IDEs
|
||||||
.idea/
|
.idea/
|
||||||
|
@ -34,7 +34,9 @@ function _mkdirp(p: string) {
|
|||||||
if (!fs.existsSync(path.dirname(p))) {
|
if (!fs.existsSync(path.dirname(p))) {
|
||||||
_mkdirp(path.dirname(p));
|
_mkdirp(path.dirname(p));
|
||||||
}
|
}
|
||||||
fs.mkdirSync(p);
|
if (!fs.existsSync(p)) {
|
||||||
|
fs.mkdirSync(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _recursiveFileList(p: string): string[] {
|
function _recursiveFileList(p: string): string[] {
|
||||||
@ -186,21 +188,61 @@ function _exec(command: string, args: string[], opts: { cwd?: string }, logger:
|
|||||||
|
|
||||||
function _build(logger: logging.Logger) {
|
function _build(logger: logging.Logger) {
|
||||||
logger.info('Building...');
|
logger.info('Building...');
|
||||||
_exec('node_modules/.bin/tsc', ['-p', 'tsconfig.json'], {}, logger);
|
_exec('node', [
|
||||||
|
require.resolve('typescript/bin/tsc'),
|
||||||
|
'-p',
|
||||||
|
'tsconfig.json',
|
||||||
|
], {}, logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function _bazel(logger: logging.Logger) {
|
async function _bazel(logger: logging.Logger) {
|
||||||
logger.info('Bazel build...');
|
// TODO: undo this when we fully support bazel on windows.
|
||||||
_exec('bazel', ['build', '//packages/...'], {}, logger);
|
// logger.info('Bazel build...');
|
||||||
|
// _exec('bazel', ['build', '//packages/...'], {}, logger);
|
||||||
|
|
||||||
|
const allJsonFiles = glob.sync('packages/**/*.json', {
|
||||||
|
ignore: [
|
||||||
|
'**/node_modules/**',
|
||||||
|
'**/files/**',
|
||||||
|
'**/*-files/**',
|
||||||
|
'**/package.json',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const quicktypeRunner = require('../tools/quicktype_runner');
|
||||||
|
logger.info('Generating JSON Schema....');
|
||||||
|
|
||||||
|
for (const fileName of allJsonFiles) {
|
||||||
|
if (fs.existsSync(fileName.replace(/\.json$/, '.ts'))
|
||||||
|
|| fs.existsSync(fileName.replace(/\.json$/, '.d.ts'))) {
|
||||||
|
// Skip files that already exist.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const content = fs.readFileSync(fileName, 'utf-8');
|
||||||
|
|
||||||
|
const json = JSON.parse(content);
|
||||||
|
if (!json.$schema) {
|
||||||
|
// Skip non-schema files.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const tsContent = await quicktypeRunner.generate(fileName);
|
||||||
|
const tsPath = path.join(__dirname, '../dist-schema', fileName.replace(/\.json$/, '.ts'));
|
||||||
|
|
||||||
|
_mkdirp(path.dirname(tsPath));
|
||||||
|
fs.writeFileSync(tsPath, tsContent, 'utf-8');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default function(argv: { local?: boolean, snapshot?: boolean }, logger: logging.Logger) {
|
export default async function(
|
||||||
|
argv: { local?: boolean, snapshot?: boolean },
|
||||||
|
logger: logging.Logger,
|
||||||
|
) {
|
||||||
_clean(logger);
|
_clean(logger);
|
||||||
|
|
||||||
const sortedPackages = _sortPackages();
|
const sortedPackages = _sortPackages();
|
||||||
_bazel(logger);
|
await _bazel(logger);
|
||||||
_build(logger);
|
_build(logger);
|
||||||
|
|
||||||
logger.info('Moving packages to dist/');
|
logger.info('Moving packages to dist/');
|
||||||
@ -216,7 +258,7 @@ export default function(argv: { local?: boolean, snapshot?: boolean }, logger: l
|
|||||||
for (const packageName of sortedPackages) {
|
for (const packageName of sortedPackages) {
|
||||||
const pkg = packages[packageName];
|
const pkg = packages[packageName];
|
||||||
const bazelBinPath = pkg.build.replace(/([\\\/]dist[\\\/])(packages)/, (_, dist, packages) => {
|
const bazelBinPath = pkg.build.replace(/([\\\/]dist[\\\/])(packages)/, (_, dist, packages) => {
|
||||||
return path.join(dist, 'bazel-bin', packages);
|
return path.join(dist, 'dist-schema', packages);
|
||||||
});
|
});
|
||||||
if (fs.existsSync(bazelBinPath)) {
|
if (fs.existsSync(bazelBinPath)) {
|
||||||
packageLogger.info(packageName);
|
packageLogger.info(packageName);
|
||||||
|
@ -29,9 +29,9 @@ function _exec(command: string, args: string[], opts: { cwd?: string }, logger:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default function (args: { tag?: string }, logger: logging.Logger) {
|
export default async function (args: { tag?: string }, logger: logging.Logger) {
|
||||||
logger.info('Building...');
|
logger.info('Building...');
|
||||||
build({}, logger.createChild('build'));
|
await build({}, logger.createChild('build'));
|
||||||
|
|
||||||
return Object.keys(packages).reduce((acc: Promise<void>, name: string) => {
|
return Object.keys(packages).reduce((acc: Promise<void>, name: string) => {
|
||||||
const pkg = packages[name];
|
const pkg = packages[name];
|
||||||
|
@ -53,7 +53,7 @@ export interface SnapshotsOptions {
|
|||||||
githubToken?: string;
|
githubToken?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function(opts: SnapshotsOptions, logger: logging.Logger) {
|
export default async function(opts: SnapshotsOptions, logger: logging.Logger) {
|
||||||
// Get the SHA.
|
// Get the SHA.
|
||||||
if (execSync(`git status --porcelain`).toString() && !opts.force) {
|
if (execSync(`git status --porcelain`).toString() && !opts.force) {
|
||||||
logger.error('You cannot run snapshots with local changes.');
|
logger.error('You cannot run snapshots with local changes.');
|
||||||
@ -78,7 +78,7 @@ export default function(opts: SnapshotsOptions, logger: logging.Logger) {
|
|||||||
|
|
||||||
// Run build.
|
// Run build.
|
||||||
logger.info('Building...');
|
logger.info('Building...');
|
||||||
build({ snapshot: true }, logger.createChild('build'));
|
await build({ snapshot: true }, logger.createChild('build'));
|
||||||
|
|
||||||
for (const packageName of Object.keys(packages)) {
|
for (const packageName of Object.keys(packages)) {
|
||||||
const pkg = packages[packageName];
|
const pkg = packages[packageName];
|
||||||
|
@ -5,39 +5,41 @@
|
|||||||
* Use of this source code is governed by an MIT-style license that can be
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* This file is pure JavaScript because we want to avoid any dependency or build step
|
|
||||||
* to it. It's just simple (and zen-ier).
|
|
||||||
*
|
|
||||||
* This file wraps around quicktype and can do one of two things;
|
|
||||||
*
|
|
||||||
* `node quicktype_runner.js <in_path> <out_path>`
|
|
||||||
* Reads the in path and outputs the TS file at the out_path.
|
|
||||||
*
|
|
||||||
* Using `-` as the out_path will output on STDOUT instead of a file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Imports.
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const qtCore = require('quicktype-core');
|
const {
|
||||||
const tempRoot = process.env['BAZEL_TMPDIR'] || require('os').tmpdir();
|
InputData,
|
||||||
|
JSONSchema,
|
||||||
|
JSONSchemaInput,
|
||||||
|
JSONSchemaStore,
|
||||||
|
TypeScriptTargetLanguage,
|
||||||
|
parseJSON,
|
||||||
|
quicktype,
|
||||||
|
} = require('quicktype-core');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file is pure JavaScript because Bazel only support compiling to ES5, while quicktype is
|
||||||
|
* ES2015. This results in an incompatible call to `super()` in the FetchingJSONSchemaStore
|
||||||
|
* class as it tries to call JSONSchemaStore's constructor in ES5.
|
||||||
|
* TODO: move this file to typescript when Bazel supports ES2015 output.
|
||||||
|
*
|
||||||
|
* This file wraps around quicktype and can do one of two things;
|
||||||
|
*
|
||||||
|
* `node quicktype_runner.js <in_path> <out_path>`
|
||||||
|
* Reads the in path and outputs the TS file at the out_path.
|
||||||
|
*
|
||||||
|
* Using `-` as the out_path will output on STDOUT instead of a file.
|
||||||
|
*/
|
||||||
|
|
||||||
// Header to add to all files.
|
// Header to add to all files.
|
||||||
const header = `
|
const header = `
|
||||||
/**
|
// THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE THE
|
||||||
* @license
|
// CORRESPONDING JSON SCHEMA FILE, THEN RUN devkit-admin build (or bazel build ...).
|
||||||
* Copyright Google Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
|
||||||
* found in the LICENSE file at https://angular.io/license
|
|
||||||
*/
|
|
||||||
|
|
||||||
// THIS FILE IS AUTOMATICALLY GENERATED IN BAZEL. TO UPDATE THIS FILE YOU NEED TO CHANGE THE
|
// tslint:disable:no-global-tslint-disable
|
||||||
// CORRESPONDING JSON SCHEMA FILE, THEN RUN BAZEL.
|
// tslint:disable
|
||||||
|
|
||||||
`.replace(/^\n/m, ''); // Remove the first \n, it's in the constant because formatting is 👍.
|
`;
|
||||||
|
|
||||||
// Footer to add to all files.
|
// Footer to add to all files.
|
||||||
const footer = ``;
|
const footer = ``;
|
||||||
@ -46,7 +48,7 @@ const footer = ``;
|
|||||||
* The simplest Node JSONSchemaStore implementation we can build which supports our custom protocol.
|
* The simplest Node JSONSchemaStore implementation we can build which supports our custom protocol.
|
||||||
* Supports reading from ng-cli addresses, valid URLs and files (absolute).
|
* Supports reading from ng-cli addresses, valid URLs and files (absolute).
|
||||||
*/
|
*/
|
||||||
class FetchingJSONSchemaStore extends qtCore.JSONSchemaStore {
|
class FetchingJSONSchemaStore extends JSONSchemaStore {
|
||||||
constructor(inPath) {
|
constructor(inPath) {
|
||||||
super();
|
super();
|
||||||
this._inPath = inPath;
|
this._inPath = inPath;
|
||||||
@ -83,10 +85,10 @@ class FetchingJSONSchemaStore extends qtCore.JSONSchemaStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (content == null) {
|
if (content == null) {
|
||||||
throw new Error(`Address ${JSON.stringify(address)} cannot be resolved.`);
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
return qtCore.parseJSON(content, "JSON Schema", address);
|
return parseJSON(content, "JSON Schema", address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,40 +115,43 @@ async function main(inPath, outPath) {
|
|||||||
async function generate(inPath) {
|
async function generate(inPath) {
|
||||||
// Best description of how to use the API was found at
|
// Best description of how to use the API was found at
|
||||||
// https://blog.quicktype.io/customizing-quicktype/
|
// https://blog.quicktype.io/customizing-quicktype/
|
||||||
const inputData = new qtCore.InputData();
|
const inputData = new InputData();
|
||||||
const source = { name: 'Schema', schema: fs.readFileSync(inPath, 'utf-8') };
|
const source = { name: 'Schema', schema: fs.readFileSync(inPath, 'utf-8') };
|
||||||
|
|
||||||
await inputData.addSource('schema', source, () => {
|
await inputData.addSource('schema', source, () => {
|
||||||
return new qtCore.JSONSchemaInput(new FetchingJSONSchemaStore(inPath));
|
return new JSONSchemaInput(new FetchingJSONSchemaStore(inPath));
|
||||||
});
|
});
|
||||||
|
|
||||||
const lang = new qtCore.TypeScriptTargetLanguage();
|
const lang = new TypeScriptTargetLanguage();
|
||||||
|
|
||||||
const { lines } = await qtCore.quicktype({
|
const { lines } = await quicktype({
|
||||||
lang,
|
lang,
|
||||||
inputData,
|
inputData,
|
||||||
alphabetizeProperties: true,
|
alphabetizeProperties: true,
|
||||||
src: [inPath],
|
|
||||||
rendererOptions: {
|
rendererOptions: {
|
||||||
'just-types': true,
|
'just-types': 'true',
|
||||||
'explicit-unions': true,
|
'explicit-unions': 'true',
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return header + lines.join('\n') + footer;
|
return header + lines.join('\n') + footer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse arguments and run main().
|
if (require.main === module) {
|
||||||
const argv = process.argv.slice(2);
|
// Parse arguments and run main().
|
||||||
if (argv.length < 2 || argv.length > 3) {
|
const argv = process.argv.slice(2);
|
||||||
console.error('Must include 2 or 3 arguments.');
|
if (argv.length < 2 || argv.length > 3) {
|
||||||
process.exit(1);
|
console.error('Must include 2 or 3 arguments.');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
main(argv[0], argv[1])
|
||||||
|
.then(() => process.exit(0))
|
||||||
|
.catch(err => {
|
||||||
|
console.error('An error happened:');
|
||||||
|
console.error(err);
|
||||||
|
process.exit(127);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
main(...argv)
|
exports.generate = generate;
|
||||||
.then(() => process.exit(0))
|
|
||||||
.catch(err => {
|
|
||||||
console.error('An error happened:');
|
|
||||||
console.error(err);
|
|
||||||
process.exit(127);
|
|
||||||
});
|
|
||||||
|
@ -52,7 +52,12 @@ _ts_json_schema_interface = rule(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def ts_json_schema(name, src, data = [], **kwargs):
|
# Generates a library that contains the interface for a JSON Schema file. Takes a single `src`
|
||||||
|
# argument as input, an optional data field for reference files, and produces a ts_library()
|
||||||
|
# rule containing the typescript interface.
|
||||||
|
# The file produced will have the same name, with the extension replaced from `.json` to `.ts`.
|
||||||
|
# Any filename collision will be an error thrown by Bazel.
|
||||||
|
def ts_json_schema(name, src, data = []):
|
||||||
out = src.replace(".json", ".ts")
|
out = src.replace(".json", ".ts")
|
||||||
|
|
||||||
_ts_json_schema_interface(
|
_ts_json_schema_interface(
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
"baseUrl": "",
|
"baseUrl": "",
|
||||||
"rootDirs": [
|
"rootDirs": [
|
||||||
".",
|
".",
|
||||||
|
"./dist-schema/",
|
||||||
"./bazel-bin/"
|
"./bazel-bin/"
|
||||||
],
|
],
|
||||||
"typeRoots": [
|
"typeRoots": [
|
||||||
|
Loading…
x
Reference in New Issue
Block a user