-
Notifications
You must be signed in to change notification settings - Fork 6.8k
build: update to typescript v3.8 #18789
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package(default_visibility = ["//visibility:public"]) | ||
|
||
load("@bazel_skylib//rules:write_file.bzl", "write_file") | ||
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_test") | ||
load("//integration/ts-compat:import-all-entry-points.bzl", "generate_import_all_entry_points_file") | ||
|
||
write_file( | ||
name = "import-all-entry-points-file", | ||
out = "import-all-entry-points.ts", | ||
content = [generate_import_all_entry_points_file()], | ||
) | ||
|
||
# List of TypeScript packages that we want to run the compatibility test against. | ||
# The list contains NPM module names that resolve to the desired TypeScript version. | ||
typescript_version_packages = [ | ||
"typescript-3.6", | ||
"typescript-3.7", | ||
"typescript", | ||
] | ||
|
||
# Generates a NodeJS test for each configured TypeScript version. | ||
[ | ||
nodejs_test( | ||
name = ts_pkg_name, | ||
args = [ts_pkg_name], | ||
data = [ | ||
"helpers.js", | ||
"test.js", | ||
":import-all-entry-points-file", | ||
"//src/cdk:npm_package", | ||
"//src/cdk-experimental:npm_package", | ||
"//src/google-maps:npm_package", | ||
"//src/material:npm_package", | ||
"//src/material-experimental:npm_package", | ||
"//src/youtube-player:npm_package", | ||
"@npm//shelljs", | ||
"@npm//%s" % ts_pkg_name, | ||
"@npm//@types/node", | ||
], | ||
entry_point = "test.js", | ||
tags = [ | ||
"integration", | ||
], | ||
) | ||
for ts_pkg_name in typescript_version_packages | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
const {relative, sep, join} = require('path'); | ||
const {readdirSync, readFileSync, existsSync} = require('fs'); | ||
const {set, ln, rm, mkdir} = require('shelljs'); | ||
const {fork} = require('child_process'); | ||
const runfiles = require(process.env.BAZEL_NODE_RUNFILES_HELPER); | ||
|
||
// Exit if any command fails. | ||
set('-e'); | ||
|
||
// List of NPM packages that have been built for the current test target. | ||
const npmPackages = getNpmPackagesFromRunfiles(); | ||
// Path to the node modules of the workspace. | ||
const nodeModulesDir = runfiles.resolve('npm/node_modules'); | ||
// Path to the generated file that imports all entry-points. | ||
const testFilePath = require.resolve('./import-all-entry-points.ts'); | ||
|
||
/** | ||
* Runs the TypeScript compatibility test with the specified tsc binary. The | ||
* compatibility test, links the built release packages into `node_modules` and | ||
* compiles a test file using the specified tsc binary which imports all entry-points. | ||
*/ | ||
exports.runTypeScriptCompatibilityTest = async (tscBinPath) => { | ||
return new Promise((resolve, reject) => { | ||
const angularDir = join(nodeModulesDir, '@angular/'); | ||
|
||
// Create the `node_modules/@angular` directory in case it's not present. | ||
mkdir('-p', angularDir); | ||
|
||
// Symlink npm packages into `node_modules/` so that the project can | ||
// be compiled without path mappings (simulating a real project). | ||
for (const {name, pkgPath} of npmPackages) { | ||
console.info(`Linking "@angular/${name}" into node modules..`); | ||
ln('-s', pkgPath, join(angularDir, name)); | ||
} | ||
|
||
const tscArgs = [ | ||
'--strict', | ||
'--lib', 'es2015,dom', | ||
// Ensures that `node_modules` can be resolved. By default, in sandbox environments the | ||
// node modules cannot be resolved because they are wrapped in the `npm/node_modules` folder | ||
'--baseUrl', nodeModulesDir, | ||
testFilePath | ||
]; | ||
// Run `tsc` to compile the project. The stdout/stderr output is inherited, so that | ||
// warnings and errors are printed to the console. | ||
const tscProcess = fork(tscBinPath, tscArgs, {stdio: 'inherit'}); | ||
|
||
tscProcess.on('exit', (exitCode) => { | ||
// Remove symlinks to keep a clean repository state. | ||
for (const {name} of npmPackages) { | ||
console.info(`Removing link for "@angular/${name}"..`); | ||
rm(join(angularDir, name)); | ||
} | ||
exitCode === 0 ? resolve() : reject(); | ||
}); | ||
}); | ||
}; | ||
|
||
/** | ||
* Gets all built Angular NPM package artifacts by querying the Bazel runfiles. | ||
* In case there is a runfiles manifest (e.g. on Windows), the packages are resolved | ||
* through the manifest because the runfiles are not symlinked and cannot be searched | ||
* within the real filesystem. TODO: Remove if Bazel on Windows uses runfile symlinking. | ||
*/ | ||
function getNpmPackagesFromRunfiles() { | ||
// Path to the Bazel runfiles manifest if present. This file is present if runfiles are | ||
// not symlinked into the runfiles directory. | ||
const runfilesManifestPath = process.env.RUNFILES_MANIFEST_FILE; | ||
const workspacePath = 'angular_material/src'; | ||
if (!runfilesManifestPath) { | ||
const packageRunfilesDir = join(process.env.RUNFILES, workspacePath); | ||
return readdirSync(packageRunfilesDir) | ||
.map(name => ({name, pkgPath: join(packageRunfilesDir, name, 'npm_package/')})) | ||
.filter(({pkgPath}) => existsSync(pkgPath)); | ||
} | ||
const workspaceManifestPathRegex = new RegExp(`^${workspacePath}/[\\w-]+/npm_package$`); | ||
return readFileSync(runfilesManifestPath, 'utf8') | ||
.split('\n') | ||
.map(mapping => mapping.split(' ')) | ||
.filter(([runfilePath]) => runfilePath.match(workspaceManifestPathRegex)) | ||
.map(([runfilePath, realPath]) => ({ | ||
name: relative(workspacePath, runfilePath).split(sep)[0], | ||
pkgPath: realPath, | ||
})); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
load("//src/cdk:config.bzl", "CDK_ENTRYPOINTS") | ||
load("//src/cdk-experimental:config.bzl", "CDK_EXPERIMENTAL_ENTRYPOINTS") | ||
load("//src/material:config.bzl", "MATERIAL_ENTRYPOINTS", "MATERIAL_TESTING_ENTRYPOINTS") | ||
load("//src/material-experimental:config.bzl", "MATERIAL_EXPERIMENTAL_ENTRYPOINTS", "MATERIAL_EXPERIMENTAL_TESTING_ENTRYPOINTS") | ||
|
||
"""Converts the given string to an identifier.""" | ||
|
||
def convert_to_identifier(name): | ||
return name.replace("/", "_").replace("-", "_") | ||
|
||
"""Creates imports and exports for the given entry-point and package.""" | ||
|
||
def create_import_export(entry_point, pkg_name): | ||
identifier = "%s_%s" % (convert_to_identifier(pkg_name), convert_to_identifier(entry_point)) | ||
return """ | ||
import * as {0} from "@angular/{1}/{2}"; | ||
export {{ {0} }}; | ||
""".format(identifier, pkg_name, entry_point) | ||
|
||
""" | ||
Creates a file that imports all entry-points as namespace. The namespaces will be | ||
re-exported. This ensures that all entry-points can successfully compile. | ||
""" | ||
|
||
def generate_import_all_entry_points_file(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a way we could consolidate on a single, canonical list of packages for the repo? Right now I think there's a handful of places that need to be updated when we add a new package. Either that, or just documenting all the places that need to be updated There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💯 Definitely agreed. I've been trying to reduce this type of duplication (as seen with entry-points in the system config etc.). I'll work on a follow-up that gives us a better list of release packages. The problem always comes from the fact that we can't easily access these variables outside of Bazel (e.g. in the release scripts). |
||
output = """ | ||
import * as cdk from "@angular/cdk"; | ||
import * as cdk_experimental from "@angular/cdk-experimental"; | ||
// Note: The primary entry-point for Angular Material does not have | ||
// any exports, so it cannot be imported as module. | ||
import * as material_experimental from "@angular/material-experimental"; | ||
import * as google_maps from "@angular/google-maps"; | ||
import * as youtube_player from "@angular/youtube-player"; | ||
export {cdk, cdk_experimental, material_experimental, google_maps, youtube_player}; | ||
""" | ||
for ep in CDK_ENTRYPOINTS: | ||
output += create_import_export(ep, "cdk") | ||
for ep in CDK_EXPERIMENTAL_ENTRYPOINTS: | ||
output += create_import_export(ep, "cdk-experimental") | ||
for ep in MATERIAL_ENTRYPOINTS + MATERIAL_TESTING_ENTRYPOINTS: | ||
output += create_import_export(ep, "material") | ||
for ep in MATERIAL_EXPERIMENTAL_ENTRYPOINTS + MATERIAL_EXPERIMENTAL_TESTING_ENTRYPOINTS: | ||
output += create_import_export(ep, "material-experimental") | ||
return output |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/** | ||
* Test script that runs the TypeScript compatibility tests against a specified | ||
* TypeScript package that is passed through command line. The script is executed | ||
* by a Bazel `nodejs_test` target and relies on Bazel runfile resolution. | ||
*/ | ||
|
||
const {runTypeScriptCompatibilityTest} = require('./helpers'); | ||
|
||
if (module === require.main) { | ||
const [pkgName] = process.argv.slice(2); | ||
if (!pkgName) { | ||
console.error('No TypeScript package specified. Exiting..'); | ||
process.exit(1); | ||
} | ||
runTypeScriptCompatibilityTest(require.resolve(`${pkgName}/bin/tsc`)).catch(e => { | ||
console.error(e); | ||
process.exit(1); | ||
}); | ||
} |
Uh oh!
There was an error while loading. Please reload this page.