mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
build(bazel): generate aio stackblitz and example zips
Can be served by running bazel run //aio:serve
This commit is contained in:
committed by
Joey Perrott
parent
655427f9b8
commit
9cb9161876
@@ -0,0 +1,19 @@
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
nodejs_binary(
|
||||
name = "generate-example-zips",
|
||||
data = [
|
||||
"exampleZipper.mjs",
|
||||
"//aio/tools/transforms",
|
||||
"@aio_npm//archiver",
|
||||
"@aio_npm//canonical-path",
|
||||
"@aio_npm//fs-extra",
|
||||
"@aio_npm//globby",
|
||||
],
|
||||
entry_point = "generateZips.mjs",
|
||||
# --preserve-symlinks-main is not enabled by default (see https://github.com/bazelbuild/rules_nodejs/pull/2176)
|
||||
# However it seems to be required for mjs entry points to resolve node_modules within the sandbox.
|
||||
templated_args = ["--node_options=--preserve-symlinks-main"],
|
||||
)
|
||||
@@ -19,7 +19,11 @@ export class ExampleZipper {
|
||||
|
||||
let gpathStackblitz = path.join(sourceDirName, '**/*stackblitz.json');
|
||||
let gpathZipper = path.join(sourceDirName, '**/zipper.json');
|
||||
let configFileNames = globbySync([gpathStackblitz, gpathZipper], { ignore: ['**/node_modules/**'] });
|
||||
let configFileNames = globbySync([gpathStackblitz, gpathZipper], {
|
||||
ignore: ['**/node_modules/**'],
|
||||
dot: true // Include subpaths that begin with '.' when using a wildcard inclusion.
|
||||
// Needed to include the bazel .cache folder on Linux.
|
||||
});
|
||||
configFileNames.forEach((configFileName) => {
|
||||
this._zipExample(configFileName, sourceDirName, outputDirName);
|
||||
});
|
||||
@@ -152,7 +156,11 @@ export class ExampleZipper {
|
||||
|
||||
gpaths.push(...alwaysExcludes);
|
||||
|
||||
let fileNames = globbySync(gpaths, { ignore: ['**/node_modules/**'] });
|
||||
let fileNames = globbySync(gpaths, {
|
||||
ignore: ['**/node_modules/**'],
|
||||
dot: true // Include subpaths that begin with '.' when using a wildcard inclusion.
|
||||
// Needed to include the bazel .cache folder on Linux.
|
||||
});
|
||||
|
||||
let zip = this._createZipArchive(outputFileName);
|
||||
fileNames.forEach((fileName) => {
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import path from 'canonical-path';
|
||||
import {fileURLToPath} from 'url';
|
||||
import {ExampleZipper} from './exampleZipper.mjs';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const EXAMPLES_PATH = path.join(__dirname, '../../content/examples');
|
||||
const ZIPS_PATH = path.join(__dirname, '../../src/generated/zips');
|
||||
const argv = process.argv.slice(2);
|
||||
if (argv.length !== 2) {
|
||||
console.error("Usage: node generateZips.mjs [examples-path] [output-path]");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const EXAMPLES_PATH = argv[0];
|
||||
const OUTPUT_PATH = argv[1];
|
||||
const ZIPS_PATH = path.join(OUTPUT_PATH, 'generated', 'zips');
|
||||
|
||||
new ExampleZipper(EXAMPLES_PATH, ZIPS_PATH);
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
nodejs_binary(
|
||||
name = "example-boilerplate",
|
||||
data = [
|
||||
"constants.js",
|
||||
"//aio/content/examples",
|
||||
"@aio_npm//canonical-path",
|
||||
"@aio_npm//fs-extra",
|
||||
"@aio_npm//ignore",
|
||||
"@aio_npm//shelljs",
|
||||
"@aio_npm//yargs",
|
||||
] + glob(["shared/**"]),
|
||||
entry_point = "example-boilerplate.js",
|
||||
)
|
||||
@@ -4,3 +4,4 @@ exports.EXAMPLES_BASE_PATH = path.resolve(__dirname, '../../content/examples');
|
||||
exports.EXAMPLE_CONFIG_FILENAME = 'example-config.json';
|
||||
exports.SHARED_PATH = path.resolve(__dirname, 'shared');
|
||||
exports.STACKBLITZ_CONFIG_FILENAME = 'stackblitz.json';
|
||||
exports.BAZEL_EXAMPLE_BOILERPLATE_OUTPUT_PATH = process.env.BAZEL_EXAMPLE_BOILERPLATE_OUTPUT_PATH;
|
||||
|
||||
@@ -4,7 +4,7 @@ const ignore = require('ignore');
|
||||
const path = require('canonical-path');
|
||||
const shelljs = require('shelljs');
|
||||
const yargs = require('yargs');
|
||||
const {EXAMPLES_BASE_PATH, EXAMPLE_CONFIG_FILENAME, SHARED_PATH} = require('./constants');
|
||||
const {EXAMPLES_BASE_PATH, BAZEL_EXAMPLE_BOILERPLATE_OUTPUT_PATH, EXAMPLE_CONFIG_FILENAME, SHARED_PATH} = require('./constants');
|
||||
|
||||
const SHARED_NODE_MODULES_PATH = path.resolve(SHARED_PATH, 'node_modules');
|
||||
|
||||
@@ -22,13 +22,16 @@ class ExampleBoilerPlate {
|
||||
this.getFoldersContaining(EXAMPLES_BASE_PATH, EXAMPLE_CONFIG_FILENAME, 'node_modules');
|
||||
const gitignore = ignore().add(fs.readFileSync(path.resolve(BOILERPLATE_BASE_PATH, '.gitignore'), 'utf8'));
|
||||
|
||||
if (!fs.existsSync(SHARED_NODE_MODULES_PATH)) {
|
||||
throw new Error(
|
||||
`The shared node_modules folder for the examples (${SHARED_NODE_MODULES_PATH}) is missing.\n` +
|
||||
'Perhaps you need to run "yarn example-use-npm" or "yarn example-use-local" to install the dependencies?');
|
||||
}
|
||||
|
||||
shelljs.exec(`yarn --cwd ${SHARED_PATH} ngcc --properties es2015 main`);
|
||||
// TODO(bazel): Comment this out until example tests are run with bazel. The node_modules folder isn't
|
||||
// needed to build the examples.
|
||||
//
|
||||
// if (!fs.existsSync(SHARED_NODE_MODULES_PATH)) {
|
||||
// throw new Error(
|
||||
// `The shared node_modules folder for the examples (${SHARED_NODE_MODULES_PATH}) is missing.\n` +
|
||||
// 'Perhaps you need to run "yarn example-use-npm" or "yarn example-use-local" to install the dependencies?');
|
||||
// }
|
||||
//
|
||||
// shelljs.exec(`yarn --cwd ${SHARED_PATH} ngcc --properties es2015 main`);
|
||||
|
||||
exampleFolders.forEach(exampleFolder => {
|
||||
const exampleConfig = this.loadJsonFile(path.resolve(exampleFolder, EXAMPLE_CONFIG_FILENAME));
|
||||
@@ -43,26 +46,31 @@ class ExampleBoilerPlate {
|
||||
);
|
||||
const isPathIgnored = absolutePath => boilerplateIgnore.ignores(path.relative(BOILERPLATE_BASE_PATH, absolutePath));
|
||||
|
||||
// TODO(bazel): Comment this out until example tests are being run with bazel. The node_modules folder isn't
|
||||
// needed to build the examples.
|
||||
//
|
||||
// Link the node modules - requires admin access (on Windows) because it adds symlinks
|
||||
const destinationNodeModules = path.resolve(exampleFolder, 'node_modules');
|
||||
fs.ensureSymlinkSync(SHARED_NODE_MODULES_PATH, destinationNodeModules);
|
||||
// const destinationNodeModules = path.resolve(exampleFolder, 'node_modules');
|
||||
// fs.ensureSymlinkSync(SHARED_NODE_MODULES_PATH, destinationNodeModules);
|
||||
|
||||
const boilerPlateType = exampleConfig.projectType || 'cli';
|
||||
const boilerPlateBasePath = path.resolve(BOILERPLATE_BASE_PATH, boilerPlateType);
|
||||
const outputPath = path.join(BAZEL_EXAMPLE_BOILERPLATE_OUTPUT_PATH, path.basename(exampleFolder));
|
||||
shelljs.mkdir('-p', outputPath);
|
||||
|
||||
// All example types other than `cli` and `systemjs` are based on `cli`. Copy over the `cli`
|
||||
// boilerplate files first.
|
||||
// (Some of these files might be later overwritten by type-specific files.)
|
||||
if (boilerPlateType !== 'cli' && boilerPlateType !== 'systemjs') {
|
||||
this.copyDirectoryContents(BOILERPLATE_CLI_PATH, exampleFolder, isPathIgnored);
|
||||
this.copyDirectoryContents(BOILERPLATE_CLI_PATH, outputPath, isPathIgnored);
|
||||
}
|
||||
|
||||
// Copy the type-specific boilerplate files.
|
||||
this.copyDirectoryContents(boilerPlateBasePath, exampleFolder, isPathIgnored);
|
||||
this.copyDirectoryContents(boilerPlateBasePath, outputPath, isPathIgnored);
|
||||
|
||||
// Copy the common boilerplate files (unless explicitly not used).
|
||||
if (exampleConfig.useCommonBoilerplate !== false) {
|
||||
this.copyDirectoryContents(BOILERPLATE_COMMON_PATH, exampleFolder, isPathIgnored);
|
||||
this.copyDirectoryContents(BOILERPLATE_COMMON_PATH, outputPath, isPathIgnored);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
nodejs_binary(
|
||||
name = "generate-stackblitz",
|
||||
data = [
|
||||
"builder.mjs",
|
||||
"//aio/tools/transforms",
|
||||
"@aio_npm//canonical-path",
|
||||
"@aio_npm//fs-extra",
|
||||
"@aio_npm//globby",
|
||||
"@aio_npm//jsdom",
|
||||
],
|
||||
entry_point = "generateStackblitz.mjs",
|
||||
# --preserve-symlinks-main is not enabled by default (see https://github.com/bazelbuild/rules_nodejs/pull/2176)
|
||||
# However it seems to be required for mjs entry points to resolve node_modules within the sandbox.
|
||||
templated_args = ["--node_options=--preserve-symlinks-main"],
|
||||
)
|
||||
@@ -3,17 +3,13 @@ import path from 'canonical-path';
|
||||
import fs from 'fs-extra';
|
||||
import {globbySync} from 'globby';
|
||||
import jsdom from 'jsdom';
|
||||
import {fileURLToPath} from 'url';
|
||||
|
||||
import regionExtractor from '../transforms/examples-package/services/region-parser.js';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
export class StackblitzBuilder {
|
||||
constructor(basePath, destPath) {
|
||||
this.basePath = basePath;
|
||||
this.destPath = destPath;
|
||||
|
||||
this.copyrights = this._buildCopyrightStrings();
|
||||
this._boilerplatePackageJsons = {};
|
||||
}
|
||||
@@ -24,7 +20,10 @@ export class StackblitzBuilder {
|
||||
// When testing it sometimes helps to look a just one example directory like so:
|
||||
// const stackblitzPaths = path.join(this.basePath, '**/testing/*stackblitz.json');
|
||||
const stackblitzPaths = path.join(this.basePath, '**/*stackblitz.json');
|
||||
const fileNames = globbySync(stackblitzPaths, { ignore: ['**/node_modules/**'] });
|
||||
const fileNames = globbySync(stackblitzPaths, { ignore: ['**/node_modules/**'],
|
||||
dot: true // Include subpaths that begin with '.' when using a wildcard inclusion.
|
||||
// Needed to include the bazel .cache folder on Linux.
|
||||
});
|
||||
let failed = false;
|
||||
fileNames.forEach((configFileName) => {
|
||||
try {
|
||||
@@ -79,42 +78,28 @@ export class StackblitzBuilder {
|
||||
// main: string - name of file that will become index.html in the stackblitz - defaults to index.html
|
||||
// file: string - name of file to display within the stackblitz (e.g. `"file": "app/app.module.ts"`)
|
||||
_buildStackblitzFrom(configFileName) {
|
||||
// replace ending 'stackblitz.json' with 'stackblitz.no-link.html' to create output file name;
|
||||
const outputFileName = configFileName.replace(/stackblitz\.json$/, 'stackblitz.no-link.html');
|
||||
let altFileName;
|
||||
if (this.destPath && this.destPath.length > 0) {
|
||||
const partPath = path.dirname(path.relative(this.basePath, outputFileName));
|
||||
altFileName = path.join(this.destPath, partPath, path.basename(outputFileName)).replace('.no-link.', '.');
|
||||
}
|
||||
try {
|
||||
const config = this._initConfigAndCollectFileNames(configFileName);
|
||||
const postData = this._createPostData(config, configFileName);
|
||||
// replace ending 'stackblitz.json' with 'stackblitz.html' to create output file name;
|
||||
const outputFileName = configFileName.replace(/stackblitz\.json$/, 'stackblitz.html');
|
||||
const partPath = path.dirname(path.relative(this.basePath, outputFileName));
|
||||
const outputFilePath = path.join(this.destPath, partPath, path.basename(outputFileName));
|
||||
const config = this._initConfigAndCollectFileNames(configFileName);
|
||||
const postData = this._createPostData(config, configFileName);
|
||||
|
||||
this._addStackblitzrc(postData);
|
||||
this._addStackblitzrc(postData);
|
||||
|
||||
const html = this._createStackblitzHtml(config, postData);
|
||||
fs.writeFileSync(outputFileName, html, 'utf-8');
|
||||
if (altFileName) {
|
||||
const altDirName = path.dirname(altFileName);
|
||||
fs.ensureDirSync(altDirName);
|
||||
fs.writeFileSync(altFileName, html, 'utf-8');
|
||||
}
|
||||
} catch (e) {
|
||||
// if we fail delete the outputFile if it exists because it is an old one.
|
||||
if (fs.existsSync(outputFileName)) {
|
||||
fs.unlinkSync(outputFileName);
|
||||
}
|
||||
if (altFileName && fs.existsSync(altFileName)) {
|
||||
fs.unlinkSync(altFileName);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
const html = this._createStackblitzHtml(config, postData);
|
||||
const outputDirName = path.dirname(outputFilePath);
|
||||
fs.ensureDirSync(outputDirName);
|
||||
fs.writeFileSync(outputFilePath, html, 'utf-8');
|
||||
}
|
||||
|
||||
_checkForOutdatedConfig() {
|
||||
// Ensure that nobody is trying to use the old config filenames (i.e. `plnkr.json`).
|
||||
const plunkerPaths = path.join(this.basePath, '**/*plnkr.json');
|
||||
const fileNames = globbySync(plunkerPaths, { ignore: ['**/node_modules/**'] });
|
||||
const fileNames = globbySync(plunkerPaths, { ignore: ['**/node_modules/**'],
|
||||
dot: true // Include subpaths that begin with '.' when using a wildcard inclusion.
|
||||
// Needed to include the bazel .cache folder on Linux.
|
||||
});
|
||||
|
||||
if (fileNames.length) {
|
||||
const readmePath = path.join(__dirname, 'README.md');
|
||||
@@ -309,7 +294,11 @@ export class StackblitzBuilder {
|
||||
|
||||
gpaths.push(...defaultExcludes);
|
||||
|
||||
config.fileNames = globbySync(gpaths, { ignore: ['**/node_modules/**'] });
|
||||
config.fileNames = globbySync(gpaths, {
|
||||
ignore: ['**/node_modules/**'],
|
||||
dot: true // Include subpaths that begin with '.' when using a wildcard inclusion.
|
||||
// Needed to include the bazel .cache folder on Linux.
|
||||
});
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import {dirname, join} from 'path';
|
||||
import {fileURLToPath} from 'url';
|
||||
import {join} from 'path';
|
||||
import {StackblitzBuilder} from './builder.mjs';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const EXAMPLES_PATH = join(__dirname, '../../content/examples');
|
||||
const LIVE_EXAMPLES_PATH = join(__dirname, '../../src/generated/live-examples');
|
||||
const argv = process.argv.slice(2);
|
||||
if (argv.length !== 2) {
|
||||
console.error("Usage: node generateStackblitz.mjs [examples-path] [output-path]");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const EXAMPLES_PATH = argv[0];
|
||||
const OUTPUT_PATH = argv[1];
|
||||
const LIVE_EXAMPLES_PATH = join(OUTPUT_PATH, 'generated', 'live-examples');
|
||||
|
||||
new StackblitzBuilder(EXAMPLES_PATH, LIVE_EXAMPLES_PATH).build();
|
||||
|
||||
Reference in New Issue
Block a user