From b1a56385e5659043adc38af53cfd5a131c98b98b Mon Sep 17 00:00:00 2001 From: Jean-Hadrien Chabran Date: Fri, 2 Dec 2022 12:57:14 +0100 Subject: [PATCH] Initial Bazel Setup (#45052) * bazel: initial bazel workspace and rules_js setup * bazel: generate types for schema files * bazel: generate graphql schema file * Fix typo Co-authored-by: Derek Cormier --- .aspect/bazelrc/.gitignore | 1 + .aspect/bazelrc/ci.bazelrc | 95 +++++++++ .aspect/bazelrc/common.bazelrc | 199 +++++++++++++++++++ .aspect/bazelrc/common6.bazelrc | 21 ++ .aspect/bazelrc/javascript.bazelrc | 42 ++++ .bazelignore | 22 ++ .bazelrc | 17 ++ .bazelversion | 1 + .gitignore | 5 +- .npmrc | 10 + .prettierignore | 3 +- BUILD.bazel | 14 ++ WORKSPACE | 75 +++++++ client/shared/src/BUILD.bazel | 26 +++ client/shared/src/generateGraphQlSchema.js | 74 +++++++ client/shared/src/schema/BUILD.bazel | 21 ++ client/shared/src/schema/generateSchema.js | 63 ++++++ client/shared/src/schema/generate_schema.bzl | 28 +++ cmd/frontend/graphqlbackend/BUILD.bazel | 10 + package.json | 1 - pnpm-workspace.yaml | 3 + schema/BUILD.bazel | 31 +++ yarn.lock | 3 +- 23 files changed, 760 insertions(+), 5 deletions(-) create mode 100644 .aspect/bazelrc/.gitignore create mode 100644 .aspect/bazelrc/ci.bazelrc create mode 100644 .aspect/bazelrc/common.bazelrc create mode 100644 .aspect/bazelrc/common6.bazelrc create mode 100644 .aspect/bazelrc/javascript.bazelrc create mode 100644 .bazelignore create mode 100644 .bazelrc create mode 100644 .bazelversion create mode 100644 .npmrc create mode 100644 BUILD.bazel create mode 100644 WORKSPACE create mode 100644 client/shared/src/BUILD.bazel create mode 100644 client/shared/src/generateGraphQlSchema.js create mode 100644 client/shared/src/schema/BUILD.bazel create mode 100644 client/shared/src/schema/generateSchema.js create mode 100644 client/shared/src/schema/generate_schema.bzl create mode 100644 cmd/frontend/graphqlbackend/BUILD.bazel create mode 100644 pnpm-workspace.yaml create mode 100644 schema/BUILD.bazel diff --git a/.aspect/bazelrc/.gitignore b/.aspect/bazelrc/.gitignore new file mode 100644 index 00000000000..74824b01f95 --- /dev/null +++ b/.aspect/bazelrc/.gitignore @@ -0,0 +1 @@ +user.bazelrc diff --git a/.aspect/bazelrc/ci.bazelrc b/.aspect/bazelrc/ci.bazelrc new file mode 100644 index 00000000000..2339b826132 --- /dev/null +++ b/.aspect/bazelrc/ci.bazelrc @@ -0,0 +1,95 @@ +# Aspect recommended Bazel flags for all projects +# Aspect's ".bazelrc flags you should enable" blog post: https://blog.aspect.dev/bazelrc-flags +# Docs for Bazel flags: https://bazel.build/docs/user-manual & https://bazel.build/reference/command-line-reference + +#################################################################################################### +# Performance +# -- +# Miscellaneous settings that improve performance +#################################################################################################### + +# Set this flag to exclude targets that have their timeout set to eternal from running on CI. +# This keeps your CI from being slowed down by individual test targets that should be optimized +# or split up into multiple test targets with sharding or manually. +# Docs: https://bazel.build/docs/user-manual#test-timeout-filters +## build --test_timeout_filters=-eternal + +#################################################################################################### +# Tests +# -- +# Settings that affect tests +#################################################################################################### + +# Set this flag to enable re-tries of failed tests on CI. +# When any test target fails, try one or more times. This applies regardless of whether the "flaky" +# tag appears on the target definition. This is a tradeoff: legitimately failing tests will take +# longer to report, but we can paper over flaky tests that pass most of the time. Not recommended +# for local builds so that the flakiness is observed during development and thus is more likely to +# get fixed. Note that when passing after the first attempt, Bazel will give a special "FLAKY" +# status. +# Docs: https://bazel.build/docs/user-manual#flaky-test-attempts +## build --flaky_test_attempts=2 + +#################################################################################################### +# Output +# -- +# Customize Bazel invocation output for CI +#################################################################################################### + +# Announce all announces command options read from the bazelrc file(s) when starting up at the +# beginning of each Bazel invocation. This is very useful on CI to be able to inspect what Bazel rc +# settings are being applied on each run. +# Docs: https://bazel.build/docs/user-manual#announce-rc +build --announce_rc + +# Add a timestamp to each message generated by Bazel specifying the time at which the message was +# displayed. +# Docs: https://bazel.build/docs/user-manual#show-timestamps +build --show_timestamps + +# Only show progress every 60 seconds on CI. +# Docs: https://bazel.build/reference/command-line-reference#flag--progress_report_interval +build --progress_report_interval=60 + +# Only show progress every 60 seconds on CI. +# https://bazel.build/reference/command-line-reference#flag--show_progress_rate_limit +build --show_progress_rate_limit=60 + +# Don't use cursor controls in its screen output. +# Docs: https://bazel.build/docs/user-manual#curses +build --curses=no + +# Use colors to highlight its output on the screen. Set to `no` if your CI does not display colors. +# Docs: https://bazel.build/docs/user-manual#color +build --color=yes + +# The terminal width in columns. Configure this to override the default value for your CI. +# Docs: https://github.com/bazelbuild/bazel/blob/1af61b21df99edc2fc66939cdf14449c2661f873/src/main/java/com/google/devtools/build/lib/runtime/UiOptions.java#L151 +## build --terminal_columns=80 + +#################################################################################################### +# Remote cache +# -- +# Generic remote cache configuration +#################################################################################################### + +# Only download remote outputs of top level targets to the local machine. +# Docs: https://bazel.build/reference/command-line-reference#flag--remote_download_toplevel +build --remote_download_toplevel + +# The maximum amount of time to wait for remote execution and cache calls. +# https://bazel.build/reference/command-line-reference#flag--remote_timeout +build --remote_timeout=3600 + +# Upload locally executed action results to the remote cache. +# Docs: https://bazel.build/reference/command-line-reference#flag--remote_upload_local_results +build --remote_upload_local_results + +# Fall back to standalone local execution strategy if remote execution fails. If the grpc remote +# cache connection fails, it will fail the build, add this so it falls back to the local cache. +# Docs: https://bazel.build/reference/command-line-reference#flag--remote_local_fallback +build --remote_local_fallback + +# Fixes builds hanging on CI that get the TCP connection closed without sending RST packets. +# Docs: https://bazel.build/reference/command-line-reference#flag--grpc_keepalive_time +build --grpc_keepalive_time=30s diff --git a/.aspect/bazelrc/common.bazelrc b/.aspect/bazelrc/common.bazelrc new file mode 100644 index 00000000000..8f8217682aa --- /dev/null +++ b/.aspect/bazelrc/common.bazelrc @@ -0,0 +1,199 @@ +# Aspect recommended Bazel flags for all projects for all Bazel versions +# Aspect's ".bazelrc flags you should enable" blog post: https://blog.aspect.dev/bazelrc-flags +# Docs for Bazel flags: https://bazel.build/docs/user-manual & https://bazel.build/reference/command-line-reference + +#################################################################################################### +# Debugging +# -- +# Use --config=debug with `bazel test` or `bazel run` to use these settings +#################################################################################################### + +# Stream stdout/stderr output from each test in real-time. +# Docs: https://bazel.build/docs/user-manual#test-output +test:debug --test_output=streamed + +# Run one test at a time. +# Docs: https://bazel.build/reference/command-line-reference#flag--test_strategy +test:debug --test_strategy=exclusive + +# Prevent long running tests from timing out. +# Docs: https://bazel.build/docs/user-manual#test-timeout +test:debug --test_timeout=9999 + +# Always run tests even if they have cached results. +# Docs: https://bazel.build/docs/user-manual#cache-test-results +test:debug --nocache_test_results + +#################################################################################################### +# Performance +# -- +# Miscellaneous settings that improve performance +#################################################################################################### + +# Merkle tree calculations will be memoized to improve the remote cache hit checking speed. The +# memory foot print of the cache is controlled by `--experimental_remote_merkle_tree_cache_size`. +# Docs: https://bazel.build/reference/command-line-reference#flag--experimental_remote_merkle_tree_cache +build --experimental_remote_merkle_tree_cache +query --experimental_remote_merkle_tree_cache + +# The number of Merkle trees to memoize to improve the remote cache hit checking speed. Even though +# the cache is automatically pruned according to Java's handling of soft references, out-of-memory +# errors can occur if set too high. If set to 0 the cache size is unlimited. Optimal value varies +# depending on project's size. +# Docs: https://bazel.build/reference/command-line-reference#flag--experimental_remote_merkle_tree_cache_size +build --experimental_remote_merkle_tree_cache_size=1000 +query --experimental_remote_merkle_tree_cache_size=1000 + +# Speed up all builds by not checking if output files have been modified. Lets you make changes to +# the output tree without triggering a build for local debugging. For example, you can modify +# [rules_js](https://github.com/aspect-build/rules_js) 3rd party npm packages in the output tree +# when local debugging. +# Docs: https://github.com/bazelbuild/bazel/blob/1af61b21df99edc2fc66939cdf14449c2661f873/src/main/java/com/google/devtools/build/lib/pkgcache/PackageOptions.java#L185 +build --noexperimental_check_output_files +fetch --noexperimental_check_output_files +query --noexperimental_check_output_files + +# Don't apply `--noremote_upload_local_results` and `--noremote_accept_cached` to the disk cache. +# If you have both `--noremote_upload_local_results` and `--disk_cache`, then this fixes a bug where +# Bazel doesn't write to the local disk cache as it treats as a remote cache. +# Docs: https://bazel.build/reference/command-line-reference#flag--incompatible_remote_results_ignore_disk +build --incompatible_remote_results_ignore_disk + +# Directories used by sandboxed non-worker execution may be reused to avoid unnecessary setup costs. +# Save time on Sandbox creation and deletion when many of the same kind of action run during the +# build. +# No longer experimental in Bazel 6: https://github.com/bazelbuild/bazel/commit/c1a95501a5611878e5cc43a3cc531f2b9e47835b +# Docs: https://bazel.build/reference/command-line-reference#flag--reuse_sandbox_directories +build --experimental_reuse_sandbox_directories + +# Avoid waiting on `Waiting for build events upload: Build Event Service`. Don't make the user wait +# for uploads, instead allow the bazel command to complete and exit. +# Docs: https://github.com/bazelbuild/bazel/blob/1af61b21df99edc2fc66939cdf14449c2661f873/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceOptions.java#L133 +build --bes_upload_mode=fully_async + +# Do not build runfiles symlink forests for external repositories under +# `.runfiles/wsname/external/repo` (in addition to `.runfiles/repo`). This reduces runfiles & +# sandbox creation times & prevents accidentally depending on this feature which may flip to off by +# default in the future. Note, some rules may fail under this flag, please file issues with the rule +# author. +# Docs: https://bazel.build/reference/command-line-reference#flag--legacy_external_runfiles +build --nolegacy_external_runfiles +run --nolegacy_external_runfiles +test --nolegacy_external_runfiles + +# Some actions are always IO-intensive but require little compute. It's wasteful to put the output +# in the remote cache, it just saturates the network and fills the cache storage causing earlier +# evictions. It's also not worth sending them for remote execution. For actions like PackageTar it's +# faster to just re-run the work locally every time. You'll have to look at an execution log to +# figure out what other action mnemonics you care about. +# https://bazel.build/reference/command-line-reference#flag--modify_execution_info +build --modify_execution_info=PackageTar=+no-remote + +#################################################################################################### +# Correctness +# -- +# Flags that affect correctness +#################################################################################################### + +# Do not upload locally executed action results to the remote cache. This should be the default for +# local builds so local builds cannot poison the remote cache. It should be flipped to +# `--remote_upload_local_results` on CI by using `--bazelrc=.aspect/bazelrc/ci.bazelrc`. +# Docs: https://bazel.build/reference/command-line-reference#flag--remote_upload_local_results +build --noremote_upload_local_results + +# Don't allow network access for build actions in the sandbox. +# Ensures that you don't accidentally make non-hermetic actions/tests which depend on remote +# services. Tag an individual target with `tags=["requires-network"]` to opt-out of the enforcement. +# Docs: https://bazel.build/reference/command-line-reference#flag--sandbox_default_allow_network +build --sandbox_default_allow_network=false +test --sandbox_default_allow_network=false + +# Warn if a test's timeout is significantly longer than the test's actual execution time. Bazel's +# default for test_timeout is medium (5 min), but most tests should instead be short (1 min). While +# a test's timeout should be set such that it is not flaky, a test that has a highly over-generous +# timeout can hide real problems that crop up unexpectedly. For instance, a test that normally +# executes in a minute or two should not have a timeout of ETERNAL or LONG as these are much, much +# too generous. +# Docs: https://bazel.build/docs/user-manual#test-verbose-timeout-warnings +test --test_verbose_timeout_warnings + +# Allow the Bazel server to check directory sources for changes. Ensures that the Bazel server +# notices when a directory changes, if you have a directory listed in the srcs of some target. +# Recommended when using +# [copy_directory](https://github.com/aspect-build/bazel-lib/blob/main/docs/copy_directory.md) and +# [rules_js](https://github.com/aspect-build/rules_js) since npm package are source directories +# inputs to copy_directory actions. +# Docs: https://bazel.build/reference/command-line-reference#flag--host_jvm_args +startup --host_jvm_args=-DBAZEL_TRACK_SOURCE_DIRECTORIES=1 + +# Allow exclusive tests to run in the sandbox. Fixes a bug where Bazel doesn't enable sandboxing for +# tests with `tags=["exclusive"]`. +# Docs: https://bazel.build/reference/command-line-reference#flag--incompatible_exclusive_test_sandboxed +test --incompatible_exclusive_test_sandboxed + +# Use a static value for `PATH` and does not inherit `LD_LIBRARY_PATH`. Doesn't let environment +# variables like `PATH` sneak into the build, which can cause massive cache misses when they change. +# Use `--action_env=ENV_VARIABLE` if you want to inherit specific environment variables from the +# client, but note that doing so can prevent cross-user caching if a shared cache is used. +# Docs: https://bazel.build/reference/command-line-reference#flag--incompatible_strict_action_env +build --incompatible_strict_action_env + +# Propagated tags from a target to the actions' execution requirements. Ensures that tags applied in +# your BUILD file, like `tags=["no-remote"]` get propagated to actions created by the rule. Without +# this option, you rely on rules authors to manually check the tags you passed and apply relevant +# ones to the actions they create. See https://github.com/bazelbuild/bazel/issues/8830 for details. +# Docs: https://bazel.build/reference/command-line-reference#flag--experimental_allow_tags_propagation +build --experimental_allow_tags_propagation +fetch --experimental_allow_tags_propagation +query --experimental_allow_tags_propagation + +# Checking the ctime of input files of an action before uploading it to a remote cache. Prevents +# concurrent local file modification from poisoning the build cache. +# Docs: https://bazel.build/reference/command-line-reference#flag--experimental_guard_against_concurrent_changes +build --experimental_guard_against_concurrent_changes + +# Do not automatically create `__init__.py` files in the runfiles of Python targets. Fixes the wrong +# default that comes from Google's internal monorepo by using `__init__.py` to delimit a Python +# package. Precisely, when a `py_binary` or `py_test` target has `legacy_create_init` set to `auto (the +# default), it is treated as false if and only if this flag is set. See +# https://github.com/bazelbuild/bazel/issues/10076. +# Docs: https://bazel.build/reference/command-line-reference#flag--incompatible_default_to_explicit_init_py +build --incompatible_default_to_explicit_init_py + +#################################################################################################### +# Convenience +# -- +# Miscellaneous convenience settings +#################################################################################################### + +# Attempt to build & test every target whose prerequisites were successfully built. +# Docs: https://bazel.build/docs/user-manual#keep-going +build --keep_going +test --keep_going + +# Output test errors to stderr so users don't have to `cat` or open test failure log files when test +# fail. This makes the log noiser in exchange for reducing the time-to-feedback on test failures for +# users. +# Docs: https://bazel.build/docs/user-manual#test-output +test --test_output=errors + +# Show the output files created by builds that requested more than one target. This helps users +# locate the build outputs in more cases +# Docs: https://bazel.build/docs/user-manual#show-result +build --show_result=20 + +# Bazel picks up host-OS-specific config lines from bazelrc files. For example, if the host OS is +# Linux and you run bazel build, Bazel picks up lines starting with build:linux. Supported OS +# identifiers are `linux`, `macos`, `windows`, `freebsd`, and `openbsd`. Enabling this flag is +# equivalent to using `--config=linux` on Linux, `--config=windows` on Windows, etc. +# Docs: https://bazel.build/reference/command-line-reference#flag--enable_platform_specific_config +build --enable_platform_specific_config +fetch --enable_platform_specific_config +test --enable_platform_specific_config +query --enable_platform_specific_config + +# Output a heap dump if an OOM is thrown during a Bazel invocation (including OOMs due to +# `--experimental_oom_more_eagerly_threshold`). The dump will be written to +# `/.heapdump.hprof`. +# Docs: https://bazel.build/reference/command-line-reference#flag--heap_dump_on_oom +build --heap_dump_on_oom diff --git a/.aspect/bazelrc/common6.bazelrc b/.aspect/bazelrc/common6.bazelrc new file mode 100644 index 00000000000..fbed447bea2 --- /dev/null +++ b/.aspect/bazelrc/common6.bazelrc @@ -0,0 +1,21 @@ +# Aspect recommended Bazel 6 only flags for all projects +# Aspect's ".bazelrc flags you should enable" blog post: https://blog.aspect.dev/bazelrc-flags +# Docs for Bazel flags: https://bazel.build/docs/user-manual & https://bazel.build/reference/command-line-reference + +#################################################################################################### +# Performance +# -- +# Miscellaneous settings that improve performance +#################################################################################################### + +# Speed up all builds by not checking if external repository files have been modified. +# Docs: https://github.com/bazelbuild/bazel/blob/1af61b21df99edc2fc66939cdf14449c2661f873/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java#L244 +build --noexperimental_check_external_repository_files +build --noexperimental_check_external_repository_files +build --noexperimental_check_external_repository_files + +# Directories used by sandboxed non-worker execution may be reused to avoid unnecessary setup costs. +# Save time on Sandbox creation and deletion when many of the same kind of action run during the +# build. +# Docs: https://bazel.build/reference/command-line-reference#flag--reuse_sandbox_directories +build --reuse_sandbox_directories diff --git a/.aspect/bazelrc/javascript.bazelrc b/.aspect/bazelrc/javascript.bazelrc new file mode 100644 index 00000000000..ec14b03af2c --- /dev/null +++ b/.aspect/bazelrc/javascript.bazelrc @@ -0,0 +1,42 @@ +# Aspect recommended Bazel flags for JavaScript projects for all Bazel versions +# Aspect's JavaScript rules: https://github.com/aspect-build/rules_js +# Docs for Bazel flags: https://bazel.build/docs/user-manual & https://bazel.build/reference/command-line-reference +# Docs for Node.js flags: https://nodejs.org/en/docs/guides/debugging-getting-started/#command-line-options + +#################################################################################################### +# Debugging +# -- +# Use --config=debug with `bazel test` or `bazel run` to use these settings +#################################################################################################### + +# Support for debugging Node.js tests. Use bazel run with `--config=debug` to turn on the NodeJS +# inspector agent. The node process will break before user code starts and wait for the debugger to +# connect. Pass the --inspect-brk option to all tests which enables the node inspector agent. See +# https://nodejs.org/de/docs/guides/debugging-getting-started/#command-line-options for more +# details. +# Docs: https://nodejs.org/en/docs/guides/debugging-getting-started/#command-line-options +run:debug -- --node_options=--inspect-brk + +#################################################################################################### +# Correctness +# -- +# Flags that affect correctness +#################################################################################################### + +# Enable runfiles on all platforms. Runfiles are on by default on Linux and MacOS but off on +# Windows. +# +# In general, rules_js and derivate rule sets assume that runfiles are enabled and do not support no +# runfiles case because it does not scale to teach all Node.js tools to use the runfiles manifest. +# +# If you are developing on Windows, you must either run bazel with administrator privileges or +# enable developer mode. If you do not you may hit this error on Windows: +# +# Bazel needs to create symlinks to build the runfiles tree. +# Creating symlinks on Windows requires one of the following: +# 1. Bazel is run with administrator privileges. +# 2. The system version is Windows 10 Creators Update (1703) or later +# and developer mode is enabled. +# +# Docs: https://bazel.build/reference/command-line-reference#flag--enable_runfiles +build --enable_runfiles diff --git a/.bazelignore b/.bazelignore new file mode 100644 index 00000000000..defe581ac1c --- /dev/null +++ b/.bazelignore @@ -0,0 +1,22 @@ +node_modules +client/branded/node_modules +client/build-config/node_modules +client/client-api/node_modules +client/codeintellify/node_modules +client/common/node_modules +client/eslint-plugin-wildcard/node_modules +client/extension-api/node_modules +client/extension-api-types/node_modules +client/http-client/node_modules +client/jetbrains/node_modules +client/observability-client/node_modules +client/observability-server/node_modules +client/search/node_modules +client/search-ui/node_modules +client/shared/node_modules +client/storybook/node_modules +client/template-parser/node_modules +client/web/node_modules +client/wildcard/node_modules + +cmd/symbols/squirrel/test_repos/starlark diff --git a/.bazelrc b/.bazelrc new file mode 100644 index 00000000000..41cfafd39d3 --- /dev/null +++ b/.bazelrc @@ -0,0 +1,17 @@ +# Import Aspect recommended Bazel settings for all projects +import %workspace%/.aspect/bazelrc/common.bazelrc + +# Import Aspect recommended Bazel 6 only settings for all projects +import %workspace%/.aspect/bazelrc/common6.bazelrc + +# Import Aspect recommended Bazel settings for JavaScript projects +import %workspace%/.aspect/bazelrc/javascript.bazelrc + +### YOUR PROJECT SPECIFIC SETTINGS GO HERE ### + +# Load any settings & overrides specific to the current user from `.aspect/bazelrc/user.bazelrc`. +# This file should appear in `.gitignore` so that settings are not shared with team members. This +# should be last statement in this config so the user configuration is able to overwrite flags from +# this file. See https://bazel.build/configure/best-practices#bazelrc-file. +try-import %workspace%/.aspect/bazelrc/user.bazelrc + diff --git a/.bazelversion b/.bazelversion new file mode 100644 index 00000000000..adfd8609ed0 --- /dev/null +++ b/.bazelversion @@ -0,0 +1 @@ +6.0.0rc3 diff --git a/.gitignore b/.gitignore index d5cc2b5d41c..42b6fbc1e1d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # Temporary directory for whatever you want .tmp/ +# Bazel +bazel-* + # Vim *.swp @@ -109,7 +112,7 @@ package-lock.json coverage/ out/ client/shared/src/schema.ts -client/shared/src/schema/* +client/shared/src/schema/*.d.ts puppeteer/ package-lock.json /dist diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000000..136367cdb99 --- /dev/null +++ b/.npmrc @@ -0,0 +1,10 @@ +# Disabling pnpm [hoisting](https://pnpm.io/npmrc#hoist) by setting `hoist=false` is recommended on +# projects using rules_js so that pnpm outside of Bazel lays out a node_modules tree similar to what +# rules_js lays out under Bazel (without a hidden node_modules/.pnpm/node_modules) +hoist=false + +# npm_translate_lock with the yarn.lock file will complain about missing/incorrect peer dependencies. +# Temporarily ignore warnings until we switch to pnpm and can user pnpm.packageExtensions to fix them. +# https://pnpm.io/package_json#pnpmpackageextensions +auto-install-peers=true +strict-peer-dependencies=false diff --git a/.prettierignore b/.prettierignore index 4f2506ab50c..4c77a6aeaf7 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,5 +1,6 @@ .bin/ *.bundle.* +bazel-* client/phabricator/scripts/loader.js client/browser/build **/package.json @@ -16,7 +17,7 @@ vendor/ out/ dist/ client/shared/src/graphqlschema.ts -client/shared/src/schema/ +client/shared/src/schema/*.d.ts ts-node-* testdata .github/* diff --git a/BUILD.bazel b/BUILD.bazel new file mode 100644 index 00000000000..0de006649eb --- /dev/null +++ b/BUILD.bazel @@ -0,0 +1,14 @@ +load("@npm//:defs.bzl", "npm_link_all_packages") +load("@aspect_rules_js//js:defs.bzl", "js_library") + +package(default_visibility = ["//visibility:public"]) + +npm_link_all_packages(name = "node_modules") + +js_library( + name = "prettier_config_js", + srcs = ["prettier.config.js"], + data = [ + "//:node_modules/@sourcegraph/prettierrc", + ], +) diff --git a/WORKSPACE b/WORKSPACE new file mode 100644 index 00000000000..2deb2607968 --- /dev/null +++ b/WORKSPACE @@ -0,0 +1,75 @@ +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "bazel_skylib", + sha256 = "74d544d96f4a5bb630d465ca8bbcfe231e3594e5aae57e1edbf17a6eb3ca2506", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz", + ], +) + +load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") + +bazel_skylib_workspace() + +http_archive( + name = "aspect_rules_js", + sha256 = "f58d7be1bb0e4b7edb7a0085f969900345f5914e4e647b4f0d2650d5252aa87d", + strip_prefix = "rules_js-1.8.0", + url = "https://github.com/aspect-build/rules_js/archive/refs/tags/v1.8.0.tar.gz", +) + +load("@aspect_rules_js//js:repositories.bzl", "rules_js_dependencies") + +rules_js_dependencies() + +http_archive( + name = "rules_nodejs", + sha256 = "50adf0b0ff6fc77d6909a790df02eefbbb3bc2b154ece3406361dda49607a7bd", + urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/5.7.1/rules_nodejs-core-5.7.1.tar.gz"], +) + +load("@rules_nodejs//nodejs:repositories.bzl", "DEFAULT_NODE_VERSION", "nodejs_register_toolchains") + +nodejs_register_toolchains( + name = "nodejs", + node_version = DEFAULT_NODE_VERSION, +) + +load("@aspect_rules_js//npm:npm_import.bzl", "npm_translate_lock") + +npm_translate_lock( + name = "npm", + data = [ + # TODO: can remove these package.json labels after switching to a pnpm lockfile. + "//:client/branded/package.json", + "//:client/build-config/package.json", + "//:client/client-api/package.json", + "//:client/codeintellify/package.json", + "//:client/common/package.json", + "//:client/eslint-plugin-wildcard/package.json", + "//:client/extension-api-types/package.json", + "//:client/extension-api/package.json", + "//:client/http-client/package.json", + "//:client/jetbrains/package.json", + "//:client/observability-client/package.json", + "//:client/observability-server/package.json", + "//:client/search-ui/package.json", + "//:client/search/package.json", + "//:client/shared/package.json", + "//:client/storybook/package.json", + "//:client/template-parser/package.json", + "//:client/web/package.json", + "//:client/wildcard/package.json", + "//:pnpm-workspace.yaml", + ], + npmrc = "//:.npmrc", + package_json = "//:package.json", # TODO: not needed after switch to pnpm_lock + verify_node_modules_ignored = "//:.bazelignore", + yarn_lock = "//:yarn.lock", # TODO: replace with pnpm_lock +) + +load("@npm//:repositories.bzl", "npm_repositories") + +npm_repositories() diff --git a/client/shared/src/BUILD.bazel b/client/shared/src/BUILD.bazel new file mode 100644 index 00000000000..fdb0c1d73ed --- /dev/null +++ b/client/shared/src/BUILD.bazel @@ -0,0 +1,26 @@ +load("@aspect_rules_js//js:defs.bzl", "js_binary", "js_run_binary") + +js_binary( + name = "generate_graphql_schema", + data = [ + "//:node_modules/@gql2ts/from-schema", + "//:node_modules/@gql2ts/language-typescript", + "//:node_modules/glob", + "//:node_modules/graphql", + "//:node_modules/mz", + "//:node_modules/prettier", + "//:prettier_config_js", + "//cmd/frontend/graphqlbackend:graphql_schema", + ], + entry_point = "generateGraphQlSchema.js", +) + +js_run_binary( + name = "graphql_schema", + outs = ["schema.ts"], + args = [ + "schema.ts", + ], + chdir = package_name(), + tool = ":generate_graphql_schema", +) diff --git a/client/shared/src/generateGraphQlSchema.js b/client/shared/src/generateGraphQlSchema.js new file mode 100644 index 00000000000..3b8e157a79f --- /dev/null +++ b/client/shared/src/generateGraphQlSchema.js @@ -0,0 +1,74 @@ +/* eslint no-console: 0 */ + +/** + * Generates the TypeScript types for the GraphQL schema. + * These are used by older code, new code should rely on the new query-specific generated types. + * + * Usage: + * - outputFile - filename to write types to + */ +const path = require('path') + +const { generateNamespace } = require('@gql2ts/from-schema') +const { DEFAULT_OPTIONS, DEFAULT_TYPE_MAP } = require('@gql2ts/language-typescript') +const glob = require('glob') +const { buildSchema, introspectionFromSchema } = require('graphql') +const { mkdir, readFile, writeFile } = require('mz/fs') +const { format, resolveConfig } = require('prettier') + +const GRAPHQL_SCHEMA_GLOB = path.join(__dirname, '../../../cmd/frontend/graphqlbackend/*.graphql') + +async function main(args) { + if (args.length !== 1) { + throw new Error('Usage: ') + } + + const outputFile = args[0] + + const schemaFiles = glob.sync(GRAPHQL_SCHEMA_GLOB) + let combinedSchema = '' + for (const schemaPath of schemaFiles) { + const schemaString = await readFile(schemaPath, 'utf8') + combinedSchema += `\n${schemaString}` + } + const schema = buildSchema(combinedSchema) + + const result = introspectionFromSchema(schema) + + const formatOptions = await resolveConfig(__dirname, { config: __dirname + '/../../../prettier.config.js' }) + const typings = + 'export type ID = string\n' + + 'export type GitObjectID = string\n' + + 'export type DateTime = string\n' + + 'export type JSONCString = string\n' + + '\n' + + generateNamespace( + '', + result, + { + typeMap: { + ...DEFAULT_TYPE_MAP, + ID: 'ID', + GitObjectID: 'GitObjectID', + DateTime: 'DateTime', + JSONCString: 'JSONCString', + }, + }, + { + generateNamespace: (name, interfaces) => interfaces, + interfaceBuilder: (name, body) => `export ${DEFAULT_OPTIONS.interfaceBuilder(name, body)}`, + enumTypeBuilder: (name, values) => + `export ${DEFAULT_OPTIONS.enumTypeBuilder(name, values).replace(/^const enum/, 'enum')}`, + typeBuilder: (name, body) => `export ${DEFAULT_OPTIONS.typeBuilder(name, body)}`, + wrapList: type => `${type}[]`, + postProcessor: code => format(code, { ...formatOptions, parser: 'typescript' }), + } + ) + await mkdir(path.dirname(outputFile), { recursive: true }) + await writeFile(outputFile, typings) +} + +main(process.argv.slice(2)).catch(error => { + console.error(error) + process.exit(1) +}) diff --git a/client/shared/src/schema/BUILD.bazel b/client/shared/src/schema/BUILD.bazel new file mode 100644 index 00000000000..9505a8b1b9a --- /dev/null +++ b/client/shared/src/schema/BUILD.bazel @@ -0,0 +1,21 @@ +load("@aspect_rules_js//js:defs.bzl", "js_binary") +load(":generate_schema.bzl", "generate_schema") + +js_binary( + name = "generate_schema", + data = [ + "//:node_modules/json-schema-to-typescript", + "//:node_modules/mz", + ], + entry_point = "generateSchema.js", +) + +[generate_schema( + name = name, + tool = ":generate_schema", +) for name in [ + "json-schema-draft-07", + "site", + "settings", + "batch_spec", +]] diff --git a/client/shared/src/schema/generateSchema.js b/client/shared/src/schema/generateSchema.js new file mode 100644 index 00000000000..aaaf84c0e28 --- /dev/null +++ b/client/shared/src/schema/generateSchema.js @@ -0,0 +1,63 @@ +/* eslint no-console: 0 */ + +/** + * Generates the TypeScript types for the JSON schemas. + * + * Usage: + * + * schemaName - extensionless name of the schema.json file to generate types for + */ + +const path = require('path') + +const { compile: compileJSONSchema } = require('json-schema-to-typescript') +const { mkdir, readFile, writeFile } = require('mz/fs') + +const schemaDirectory = path.join(__dirname, '..', '..', '..', '..', 'schema') +const outputDirectory = __dirname + +/** + * Allow json-schema-ref-parser to resolve the v7 draft of JSON Schema + * using a local copy of the spec, enabling developers to run/develop Sourcegraph offline + */ +const draftV7resolver = { + order: 1, + read: () => readFile(path.join(schemaDirectory, 'json-schema-draft-07.schema.json')), + canRead: file => file.url === 'http://json-schema.org/draft-07/schema', +} + +async function main(args) { + if (args.length !== 1) { + throw new Error('Usage: ') + } + + const schemaName = args[0] + + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + let schema = await readFile(path.join(schemaDirectory, `${schemaName}.schema.json`), 'utf8') + + // HACK: Rewrite absolute $refs to be relative. They need to be absolute for Monaco to resolve them + // when the schema is in a oneOf (to be merged with extension schemas). + schema = schema.replace(/https:\/\/sourcegraph\.com\/v1\/settings\.schema\.json#\/definitions\//g, '#/definitions/') + + const types = await compileJSONSchema(JSON.parse(schema), 'settings.schema', { + cwd: schemaDirectory, + $refOptions: { + resolve: /** @type {import('json-schema-ref-parser').Options['resolve']} */ ({ + draftV7resolver, + // there should be no reason to make network calls during this process, + // and if there are we've broken env for offline devs/increased dev startup time + http: false, + }), + }, + }) + + await mkdir(outputDirectory, { recursive: true }) + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + await writeFile(path.join(outputDirectory, `${schemaName}.schema.d.ts`), types) +} + +main(process.argv.slice(2)).catch(error => { + console.error(error) + process.exit(1) +}) diff --git a/client/shared/src/schema/generate_schema.bzl b/client/shared/src/schema/generate_schema.bzl new file mode 100644 index 00000000000..aa91920779f --- /dev/null +++ b/client/shared/src/schema/generate_schema.bzl @@ -0,0 +1,28 @@ +load("@aspect_rules_js//js:defs.bzl", "js_run_binary") +load("@bazel_skylib//lib:collections.bzl", "collections") + +def generate_schema(name, tool): + """Generate TypeScript types for a schema. + + Converts the schema with target name //schema: and outputs + .schema.d.ts. + + Args: + name: name of the schema file under schemas/ minus the extension + tool: js_binary that performs the schema generation + """ + js_run_binary( + name = name, + chdir = native.package_name(), + srcs = collections.uniq( + [ + "//schema:%s" % name, + "//schema:json-schema-draft-07", + ], + ), + outs = ["%s.schema.d.ts" % name], + args = [ + name, + ], + tool = tool, + ) diff --git a/cmd/frontend/graphqlbackend/BUILD.bazel b/cmd/frontend/graphqlbackend/BUILD.bazel new file mode 100644 index 00000000000..11d774472bc --- /dev/null +++ b/cmd/frontend/graphqlbackend/BUILD.bazel @@ -0,0 +1,10 @@ +load("@aspect_rules_js//js:defs.bzl", "js_library") + +package(default_visibility = ["//client/shared/src:__pkg__"]) + +js_library( + name = "graphql_schema", + srcs = glob([ + "*.graphql", + ]), +) diff --git a/package.json b/package.json index 4d08b136a71..a55b372e3cd 100644 --- a/package.json +++ b/package.json @@ -126,7 +126,6 @@ "@slack/web-api": "^5.15.0", "@sourcegraph/eslint-config": "0.32.0", "@sourcegraph/eslint-plugin-sourcegraph": "^1.0.5", - "@sourcegraph/eslint-plugin-wildcard": "1.0.0", "@sourcegraph/extension-api-stubs": "^1.6.1", "@sourcegraph/prettierrc": "^3.0.3", "@sourcegraph/stylelint-config": "^1.4.0", diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 00000000000..2df24f5f2b0 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,3 @@ +packages: + - "client/*" + - "dev/release" diff --git a/schema/BUILD.bazel b/schema/BUILD.bazel new file mode 100644 index 00000000000..3084c642a13 --- /dev/null +++ b/schema/BUILD.bazel @@ -0,0 +1,31 @@ +load("@aspect_rules_js//js:defs.bzl", "js_library") + +package(default_visibility = ["//client/shared/src/schema:__pkg__"]) + +js_library( + name = "json-schema-draft-07", + srcs = [ + "json-schema-draft-07.schema.json", + ], +) + +js_library( + name = "settings", + srcs = [ + "settings.schema.json", + ], +) + +js_library( + name = "site", + srcs = [ + "site.schema.json", + ], +) + +js_library( + name = "batch_spec", + srcs = [ + "batch_spec.schema.json", + ], +) diff --git a/yarn.lock b/yarn.lock index a3223e868dc..918c08c5d78 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5426,7 +5426,7 @@ __metadata: languageName: node linkType: hard -"@sourcegraph/eslint-plugin-wildcard@1.0.0, @sourcegraph/eslint-plugin-wildcard@workspace:client/eslint-plugin-wildcard": +"@sourcegraph/eslint-plugin-wildcard@workspace:client/eslint-plugin-wildcard": version: 0.0.0-use.local resolution: "@sourcegraph/eslint-plugin-wildcard@workspace:client/eslint-plugin-wildcard" peerDependencies: @@ -28620,7 +28620,6 @@ pvutils@latest: "@slack/web-api": ^5.15.0 "@sourcegraph/eslint-config": 0.32.0 "@sourcegraph/eslint-plugin-sourcegraph": ^1.0.5 - "@sourcegraph/eslint-plugin-wildcard": 1.0.0 "@sourcegraph/extension-api-classes": ^1.1.0 "@sourcegraph/extension-api-stubs": ^1.6.1 "@sourcegraph/prettierrc": ^3.0.3