| /** |
| * @license |
| * Copyright 2017 The Bazel Authors. All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * |
| * You may obtain a copy of the License at |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| /** |
| * @fileoverview This script generates the BUILD.bazel file for NodeJS, npm & yarn. |
| */ |
| 'use strict'; |
| |
| const fs = require('fs'); |
| const path = require('path'); |
| |
| const IS_WINDOWS = TEMPLATED_is_windows; |
| const NODE_DIR = 'TEMPLATED_node_dir'; |
| const YARN_DIR = 'TEMPLATED_yarn_dir'; |
| const NODE_ACTUAL = 'TEMPLATED_node_actual'; |
| const NPM_ACTUAL = 'TEMPLATED_npm_actual'; |
| const YARN_ACTUAL = 'TEMPLATED_yarn_actual'; |
| |
| if (require.main === module) { |
| main(); |
| } |
| |
| function mkdirp(dirname) { |
| if (!fs.existsSync(dirname)) { |
| mkdirp(path.dirname(dirname)); |
| fs.mkdirSync(dirname); |
| } |
| } |
| |
| function writeFileSync(filePath, contents) { |
| mkdirp(path.dirname(filePath)); |
| fs.writeFileSync(filePath, contents); |
| } |
| |
| /** |
| * Main entrypoint. |
| * Write BUILD file. |
| */ |
| function main() { |
| generateBuildFile() |
| } |
| |
| module.exports = { main }; |
| |
| function generateBuildFile() { |
| // *.pyc files are generated during node-gyp compilation and include |
| // absolute paths, making them non-hermetic. |
| // See https://github.com/bazelbuild/rules_nodejs/issues/347 |
| const excludedFiles = ['.md', '.html', '.pyc']; |
| const nodejsSrcFiles = filterFilesForFilegroup(listFiles(NODE_DIR), [], excludedFiles) |
| const yarnSrcFiles = filterFilesForFilegroup(listFiles(YARN_DIR), [], excludedFiles) |
| |
| const binaryExt = IS_WINDOWS ? '.cmd' : ''; |
| const buildFile = `# Generated by node_repositories.bzl |
| package(default_visibility = ["//visibility:public"]) |
| exports_files([ |
| "run_npm.sh.template", |
| "bin/node_args.sh", |
| "${NODE_DIR}/bin/node", |
| "bin/node${binaryExt}", |
| "bin/npm${binaryExt}", |
| "bin/npm_node_repositories${binaryExt}", |
| "bin/yarn${binaryExt}", |
| "bin/yarn_node_repositories${binaryExt}", |
| ]) |
| alias(name = "node", actual = "${NODE_ACTUAL}") |
| alias(name = "npm", actual = "${NPM_ACTUAL}") |
| alias(name = "yarn", actual = "${YARN_ACTUAL}") |
| filegroup( |
| name = "node_runfiles", |
| srcs = [ |
| ${nodejsSrcFiles.map(f => `"${NODE_DIR}/${f}",`).join('\n ')} |
| ${yarnSrcFiles.map(f => `"${YARN_DIR}/${f}",`).join('\n ')} |
| ], |
| ) |
| ` |
| writeFileSync('BUILD.bazel', buildFile); |
| } |
| |
| /** |
| * Returns an array of all the files under a directory as relative |
| * paths to the directory. |
| */ |
| function listFiles(rootDir, subDir = '') { |
| const dir = path.posix.join(rootDir, subDir); |
| if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) { |
| return []; |
| } |
| return fs |
| .readdirSync(dir) |
| .reduce((files, file) => { |
| const fullPath = path.posix.join(dir, file); |
| const relPath = path.posix.join(subDir, file); |
| let stat; |
| try { |
| stat = fs.statSync(fullPath); |
| } catch (e) { |
| throw e; |
| } |
| return stat.isDirectory() ? files.concat(listFiles(rootDir, relPath)) : |
| files.concat(relPath); |
| }, []); |
| } |
| |
| /** |
| * A filter function for a bazel filegroup. |
| * @param files array of files to filter |
| * @param allowedExts list of white listed extensions; if empty, no filter is done on extensions; |
| * '' empty string denotes to allow files with no extensions, other extensions |
| * are listed with '.ext' notation such as '.d.ts'. |
| */ |
| function filterFilesForFilegroup(files, allowedExts = [], excludedExts = []) { |
| // Files with spaces (\x20) or unicode characters (<\x20 && >\x7E) are not allowed in |
| // Bazel runfiles. See https://github.com/bazelbuild/bazel/issues/4327 |
| files = files.filter(f => !f.match(/[^\x21-\x7E]/)); |
| if (allowedExts.length) { |
| const allowNoExts = allowedExts.includes(''); |
| files = files.filter(f => { |
| // include files with no extensions if noExt is true |
| if (allowNoExts && !path.extname(f)) return true; |
| // filter files in allowedExts |
| for (const e of allowedExts) { |
| if (e && f.endsWith(e)) { |
| return true; |
| } |
| } |
| return false; |
| }) |
| } |
| if (excludedExts.length) { |
| files = files.filter(f => { |
| // filter out files in excludedExts |
| for (const e of excludedExts) { |
| if (e && f.endsWith(e)) { |
| return false; |
| } |
| } |
| return true; |
| }) |
| } |
| return files; |
| } |