From 222509e2bc6e54fd774de64106fd49787313edb9 Mon Sep 17 00:00:00 2001 From: Jason Bedard Date: Tue, 4 Apr 2023 12:51:46 -0700 Subject: [PATCH] chore(6.0): remove @bazel/create --- .bazelci/presubmit.yml | 3 - README.md | 14 -- docs/index.md | 125 ----------------- packages/create/BUILD.bazel | 43 ------ packages/create/README.md | 19 --- packages/create/index.js | 256 ----------------------------------- packages/create/package.json | 21 --- packages/create/test.js | 98 -------------- scripts/on-release.js | 2 +- 9 files changed, 1 insertion(+), 580 deletions(-) delete mode 100644 packages/create/BUILD.bazel delete mode 100644 packages/create/README.md delete mode 100644 packages/create/index.js delete mode 100644 packages/create/package.json delete mode 100644 packages/create/test.js diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index 4c2fc60647..1819535dc6 100644 --- a/.bazelci/presubmit.yml +++ b/.bazelci/presubmit.yml @@ -15,8 +15,6 @@ tasks: platform: ubuntu1804 run_targets: - "@yarn//:yarn" - # Regression test for #1493 - - "//packages/create:npm_package.pack" - "//internal/node/test:no_deps" - "//internal/node/test:has_deps_legacy" - "//internal/node/test:has_deps" @@ -111,7 +109,6 @@ tasks: # run_targets: # - "@yarn//:yarn" # # Regression test for #1493 - # - "//packages/create:npm_package.pack" # - "//internal/node/test:no_deps" # - "//internal/node/test:has_deps_legacy" # - "//internal/node/test:has_deps" diff --git a/README.md b/README.md index f4e163ecb0..34c6d52a57 100644 --- a/README.md +++ b/README.md @@ -38,20 +38,6 @@ If you use code from an `/internal` path, these are not subject to our support p Comprehensive documentation for installing and using the rules, including generated API docs: https://bazelbuild.github.io/rules_nodejs/ -## Quickstart - -This is the fastest way to get started. -See the [installation documentation](https://bazelbuild.github.io/rules_nodejs/install.html) for details and alternative methods, or if you already have a Bazel project and you're adding Node/JavaScript support to it. - -```sh -$ npx @bazel/create my_workspace -$ cd my_workspace -``` - -> The `npx` tool is distributed with node. If you prefer, you can run equivalent commands `npm init @bazel` or `yarn create @bazel`. -> If you've used `@bazel/create` before, you may want to use `npx @bazel/create@latest` to get the most recent version. -> Run without any arguments to see available command-line flags. - ## Adopters Thanks to the following active users! diff --git a/docs/index.md b/docs/index.md index 4d5862f95d..375eac344a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -63,131 +63,6 @@ The JS ecosystem is also full of false equivalence arguments. The first question This is understandable, since most JS tooling is forced to provide a single turn-key experience with an isolated ecosystem of plugins, and humans love a head-to-head competition. Instead Bazel just orchestrates calling these tools. -## Quickstart - -First we create a new workspace, which will be in a new directory. -We can use the `@bazel/create` npm package to do this in one command. -This is the fastest way to get started for most use cases. - -> See [the installation page](install.html) for details and alternative methods. - -```sh -$ npm init @bazel my_workspace -$ cd my_workspace -``` - -> You could do the same thing with yarn: -> ```sh -> $ yarn create @bazel my_workspace -> $ cd my_workspace -> ``` -> Both of these commands are equivalent to `npx @bazel/create` which downloads the latest version of the `@bazel/create` package from npm and runs the program it contains. -> Run the tool with no arguments for command-line options and next steps. - -Next we install some development tools. -For this example, we'll use Babel to transpile our JavaScript, Mocha for running tests, and http-server to serve our app. -These are arbitrary choices, you may use whatever are your favorites. - -```sh -$ npm install @babel/core @babel/cli @babel/preset-env http-server mocha domino -``` - -Let's run these tools with Bazel. There are two ways to run tools: - -- Use an auto-generated Bazel rule by importing from an `index.bzl` file in the npm package -- Use a custom rule in rules_nodejs or write one yourself - -In this example we use the auto-generated rules. -First we need to import them, using a load statement. -So edit `BUILD.bazel` and add: - -```python -load("@npm//@babel/cli:index.bzl", "babel") -load("@npm//mocha:index.bzl", "mocha_test") -load("@npm//http-server:index.bzl", "http_server") -``` - -> This shows us that rules_nodejs has told Bazel that a workspace named @npm is available -> (think of the at-sign like a scoped package for Bazel). -> rules_nodejs will add `index.bzl` files exposing all the binaries the package manager installed -> (the same as the content of the `node_modules/.bin folder`). -> The three tools we installed are in this @npm scope and each has an index file with a .bzl extension. - -Next we teach Bazel how to transform our JavaScript inputs into transpiled outputs. -Here we assume that you have `app.js` and `es5.babelrc` in your project. See [our example webapp](https://github.com/bazelbuild/rules_nodejs/tree/1.4.0/examples/webapp) for an example of what those files might look like. -Now we want Babel to produce `app.es5.js` so we add to `BUILD.bazel`: - -```python -babel( - name = "compile", - data = [ - "app.js", - "es5.babelrc", - "@npm//@babel/preset-env", - ], - outs = ["app.es5.js"], - args = [ - "app.js", - "--config-file", - "./$(execpath es5.babelrc)", - "--out-file", - "$(execpath app.es5.js)", - ], -) -``` - -> This just calls the Babel CLI, so you can see [their documentation](https://babeljs.io/docs/en/babel-cli) for what arguments to pass. -> We use the $(execpath) helper in Bazel so we don't need to hardcode paths to the inputs or outputs. - -We can now build the application: `npm run build` - -and we see the .js outputs from babel appear in the `dist/bin` folder. - -Let's serve the app to see how it looks, by adding to `BUILD.bazel`: - -``` -http_server( - name = "server", - data = [ - "index.html", - "app.es5.js", - ], - args = ["."], -) -``` - -Add a `serve` entry to the scripts in `package.json`: - -```json -{ - "scripts": { - "serve": "ibazel run :server" - } -} -``` - -> ibazel is the watch mode for bazel. -> -> Note that on Windows, you need to pass `--enable_runfiles` flag to Bazel. -> That's because Bazel creates a directory where inputs and outputs both conveniently appear together. - -Now we can serve the app: `npm run serve` - -Finally we'll add a test using Mocha, and the domino package so we don't need a browser. Add to `BUILD.bazel`: - -```python -mocha_test( - name = "unit_tests", - args = ["*.spec.js"], - data = glob(["*.spec.js"]) + [ - "@npm//domino", - "app.es5.js", - ], -) -``` - -Run the tests: `npm test` - ## Next steps Look through the `/examples` directory in this repo for many examples of running tools under Bazel. diff --git a/packages/create/BUILD.bazel b/packages/create/BUILD.bazel deleted file mode 100644 index b3a213bb6d..0000000000 --- a/packages/create/BUILD.bazel +++ /dev/null @@ -1,43 +0,0 @@ -load("@build_bazel_rules_nodejs//:tools/defaults.bzl", "nodejs_test", "pkg_npm") -load("//third_party/github.com/bazelbuild/bazel-skylib:rules/copy_file.bzl", "copy_file") - -# Copy common bazelrc file to be included in this package -copy_file( - name = "copy_bazelrc", - src = "//:common.bazelrc", - out = "common.bazelrc", -) - -copy_file( - name = "copy_bazelversion", - src = "//:.bazelversion", - out = ".bazelversion", -) - -pkg_npm( - name = "npm_package", - package_name = "@bazel/create", - srcs = [ - "README.md", - "index.js", - "package.json", - ], - deps = [ - ":copy_bazelrc", - ":copy_bazelversion", - ], -) - -nodejs_test( - name = "test", - data = [ - "test.js", - ":npm_package", - "@npm//minimist", - ], - entry_point = ":test.js", -) - -# TODO(alexeagle): add e2e testing by running bazel in a newly created project -# load("@build_bazel_integration_testing//tools:common.bzl", "GET_LATEST_BAZEL_VERSIONS") -# some_nodejs_bazel_integration_test or use Java/Go existing libraries diff --git a/packages/create/README.md b/packages/create/README.md deleted file mode 100644 index 2434952443..0000000000 --- a/packages/create/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# @bazel/create - -This package allows users to have a very simple quickstart to get up and running with Bazel via npm or yarn. - -```bash -$ npx @bazel/create -# or -$ yarn create @bazel -# or -$ npm init @bazel -``` - -See https://yarnpkg.com/en/docs/cli/create and https://docs.npmjs.com/cli/init - -# Design - -We version @bazel/create along with the other packages in this monorepo. - -yarn and npm will download this package globally. For this reason we take no dependencies here to minimize the risk of version conflicts in the global install space. diff --git a/packages/create/index.js b/packages/create/index.js deleted file mode 100644 index 2b0c83bd84..0000000000 --- a/packages/create/index.js +++ /dev/null @@ -1,256 +0,0 @@ -#!/usr/bin/env node - -const fs = require('fs'); -const path = require('path'); -const VERBOSE_LOGS = !!process.env['VERBOSE_LOGS']; - -function log_verbose(...m) { - if (VERBOSE_LOGS) console.error('[@bazel/create]', ...m); -} - -/** - * Detect if the user ran `yarn create @bazel` so we can default - * to using yarn in the new workspace. - * - * TODO: check whether it detects properly on Windows - */ -function detectRunningUnderYarn() { - const executable = process.argv[1]; - if (!!executable && executable.indexOf('yarn/bin') >= 0) { - return true; - } - if (process.env['_'] && process.env['_'].endsWith('yarn')) { - return true; - } - return false; -} - -function validateWorkspaceName(name, error) { - if (/^[_a-zA-Z0-9]+$/.test(name)) { - return true; - } - error(`ERROR: ${name} is not a valid Bazel workspace name. - - A workspace name must start with a letter and can contain letters, numbers, and underscores - (this is to maximize the number of languages for which this string can be a valid package/module name). - It should describe the project in reverse-DNS form, with elements separated by underscores. - For example, if a project is hosted at example.com/some-project, - you might use com_example_some_project as the workspace name. - From https://docs.bazel.build/versions/main/be/functions.html#workspace`); - - return false; -} - -function usage(error) { - error(`@bazel/create usage: - - Invoke it with any of these equivalent commands: - npx @bazel/create [workspace name] [options...] - npm init @bazel [workspace name] [options...] - yarn create @bazel [workspace name] [options...] - - Options: - --packageManager=[yarn|npm] Select npm or yarn to install packages - (default: npm if you ran npm/npx, yarn if you ran yarn create) - --typescript Set up the workspace for TypeScript development - --workspaceDir Set a name for the directory containing the workspace - (default: workspace name) - - Run @bazel/create --help to see all options - `); -} - -function main(argv, error = console.error, log = console.log) { - const args = require('minimist')(argv, { - boolean: ['typescript'], - }); - - if (args['help']) { - usage(error); - return 0; - } - - if (!args['_'] || args['_'].length < 1) { - error('Please specify the workspace directory\n'); - usage(error); - return 1; - } - - // Which package manager will be used in the new project - let pkgMgr = args['packageManager']; - - if (!pkgMgr) { - pkgMgr = detectRunningUnderYarn() ? 'yarn' : 'npm'; - } else if(pkgMgr !== 'yarn' && pkgMgr !== 'npm') { - error('Please select between \'yarn\' and \'npm\' when providing --packageManager'); - usage(error); - return 1; - } - - log_verbose('Running with', process.argv); - log_verbose('Environment', process.env); - - const [wkspName] = args['_']; - const wkspDir = args['workspaceDir'] || wkspName; - - if (!validateWorkspaceName(wkspName, error)) { - return 1; - } - - log(`Creating Bazel workspace ${wkspName}...`); - if (!fs.existsSync(wkspDir)) { - fs.mkdirSync(wkspDir); - } - fs.mkdirSync(path.join(wkspDir, 'tools')); - - function write(workspaceRelativePath, content) { - fs.writeFileSync( - path.join(wkspDir, workspaceRelativePath), content + require('os').EOL, - {encoding: 'utf-8'}); - } - - const devDependencies = { - '@bazel/bazelisk': 'latest', - '@bazel/ibazel': 'latest', - '@bazel/buildifier': 'latest', - }; - let rootBuildContent = '# Add rules here to build your software\n' + - '# See https://docs.bazel.build/versions/main/build-ref.html#BUILD_files\n\n'; - - if (args['typescript']) { - devDependencies['typescript'] = 'latest'; - write('tsconfig.json', `\ -{ - // If building without sandboxing, we need to prevent TypeScript from descending into - // Bazel's external folder which contains third-party Bazel dependencies. - "exclude": ["external/*"] -}`); - rootBuildContent += '# Allow any ts_project rules in this workspace to reference the config\n' + - '# Note: if you move the tsconfig.json file to a subdirectory, you can add an alias() here instead\n' + - '# so that ts_project rules still use it by default.\n' + - '# See https://www.npmjs.com/package/@bazel/typescript#installation\n' + - 'exports_files(["tsconfig.json"], visibility = ["//:__subpackages__"])\n'; - } - - write('BUILD.bazel', rootBuildContent); - - const yarnInstallCmd = - `# The yarn_install rule runs yarn anytime the package.json or yarn.lock file changes. -# It also extracts and installs any Bazel rules distributed in an npm package. -load("@build_bazel_rules_nodejs//:index.bzl", "yarn_install") -yarn_install( - # Name this npm so that Bazel Label references look like @npm//package - name = "npm", - package_json = "//:package.json", - yarn_lock = "//:yarn.lock", -)`; - - const npmInstallCmd = - `# The npm_install rule runs yarn anytime the package.json or package-lock.json file changes. -# It also extracts any Bazel rules distributed in an npm package. -load("@build_bazel_rules_nodejs//:index.bzl", "npm_install") - -npm_install( - # Name this npm so that Bazel Label references look like @npm//package - name = "npm", - package_json = "//:package.json", - package_lock_json = "//:package-lock.json", -)`; - - let bazelDepsContent = `# Third-party dependencies fetched by Bazel -# Unlike WORKSPACE, the content of this file is unordered. -# We keep them separate to make the WORKSPACE file more maintainable. - -# Install the nodejs "bootstrap" package -# This provides the basic tools for running and packaging nodejs programs in Bazel -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") -def fetch_dependencies(): - http_archive( - name = "build_bazel_rules_nodejs", - sha256 = "94070eff79305be05b7699207fbac5d2608054dd53e6109f7d00d923919ff45a", - urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/5.8.2/rules_nodejs-5.8.2.tar.gz"], - )` - let workspaceContent = `# Bazel workspace created by @bazel/create 0.0.0-PLACEHOLDER - -# Declares that this directory is the root of a Bazel workspace. -# See https://docs.bazel.build/versions/main/build-ref.html#workspace -workspace( - # How this workspace would be referenced with absolute labels from another workspace - name = "${wkspName}", -) - -load("//tools:bazel_deps.bzl", "fetch_dependencies") - -fetch_dependencies() - -load("@build_bazel_rules_nodejs//:repositories.bzl", "build_bazel_rules_nodejs_dependencies") - -build_bazel_rules_nodejs_dependencies() - -${pkgMgr === 'yarn' ? yarnInstallCmd : npmInstallCmd}`; - - write('tools/BUILD.bazel', '# Currently there are no targets in this Bazel package') - write('tools/bazel_deps.bzl', bazelDepsContent); - // Don't name it WORKSPACE.bazel since there's a bug with managed_directories - write('WORKSPACE', workspaceContent); - write('.bazelignore', `\ -# NB: semantics here are not the same as .gitignore -# see https://github.com/bazelbuild/bazel/issues/8106 -# For example, every nested node_modules directory needs to be listed here. -node_modules -dist -bazel-out`); - write( - 'package.json', - JSON.stringify( - { - name: wkspName, - version: '0.1.0', - private: true, - devDependencies, - scripts: { - 'build': 'bazel build //...', - 'test': 'bazel test //...', - } - }, - null, 4)); - write('.gitignore', `\ -.bazelrc.user -dist -bazel-out -node_modules`); - // in the published distribution, this file will appear in the same folder as this file - try { - const rc = require.resolve('./common.bazelrc'); - write('.bazelrc', fs.readFileSync(rc)); - const version = require.resolve('./.bazelversion'); - write('.bazelversion', fs.readFileSync(version)); - } catch (_) { - // but running locally against sources, it's in the root of the repo two directories up - if (fs.existsSync('../../common.bazelrc')) { - write('.bazelrc', fs.readFileSync('../../common.bazelrc')); - } else { - error('ERROR: missing common.bazelrc file, continuing with no bazel settings...'); - } - write('.bazelversion', 'latest'); - } - - log(`Successfully created new Bazel workspace at ${path.resolve(wkspDir)}`); - // TODO: we should probably run the package manager install now - - log(`Next steps: - 1. cd ${wkspDir} - 2. ${pkgMgr} install - 3. ${pkgMgr === 'yarn' ? 'yarn build' : 'npm run build'} - Note that there is nothing to build, so this trivially succeeds. - 4. Add contents to the BUILD.bazel file or create a new BUILD.bazel in a subdirectory. - `); - - return 0; -} - -module.exports = {main}; - -if (require.main === module) { - process.exitCode = main(process.argv.slice(2)); -} diff --git a/packages/create/package.json b/packages/create/package.json deleted file mode 100644 index ac4e63e518..0000000000 --- a/packages/create/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "@bazel/create", - "description": "Create a new Bazel workspace", - "license": "Apache-2.0", - "version": "0.0.0-PLACEHOLDER", - "repository": { - "type" : "git", - "url" : "https://github.com/bazelbuild/rules_nodejs.git", - "directory": "packages/create" - }, - "bugs": { - "url": "https://github.com/bazelbuild/rules_nodejs/issues" - }, - "keywords": [ - "bazel" - ], - "bin": "index.js", - "dependencies": { - "minimist": "1.2.0" - } -} \ No newline at end of file diff --git a/packages/create/test.js b/packages/create/test.js deleted file mode 100644 index 98c5d63254..0000000000 --- a/packages/create/test.js +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Simple node program to test that workspace creation works. - * We don't use a test framework here since dependencies are awkward. - */ -const runfiles = require(process.env['BAZEL_NODE_RUNFILES_HELPER']); -const pkg = runfiles.resolve('build_bazel_rules_nodejs/packages/create/npm_package'); -const fs = require('fs'); -const {main} = require(pkg); - -function fail(...msg) { - console.error(...msg); - throw new Error('test failed'); -} - -function read(path) { - return fs.readFileSync(path, {encoding: 'utf-8'}); -} - -let error, exitCode; -function captureError(...msg) { - error = error + '\n' + msg.join(' '); -} - -exitCode = main([], captureError); -if (error.indexOf('specify the workspace directory') < 0) { - fail('expected', error, 'to tell the user they missed an argument'); -} -if (exitCode != 1) { - fail('should exit 1 on error') -} - -error = ''; -exitCode = main(['has-hyphen'], captureError); -if (error.indexOf('not a valid Bazel workspace') < 0) { - fail('should error when invalid workspace name'); -} -if (exitCode != 1) { - fail('should exit 1 on error') -} - -process.chdir(process.env['TEST_TMPDIR']); -exitCode = main(['some_project'], captureError); -if (exitCode != 0) { - fail('should exit 0 on success') -} -const projFiles = fs.readdirSync('some_project'); -if (projFiles.indexOf('.bazelrc') < 0) { - fail('project should have .bazelrc'); -} -if (projFiles.indexOf('.bazelversion') < 0) { - fail('project should have .bazelversion'); -} -let wkspContent = read('some_project/WORKSPACE'); -if (wkspContent.indexOf('npm_install(') < 0) { - fail('should use npm by default'); -} -// TODO: run bazel in the new directory to verify a build works - -exitCode = main(['configure_pkgMgr', '--packageManager=yarn'], captureError); -if (exitCode != 0) fail('should be success'); -wkspContent = read('configure_pkgMgr/WORKSPACE'); -if (wkspContent.indexOf('yarn_install(') < 0) { - fail('should use yarn when requested'); -} - -process.env['_'] = '/usr/bin/yarn'; -exitCode = main(['default_to_yarn']); -if (exitCode != 0) fail('should be success'); -wkspContent = read('default_to_yarn/WORKSPACE'); -if (wkspContent.indexOf('yarn_install(') < 0) { - fail('should use yarn by default'); -} - -exitCode = main(['use_npm_with_yarn', '--packageManager=npm']); -if (exitCode != 0) fail('should be success'); -wkspContent = read('use_npm_with_yarn/WORKSPACE'); -if (wkspContent.indexOf('npm_install(') < 0) { - fail('should use npm as selected'); -} - -exitCode = main(['neither_yarn_nor_npm', '--packageManager=foo']); -if (exitCode != 1) fail('should exit 1 when selecting neither \'yarn\' nor \'npm\''); -// TODO: run bazel in the new directory to verify a build works - -exitCode = main(['--typescript', 'with_ts'], captureError); -if (exitCode != 0) fail('should be success'); -let pkgContent = read('with_ts/package.json'); - -exitCode = main(['different_workspace_dir', '--workspaceDir=some-other-dir']) -if (exitCode != 0) fail('should be success'); -if (!fs.existsSync('some-other-dir')) fail('should create directory'); - -exitCode = main(['workspace_in_current_dir', '--workspaceDir=.']) -if (exitCode != 0) fail('should be success'); -if (!fs.existsSync('./WORKSPACE')) fail('should create WORKSPACE file in current directory'); - -exitCode = main(['--help'], captureError); -if (exitCode != 0) fail('should be success'); diff --git a/scripts/on-release.js b/scripts/on-release.js index 8c2e4f2ddd..c10bdc2c42 100644 --- a/scripts/on-release.js +++ b/scripts/on-release.js @@ -23,7 +23,7 @@ function computeSha256(path) { const sha256 = computeSha256(artifact); if (starlarkModule == 'build_bazel_rules_nodejs') { - for (const f of ['docs/install.md', 'packages/create/index.js']) { + for (const f of ['docs/install.md']) { shell.sed( '-i', 'download/[0-9\.]*(-(beta|rc).[0-9]+)?/rules_nodejs-[0-9\.]*(-(beta|rc).[0-9]+)?.tar.gz', `download/${version}/rules_nodejs-${version}.tar.gz`, f);