| 
									
										
										
										
											2020-03-02 18:35:30 +01:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							| 
									
										
										
										
											2020-05-19 12:08:49 -07:00
										 |  |  |  * Copyright Google LLC All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2020-03-02 18:35:30 +01:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Build the dist/packages-dist directory in the same fashion as the legacy
 | 
					
						
							|  |  |  | // /build.sh script, by building the npm packages with Bazel and copying files.
 | 
					
						
							|  |  |  | // This is needed for scripts and tests which are not updated to the Bazel output
 | 
					
						
							|  |  |  | // layout (which always matches the input layout).
 | 
					
						
							|  |  |  | // Do not add new dependencies on this script, instead adapt scripts to use the
 | 
					
						
							|  |  |  | // new layout, and write new tests as Bazel targets.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Ideally integration tests should run under bazel, and just consume the npm
 | 
					
						
							|  |  |  | // packages via `deps`. Until that works, we manually build the npm packages and then
 | 
					
						
							|  |  |  | // copy the results to the appropriate `dist` location.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-18 20:54:54 +00:00
										 |  |  | // NOTE: this script may be run from any directory. The actions should be written to be independent
 | 
					
						
							|  |  |  | // of the current working directory. For example, use absolute paths wherever possible, and pass a
 | 
					
						
							|  |  |  | // working directory to tools like `yarn`.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  | const {execSync} = require('child_process'); | 
					
						
							|  |  |  | const {resolve, relative} = require('path'); | 
					
						
							| 
									
										
										
										
											2019-11-18 16:33:24 +02:00
										 |  |  | const {chmod, cp, mkdir, rm, set, test} = require('shelljs'); | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | set('-e'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** @type {string} The absolute path to the project root directory. */ | 
					
						
							| 
									
										
										
										
											2020-02-29 22:25:49 +02:00
										 |  |  | const baseDir = resolve(`${__dirname}/../..`); | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** @type {string} The command to use for running bazel. */ | 
					
						
							| 
									
										
										
										
											2019-11-18 20:54:54 +00:00
										 |  |  | const bazelCmd = `yarn --cwd "${baseDir}" --silent bazel`; | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** @type {string} The absolute path to the bazel-bin directory. */ | 
					
						
							|  |  |  | const bazelBin = exec(`${bazelCmd} info bazel-bin`, true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @type {string} | 
					
						
							|  |  |  |  * The relative path to the entry script (i.e. the one loaded when the Node.js process launched). | 
					
						
							|  |  |  |  * It is relative to `baseDir`. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const scriptPath = relative(baseDir, require.main.filename); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = { | 
					
						
							| 
									
										
										
										
											2020-05-05 13:12:39 -07:00
										 |  |  |   baseDir, | 
					
						
							|  |  |  |   bazelBin, | 
					
						
							|  |  |  |   bazelCmd, | 
					
						
							|  |  |  |   buildTargetPackages, | 
					
						
							|  |  |  |   exec, | 
					
						
							|  |  |  |   scriptPath, | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2020-02-29 21:05:23 +02:00
										 |  |  |  * Build the Angular packages. | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-05 19:05:54 +03:00
										 |  |  |  * @param {string} destDir Path to the output directory into which we copy the npm packages. | 
					
						
							| 
									
										
										
										
											2019-11-18 20:54:54 +00:00
										 |  |  |  * This path should either be absolute or relative to the project root. | 
					
						
							| 
									
										
										
										
											2019-11-22 12:11:48 -08:00
										 |  |  |  * @param {boolean} enableIvy True, if Ivy should be used. | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  |  * @param {string} description Human-readable description of the build. | 
					
						
							| 
									
										
										
										
											2020-12-11 12:51:29 -08:00
										 |  |  |  * @param {boolean?} isRelease True, if the build should be stamped for a release. | 
					
						
							| 
									
										
										
										
											2020-11-12 11:01:01 -08:00
										 |  |  |  * @returns {Array<{name: string, outputPath: string}} A list of packages built. | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-04-05 19:05:54 +03:00
										 |  |  | function buildTargetPackages(destDir, enableIvy, description, isRelease = false) { | 
					
						
							| 
									
										
										
										
											2020-03-02 18:35:30 +01:00
										 |  |  |   console.info('##################################'); | 
					
						
							|  |  |  |   console.info(`${scriptPath}:`); | 
					
						
							|  |  |  |   console.info('  Building @angular/* npm packages'); | 
					
						
							|  |  |  |   console.info(`  Mode: ${description}`); | 
					
						
							|  |  |  |   console.info('##################################'); | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 11:01:01 -08:00
										 |  |  |   /** The list of packages which were built. */ | 
					
						
							|  |  |  |   const builtPackages = []; | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  |   // List of targets to build, e.g. core, common, compiler, etc. Note that we want to also remove
 | 
					
						
							|  |  |  |   // all carriage return (`\r`) characters form the query output, because otherwise the carriage
 | 
					
						
							|  |  |  |   // return is part of the bazel target name and bazel will complain.
 | 
					
						
							| 
									
										
										
										
											2020-05-05 13:12:39 -07:00
										 |  |  |   const getTargetsCmd = `${ | 
					
						
							|  |  |  |       bazelCmd} query --output=label "attr('tags', '\\[.*release-with-framework.*\\]', //packages/...) intersect kind('ng_package|pkg_npm', //packages/...)"`;
 | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  |   const targets = exec(getTargetsCmd, true).split(/\r?\n/); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-14 20:23:52 +02:00
										 |  |  |   // If we are in release mode, run `bazel clean` to ensure the execroot and action cache
 | 
					
						
							|  |  |  |   // are not populated. This is necessary because targets using `npm_package` rely on
 | 
					
						
							|  |  |  |   // workspace status variables for the package version. Such NPM package targets are not
 | 
					
						
							|  |  |  |   // rebuilt if only the workspace status variables change. This could result in accidental
 | 
					
						
							|  |  |  |   // re-use of previously built package output with a different `version` in the `package.json`.
 | 
					
						
							|  |  |  |   if (isRelease) { | 
					
						
							|  |  |  |     console.info('Building in release mode. Resetting the Bazel execroot and action cache..'); | 
					
						
							|  |  |  |     exec(`${bazelCmd} clean`); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-11 12:51:29 -08:00
										 |  |  |   // Use either `--config=snapshot` or `--config=release` so that builds are created with the
 | 
					
						
							|  |  |  |   // correct embedded version info.
 | 
					
						
							|  |  |  |   exec(`${bazelCmd} build --config=${isRelease ? 'release' : 'snapshot'} --config=${ | 
					
						
							|  |  |  |       enableIvy ? 'ivy' : 'view-engine'} ${targets.join(' ')}`);
 | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Create the output directory.
 | 
					
						
							| 
									
										
										
										
											2021-04-05 19:05:54 +03:00
										 |  |  |   const absDestDir = resolve(baseDir, destDir); | 
					
						
							|  |  |  |   if (!test('-d', absDestDir)) { | 
					
						
							|  |  |  |     mkdir('-p', absDestDir); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   targets.forEach(target => { | 
					
						
							|  |  |  |     const pkg = target.replace(/\/\/packages\/(.*):npm_package/, '$1'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Skip any that don't have an "npm_package" target.
 | 
					
						
							|  |  |  |     const srcDir = `${bazelBin}/packages/${pkg}/npm_package`; | 
					
						
							| 
									
										
										
										
											2021-04-05 19:05:54 +03:00
										 |  |  |     const destDir = `${absDestDir}/${pkg}`; | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-18 16:33:24 +02:00
										 |  |  |     if (test('-d', srcDir)) { | 
					
						
							| 
									
										
										
										
											2020-03-02 18:35:30 +01:00
										 |  |  |       console.info(`# Copy artifacts to ${destDir}`); | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  |       rm('-rf', destDir); | 
					
						
							|  |  |  |       cp('-R', srcDir, destDir); | 
					
						
							|  |  |  |       chmod('-R', 'u+w', destDir); | 
					
						
							| 
									
										
										
										
											2020-11-12 11:01:01 -08:00
										 |  |  |       builtPackages.push({name: `@angular/${pkg}`, outputPath: destDir}); | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2020-02-29 22:25:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   console.info(''); | 
					
						
							| 
									
										
										
										
											2020-11-12 11:01:01 -08:00
										 |  |  |   return builtPackages; | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Execute a command synchronously. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * By default, the current process' stdout is used (and thus the output is not captured and returned | 
					
						
							|  |  |  |  * to the caller). This is necessary for showing colors and modifying already printed output, for | 
					
						
							|  |  |  |  * example to show progress. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * If the caller requests the output (via `captureStdout: true`), the command is run without | 
					
						
							|  |  |  |  * printing anything to stdout and then (once the command has completed) the whole output is printed | 
					
						
							|  |  |  |  * to stdout and returned to the caller. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @param {string} cmd The command to run. | 
					
						
							|  |  |  |  * @param {boolean} [captureStdout=false] Whether to return the output of the command. | 
					
						
							| 
									
										
										
										
											2020-10-27 18:07:59 +02:00
										 |  |  |  * @param {import('child_process').ExecSyncOptions} [options] The options to pass to `execSync()`. | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  |  * @return {string | undefined} The captured stdout output if `captureStdout: true` or `undefined`. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-10-27 18:07:59 +02:00
										 |  |  | function exec(cmd, captureStdout, options) { | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  |   const output = execSync(cmd, { | 
					
						
							|  |  |  |     stdio: [ | 
					
						
							|  |  |  |       /* stdin  */ 'inherit', | 
					
						
							|  |  |  |       /* stdout */ captureStdout ? 'pipe' : 'inherit', | 
					
						
							|  |  |  |       /* stderr */ 'inherit', | 
					
						
							|  |  |  |     ], | 
					
						
							| 
									
										
										
										
											2020-10-27 18:07:59 +02:00
										 |  |  |     ...options, | 
					
						
							| 
									
										
										
										
											2019-11-15 02:56:55 +02:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (captureStdout) { | 
					
						
							|  |  |  |     process.stdout.write(output); | 
					
						
							|  |  |  |     return output.toString().trim(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |