diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000000000..cd80114f9371f --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,12 @@ +[build] +target-dir = 'build/target' + +[target.x86_64-unknown-linux-musl] +rustflags = [ + "-C", + "target-feature=-crt-static", +] + +[target.aarch64-unknown-linux-musl] +linker = "aarch64-linux-musl-gcc" +rustflags = ["-C", "target-feature=-crt-static"] \ No newline at end of file diff --git a/.circleci/config.yml b/.circleci/config.yml index efa17f2ab5a27..29acc302240cd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,6 +6,7 @@ version: 2.1 orbs: nx: nrwl/nx@1.6.1 node: circleci/node@5.0.2 + rust: circleci/rust@1.6.0 browser-tools: circleci/browser-tools@1.4.0 # ------------------------- @@ -38,7 +39,7 @@ executors: linux: <<: *defaults docker: - - image: cimg/node:lts-browsers + - image: cimg/rust:1.66.1-browsers resource_class: medium+ macos: @@ -224,6 +225,7 @@ jobs: echo "export NX_RUN_GROUP=\"run-group-macos-$CIRCLE_WORKFLOW_ID\";" >> $BASH_ENV - setup: os: macos + - rust/install - run: name: Run E2E Tests for macOS # FIXME: remove --exclude=e2e-detox once we have a fix for the detox tests diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000000000..e049331bd0328 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,225 @@ +name: publish +env: + DEBUG: napi:* + NX_RUN_GROUP: ${{ github.run_id }}-${{ github.run_attempt }} +on: + release: + types: [published] +jobs: + build: + if: "!contains(github.event.head_commit.message, 'skip ci')" + strategy: + fail-fast: false + matrix: + settings: + - host: macos-latest + target: x86_64-apple-darwin + build: | + yarn nx -- run-many --target=build-native -- --target=x86_64-apple-darwin + - host: windows-latest + build: yarn nx -- run-many --target=build-native -- --target=x86_64-pc-windows-msvc + target: x86_64-pc-windows-msvc + # Windows 32bit (not needed) + # - host: windows-latest + # build: | + # yarn nx -- run-many --target=build-native -- --target=i686-pc-windows-msvc + # target: i686-pc-windows-msvc + - host: ubuntu-latest + target: x86_64-unknown-linux-gnu + docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian + build: |- + set -e && + yarn --version && + yarn nx -- run-many --target=build-native -- --target=x86_64-unknown-linux-gnu + - host: ubuntu-latest + target: x86_64-unknown-linux-musl + docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine + build: set -e && yarn nx -- run-many --target=build-native -- --target=x86_64-unknown-linux-musl + - host: macos-latest + target: aarch64-apple-darwin + build: | + sudo rm -Rf /Library/Developer/CommandLineTools/SDKs/*; + export CC=$(xcrun -f clang); + export CXX=$(xcrun -f clang++); + SYSROOT=$(xcrun --sdk macosx --show-sdk-path); + export CFLAGS="-isysroot $SYSROOT -isystem $SYSROOT"; + yarn nx -- run-many --target=build-native -- --target=aarch64-apple-darwin + - host: ubuntu-latest + target: aarch64-unknown-linux-gnu + docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64 + build: |- + set -e && + yarn --version && + yarn nx -- run-many --target=build-native -- --target=aarch64-unknown-linux-gnu + - host: ubuntu-latest + target: armv7-unknown-linux-gnueabihf + setup: | + sudo apt-get update + sudo apt-get install gcc-arm-linux-gnueabihf -y + build: | + yarn nx -- run-many --target=build-native -- --target=armv7-unknown-linux-gnueabihf + # Android (not needed) + # - host: ubuntu-latest + # target: aarch64-linux-android + # build: | + # yarn nx -- run-many --target=build-native -- --target=aarch64-linux-android + # - host: ubuntu-latest + # target: armv7-linux-androideabi + # build: | + # yarn nx -- run-many --target=build-native -- --target=armv7-linux-androideabi + - host: ubuntu-latest + target: aarch64-unknown-linux-musl + docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine + build: |- + set -e && + rustup target add aarch64-unknown-linux-musl && + yarn nx -- run-many --target=build-native -- --target=aarch64-unknown-linux-musl + - host: windows-latest + target: aarch64-pc-windows-msvc + build: yarn nx -- run-many --target=build-native -- --target=aarch64-pc-windows-msvc + name: stable - ${{ matrix.settings.target }} - node@18 + runs-on: ${{ matrix.settings.host }} + steps: + - uses: actions/checkout@v3 + - name: Setup node + uses: actions/setup-node@v3 + if: ${{ !matrix.settings.docker }} + with: + node-version: 18 + check-latest: true + cache: yarn + - name: Install + uses: dtolnay/rust-toolchain@stable + if: ${{ !matrix.settings.docker }} + with: + targets: ${{ matrix.settings.target }} + - name: Cache cargo + uses: actions/cache@v3 + with: + path: | + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + .cargo-cache + target/ + key: ${{ matrix.settings.target }}-cargo-registry + - uses: goto-bus-stop/setup-zig@v2 + if: ${{ matrix.settings.target == 'armv7-unknown-linux-gnueabihf' }} + with: + version: 0.10.0 + - name: Setup toolchain + run: ${{ matrix.settings.setup }} + if: ${{ matrix.settings.setup }} + shell: bash + - name: Setup node x86 + if: matrix.settings.target == 'i686-pc-windows-msvc' + run: yarn config set supportedArchitectures.cpu "ia32" + shell: bash + - name: Install dependencies + run: yarn install + timeout-minutes: 30 + - name: Setup node x86 + uses: actions/setup-node@v3 + if: matrix.settings.target == 'i686-pc-windows-msvc' + with: + node-version: 18 + check-latest: true + cache: yarn + architecture: x86 + - name: Build in docker + uses: addnab/docker-run-action@v3 + if: ${{ matrix.settings.docker }} + with: + image: ${{ matrix.settings.docker }} + options: --user 0:0 -v ${{ github.workspace }}/.cargo-cache/git/db:/usr/local/cargo/git/db -v ${{ github.workspace }}/.cargo/registry/cache:/usr/local/cargo/registry/cache -v ${{ github.workspace }}/.cargo/registry/index:/usr/local/cargo/registry/index -v ${{ github.workspace }}:/build -w /build + run: ${{ matrix.settings.build }} + - name: Build + run: ${{ matrix.settings.build }} + if: ${{ !matrix.settings.docker }} + shell: bash + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: bindings-${{ matrix.settings.target }} + path: packages/**/*.node + if-no-files-found: error +# build-freebsd: +# runs-on: macos-12 +# name: Build FreeBSD +# steps: +# - uses: actions/checkout@v3 +# - name: Build +# id: build +# uses: vmactions/freebsd-vm@v0 +# env: +# DEBUG: napi:* +# RUSTUP_HOME: /usr/local/rustup +# CARGO_HOME: /usr/local/cargo +# RUSTUP_IO_THREADS: 1 +# with: +# envs: DEBUG RUSTUP_HOME CARGO_HOME RUSTUP_IO_THREADS +# usesh: true +# mem: 3000 +# prepare: | +# pkg install -y -f curl node libnghttp2 +# curl -qL https://www.npmjs.com/install.sh | sh +# npm install --location=global --ignore-scripts yarn +# curl https://sh.rustup.rs -sSf --output rustup.sh +# sh rustup.sh -y --profile minimal --default-toolchain stable +# export PATH="/usr/local/cargo/bin:$PATH" +# echo "~~~~ rustc --version ~~~~" +# rustc --version +# echo "~~~~ node -v ~~~~" +# node -v +# echo "~~~~ yarn --version ~~~~" +# yarn --version +# run: | +# export PATH="/usr/local/cargo/bin:$PATH" +# pwd +# ls -lah +# whoami +# env +# freebsd-version +# yarn install +# yarn nx -- run-many --target=build-native -- --target=x86_64-unknown-freebsd +# strip -x packages/*/*.node +# rm -rf node_modules +# rm -rf target +# rm -rf .yarn/cache +# - name: Upload artifact +# uses: actions/upload-artifact@v3 +# with: +# name: bindings-freebsd +# path: packages/*/*.node +# if-no-files-found: error + publish: + name: Publish + runs-on: ubuntu-latest + needs: + # - build-freebsd + - build + steps: + - uses: actions/checkout@v3 + - name: Setup node + uses: actions/setup-node@v3 + with: + node-version: 18 + check-latest: true + cache: yarn + - name: Install dependencies + run: yarn install + - name: Download all artifacts + uses: actions/download-artifact@v3 + with: + path: artifacts + - name: List artifacts + run: ls -R artifacts + shell: bash + - name: Publish + run: | + git checkout -b publish/$GITHUB_REF_NAME + npm config set //registry.npmjs.org/:_authToken=$NPM_TOKEN + yarn nx-release --local=false $GITHUB_REF_NAME + env: + GH_TOKEN: ${{ github.token }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index 7772e9a465204..1ff4fe39b7fd1 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ CHANGELOG.md # Local dev files .env + +*.node \ No newline at end of file diff --git a/.prettierignore b/.prettierignore index 0b9b14122ae3f..631cbfd4bcce9 100644 --- a/.prettierignore +++ b/.prettierignore @@ -14,6 +14,7 @@ packages/react/src/schematics/**/files/**/*.json packages/jest/src/schematics/**/files/**/*.json packages/**/schematics/**/files/**/*.html packages/**/generators/**/files/**/*.html +packages/nx/src/native/ nx-dev/nx-dev/.next/ nx-dev/nx-dev/public/documentation graph/client/src/assets/environment.js diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 25bd3b19feb08..5e55a4e9a1165 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,6 +37,8 @@ Source code and documentation are included in the top-level folders listed below ## Building the Project +> Nx uses Rust to build native bindings for Node. Please make sure that you have Rust installed via [rustup.rs](https://rustup.rs) + After cloning the project to your machine, to install the dependencies, run: ```bash diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000000000..8814625787449 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,484 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "assert_fs" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d94b2a3f3786ff2996a98afbd6b4e5b7e890d685ccf67577f508ee2342c71cc9" +dependencies = [ + "doc-comment", + "globwalk", + "predicates", + "predicates-core", + "predicates-tree", + "tempfile", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bstr" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45ea9b00a7b3f2988e9a65ad3917e62123c38dba709b666506207be96d1790b" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ctor" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + +[[package]] +name = "either" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" + +[[package]] +name = "fastrand" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +dependencies = [ + "instant", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "globset" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags", + "ignore", + "walkdir", +] + +[[package]] +name = "ignore" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a05705bc64e0b66a806c3740bd6578ea66051b157ec42dc219c785cbf185aef3" +dependencies = [ + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "napi" +version = "2.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "838b5b414a008e75b97edb3c3e6f189034af789a0608686299b149d3b0e66c39" +dependencies = [ + "bitflags", + "ctor", + "napi-sys", + "once_cell", + "thread_local", +] + +[[package]] +name = "napi-build" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "882a73d9ef23e8dc2ebbffb6a6ae2ef467c0f18ac10711e4cc59c5485d41df0e" + +[[package]] +name = "napi-derive" +version = "2.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af4e44e34e70aa61be9036ae652e27c20db5bca80e006be0f482419f6601352a" +dependencies = [ + "convert_case", + "napi-derive-backend", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "napi-derive-backend" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17925fff04b6fa636f8e4b4608cc1a4f1360b64ac8ecbfdb7da1be1dc74f6843" +dependencies = [ + "convert_case", + "once_cell", + "proc-macro2", + "quote", + "regex", + "syn", +] + +[[package]] +name = "napi-sys" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "529671ebfae679f2ce9630b62dd53c72c56b3eb8b2c852e7e2fa91704ff93d67" +dependencies = [ + "libloading", +] + +[[package]] +name = "nx" +version = "0.1.0" +dependencies = [ + "assert_fs", + "crossbeam-channel", + "ignore", + "napi", + "napi-build", + "napi-derive", + "xxhash-rust", +] + +[[package]] +name = "once_cell" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" + +[[package]] +name = "predicates" +version = "2.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" +dependencies = [ + "difflib", + "itertools", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f883590242d3c6fc5bf50299011695fa6590c2c70eac95ee1bdb9a733ad1a2" + +[[package]] +name = "predicates-tree" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54ff541861505aabf6ea722d2131ee980b8276e10a1297b94e896dd8b621850d" +dependencies = [ + "predicates-core", + "termtree", +] + +[[package]] +name = "proc-macro2" +version = "1.0.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "serde" +version = "1.0.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" + +[[package]] +name = "syn" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "termtree" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059e91184749cb66be6dc994f67f182b6d897cb3df74a5bf66b5e709295fd8" + +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + +[[package]] +name = "unicode-ident" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" + +[[package]] +name = "unicode-segmentation" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "xxhash-rust" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "735a71d46c4d68d71d4b24d03fdc2b98e38cea81730595801db779c04fe80d70" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000000000..8e4a982785ef4 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ + +[workspace] +members = ['packages/nx'] + +[profile.release] +lto = true diff --git a/lerna.json b/lerna.json index dd332ec1923c4..498bdf9d13912 100644 --- a/lerna.json +++ b/lerna.json @@ -1,10 +1,6 @@ { - "packages": ["build/packages/*"], + "packages": ["build/packages/*", "build/packages/nx/native-packages/*"], "version": "15.7.0-beta.0", "granularPathspec": false, - "command": { - "publish": { - "graphType": "all" - } - } + "command": { "publish": { "graphType": "all" } } } diff --git a/nx.json b/nx.json index 6bfec4a0a0c5e..d5ee3820d3163 100644 --- a/nx.json +++ b/nx.json @@ -13,8 +13,10 @@ "lint-base", "lint", "build-base", + "build-native", "e2e", "test", + "test-native", "sitemap", "build-storybook" ], @@ -39,15 +41,25 @@ "!{projectRoot}/.storybook/**/*", "!{projectRoot}/**/*.stories.@(js|jsx|ts|tsx|mdx)" ], - "sharedGlobals": ["{workspaceRoot}/babel.config.json"] + "sharedGlobals": ["{workspaceRoot}/babel.config.json"], + "native": [ + "{projectRoot}/**/*.rs", + "{projectRoot}/**/Cargo.*", + { + "runtime": "node -p 'process.platform'" + } + ] }, "targetDefaults": { "build": { "dependsOn": ["build-base"], "inputs": ["production", "^production"] }, + "build-native": { + "inputs": ["native"] + }, "build-base": { - "dependsOn": ["^build-base"], + "dependsOn": ["^build-base", "build-native"], "inputs": ["production", "^production"], "executor": "@nrwl/js:tsc", "options": { @@ -58,7 +70,13 @@ }, "outputs": ["{options.outputPath}"] }, + "test-native": { + "inputs": ["native"], + "executor": "@monodon/rust:test", + "options": {} + }, "test": { + "dependsOn": ["test-native", "build-native", "^build-native"], "inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"], "executor": "@nrwl/jest:jest", "options": { @@ -68,6 +86,7 @@ "outputs": ["{workspaceRoot}/coverage/{projectRoot}"] }, "lint": { + "dependsOn": ["build-native", "^build-native"], "inputs": [ "default", "{workspaceRoot}/.eslintrc.json", @@ -164,5 +183,6 @@ "inputs": ["default", "^production", "{workspaceRoot}/.storybook/**/*"] } }, - "defaultProject": "@nrwl/nx-source" + "defaultProject": "@nrwl/nx-source", + "plugins": ["@monodon/rust"] } diff --git a/package.json b/package.json index 9e48dcfd9e549..f40f379cf8290 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,8 @@ "submit-plugin": "node ./scripts/submit-plugin.js", "prepare": "is-ci || husky install", "echo": "echo 123458", - "root-lint": "nx workspace-lint" + "root-lint": "nx workspace-lint", + "preinstall": "node ./scripts/preinstall.js" }, "devDependencies": { "@angular-devkit/architect": "~0.1501.0", @@ -44,6 +45,8 @@ "@babel/preset-typescript": "^7.15.0", "@cypress/react": "^6.0.0", "@floating-ui/react-dom": "^1.0.1", + "@monodon/rust": "0.4.4", + "@napi-rs/cli": "2.14.0", "@nestjs/cli": "^9.0.0", "@nestjs/common": "^9.0.0", "@nestjs/core": "^9.0.0", diff --git a/packages/eslint-plugin-nx/src/rules/enforce-module-boundaries.spec.ts b/packages/eslint-plugin-nx/src/rules/enforce-module-boundaries.spec.ts index 1136d2e615158..97df03e46da8b 100644 --- a/packages/eslint-plugin-nx/src/rules/enforce-module-boundaries.spec.ts +++ b/packages/eslint-plugin-nx/src/rules/enforce-module-boundaries.spec.ts @@ -1,3 +1,5 @@ +import 'nx/src/utils/testing/mock-fs'; + import type { FileData, ProjectGraph } from '@nrwl/devkit'; import { DependencyType } from '@nrwl/devkit'; import * as parser from '@typescript-eslint/parser'; @@ -9,8 +11,6 @@ import enforceModuleBoundaries, { } from '../../src/rules/enforce-module-boundaries'; import { createProjectRootMappings } from 'nx/src/project-graph/utils/find-project-for-path'; -jest.mock('fs', () => require('memfs').fs); - jest.mock('@nrwl/devkit', () => ({ ...jest.requireActual('@nrwl/devkit'), workspaceRoot: '/root', diff --git a/packages/js/src/utils/package-json/update-package-json.spec.ts b/packages/js/src/utils/package-json/update-package-json.spec.ts index 22eb3b7dbe3c1..12c19c083e438 100644 --- a/packages/js/src/utils/package-json/update-package-json.spec.ts +++ b/packages/js/src/utils/package-json/update-package-json.spec.ts @@ -1,3 +1,5 @@ +import 'nx/src/utils/testing/mock-fs'; + import { getUpdatedPackageJsonContent, updatePackageJson, @@ -10,7 +12,6 @@ import { DependentBuildableProjectNode } from '@nrwl/workspace/src/utilities/bui jest.mock('nx/src/utils/workspace-root', () => ({ workspaceRoot: '/root', })); -jest.mock('fs', () => require('memfs').fs); describe('getUpdatedPackageJsonContent', () => { it('should update fields for commonjs only (default)', () => { diff --git a/packages/next/src/utils/config.spec.ts b/packages/next/src/utils/config.spec.ts index 6f509a5c8701f..79b9a20cfcc31 100644 --- a/packages/next/src/utils/config.spec.ts +++ b/packages/next/src/utils/config.spec.ts @@ -1,3 +1,4 @@ +import 'nx/src/utils/testing/mock-fs'; import { createWebpackConfig, prepareConfig } from './config'; import { NextBuildBuilderOptions } from '@nrwl/next'; import { dirname } from 'path'; @@ -15,7 +16,6 @@ jest.mock('next/dist/server/config', () => ({ webpack: () => ({}), }), })); -jest.mock('fs', () => require('memfs').fs); describe('Next.js webpack config builder', () => { beforeEach(() => { diff --git a/packages/nx/.npmignore b/packages/nx/.npmignore new file mode 100644 index 0000000000000..d001f4a3f9d00 --- /dev/null +++ b/packages/nx/.npmignore @@ -0,0 +1,2 @@ +native-packages/ +/*.node diff --git a/packages/nx/Cargo.toml b/packages/nx/Cargo.toml new file mode 100644 index 0000000000000..5b94c12553843 --- /dev/null +++ b/packages/nx/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = 'nx' +version = '0.1.0' +edition = '2021' + +[dependencies] +xxhash-rust = { version = '0.8.5', features = ['xxh3', 'xxh64'] } +napi = { version = '2.10.2', default-features = false, features = ['napi4'] } +napi-derive = '2.9.3' +ignore = '0.4' +crossbeam-channel = '0.5' + +[lib] +crate-type = ['cdylib'] + +[build-dependencies] +napi-build = '2.0.1' + +[dev-dependencies] +assert_fs = "1.0.10" diff --git a/packages/nx/build.rs b/packages/nx/build.rs new file mode 100644 index 0000000000000..9fc236788932b --- /dev/null +++ b/packages/nx/build.rs @@ -0,0 +1,5 @@ +extern crate napi_build; + +fn main() { + napi_build::setup(); +} diff --git a/packages/nx/native-packages/darwin-arm64/README.md b/packages/nx/native-packages/darwin-arm64/README.md new file mode 100644 index 0000000000000..1a9accd0fce8c --- /dev/null +++ b/packages/nx/native-packages/darwin-arm64/README.md @@ -0,0 +1,3 @@ +# `nx-darwin-arm64` + +This is the **aarch64-apple-darwin** binary for `@nrwl/nx` diff --git a/packages/nx/native-packages/darwin-arm64/package.json b/packages/nx/native-packages/darwin-arm64/package.json new file mode 100644 index 0000000000000..b55c2fe758f68 --- /dev/null +++ b/packages/nx/native-packages/darwin-arm64/package.json @@ -0,0 +1,20 @@ +{ + "name": "@nrwl/nx-darwin-arm64", + "version": "0.0.0", + "os": [ + "darwin" + ], + "cpu": [ + "arm64" + ], + "main": "nx.darwin-arm64.node", + "files": [ + "nx.darwin-arm64.node" + ], + "engines": { + "node": ">= 10" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/nx/native-packages/darwin-x64/README.md b/packages/nx/native-packages/darwin-x64/README.md new file mode 100644 index 0000000000000..bb198003e67c2 --- /dev/null +++ b/packages/nx/native-packages/darwin-x64/README.md @@ -0,0 +1,3 @@ +# `nx-darwin-x64` + +This is the **x86_64-apple-darwin** binary for `@nrwl/nx` diff --git a/packages/nx/native-packages/darwin-x64/package.json b/packages/nx/native-packages/darwin-x64/package.json new file mode 100644 index 0000000000000..869be007d3c98 --- /dev/null +++ b/packages/nx/native-packages/darwin-x64/package.json @@ -0,0 +1,20 @@ +{ + "name": "@nrwl/nx-darwin-x64", + "version": "0.0.0", + "os": [ + "darwin" + ], + "cpu": [ + "x64" + ], + "main": "nx.darwin-x64.node", + "files": [ + "nx.darwin-x64.node" + ], + "engines": { + "node": ">= 10" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/nx/native-packages/linux-arm-gnueabihf/README.md b/packages/nx/native-packages/linux-arm-gnueabihf/README.md new file mode 100644 index 0000000000000..6e9794594c131 --- /dev/null +++ b/packages/nx/native-packages/linux-arm-gnueabihf/README.md @@ -0,0 +1,3 @@ +# `nx-linux-arm-gnueabihf` + +This is the **armv7-unknown-linux-gnueabihf** binary for `@nrwl/nx` diff --git a/packages/nx/native-packages/linux-arm-gnueabihf/package.json b/packages/nx/native-packages/linux-arm-gnueabihf/package.json new file mode 100644 index 0000000000000..65079931d5664 --- /dev/null +++ b/packages/nx/native-packages/linux-arm-gnueabihf/package.json @@ -0,0 +1,20 @@ +{ + "name": "@nrwl/nx-linux-arm-gnueabihf", + "version": "0.0.0", + "os": [ + "linux" + ], + "cpu": [ + "arm" + ], + "main": "nx.linux-arm-gnueabihf.node", + "files": [ + "nx.linux-arm-gnueabihf.node" + ], + "engines": { + "node": ">= 10" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/nx/native-packages/linux-arm64-gnu/README.md b/packages/nx/native-packages/linux-arm64-gnu/README.md new file mode 100644 index 0000000000000..8d1887d7f27bb --- /dev/null +++ b/packages/nx/native-packages/linux-arm64-gnu/README.md @@ -0,0 +1,3 @@ +# `nx-linux-arm64-gnu` + +This is the **aarch64-unknown-linux-gnu** binary for `@nrwl/nx` diff --git a/packages/nx/native-packages/linux-arm64-gnu/package.json b/packages/nx/native-packages/linux-arm64-gnu/package.json new file mode 100644 index 0000000000000..44e7389e01564 --- /dev/null +++ b/packages/nx/native-packages/linux-arm64-gnu/package.json @@ -0,0 +1,23 @@ +{ + "name": "@nrwl/nx-linux-arm64-gnu", + "version": "0.0.0", + "os": [ + "linux" + ], + "cpu": [ + "arm64" + ], + "main": "nx.linux-arm64-gnu.node", + "files": [ + "nx.linux-arm64-gnu.node" + ], + "engines": { + "node": ">= 10" + }, + "publishConfig": { + "access": "public" + }, + "libc": [ + "glibc" + ] +} diff --git a/packages/nx/native-packages/linux-arm64-musl/README.md b/packages/nx/native-packages/linux-arm64-musl/README.md new file mode 100644 index 0000000000000..31788ae4f6bb6 --- /dev/null +++ b/packages/nx/native-packages/linux-arm64-musl/README.md @@ -0,0 +1,3 @@ +# `nx-linux-arm64-musl` + +This is the **aarch64-unknown-linux-musl** binary for `@nrwl/nx` diff --git a/packages/nx/native-packages/linux-arm64-musl/package.json b/packages/nx/native-packages/linux-arm64-musl/package.json new file mode 100644 index 0000000000000..52a89dc3c2acb --- /dev/null +++ b/packages/nx/native-packages/linux-arm64-musl/package.json @@ -0,0 +1,23 @@ +{ + "name": "@nrwl/nx-linux-arm64-musl", + "version": "0.0.0", + "os": [ + "linux" + ], + "cpu": [ + "arm64" + ], + "main": "nx.linux-arm64-musl.node", + "files": [ + "nx.linux-arm64-musl.node" + ], + "engines": { + "node": ">= 10" + }, + "libc": [ + "musl" + ], + "publishConfig": { + "access": "public" + } +} diff --git a/packages/nx/native-packages/linux-x64-gnu/README.md b/packages/nx/native-packages/linux-x64-gnu/README.md new file mode 100644 index 0000000000000..889d3c5a567b0 --- /dev/null +++ b/packages/nx/native-packages/linux-x64-gnu/README.md @@ -0,0 +1,3 @@ +# `nx-linux-x64-gnu` + +This is the **x86_64-unknown-linux-gnu** binary for `@nrwl/nx` diff --git a/packages/nx/native-packages/linux-x64-gnu/package.json b/packages/nx/native-packages/linux-x64-gnu/package.json new file mode 100644 index 0000000000000..2246bc062aad3 --- /dev/null +++ b/packages/nx/native-packages/linux-x64-gnu/package.json @@ -0,0 +1,23 @@ +{ + "name": "@nrwl/nx-linux-x64-gnu", + "version": "0.0.0", + "os": [ + "linux" + ], + "cpu": [ + "x64" + ], + "main": "nx.linux-x64-gnu.node", + "files": [ + "nx.linux-x64-gnu.node" + ], + "engines": { + "node": ">= 10" + }, + "libc": [ + "glibc" + ], + "publishConfig": { + "access": "public" + } +} diff --git a/packages/nx/native-packages/linux-x64-musl/README.md b/packages/nx/native-packages/linux-x64-musl/README.md new file mode 100644 index 0000000000000..d007b0902f69e --- /dev/null +++ b/packages/nx/native-packages/linux-x64-musl/README.md @@ -0,0 +1,3 @@ +# `nx-linux-x64-musl` + +This is the **x86_64-unknown-linux-musl** binary for `@nrwl/nx` diff --git a/packages/nx/native-packages/linux-x64-musl/package.json b/packages/nx/native-packages/linux-x64-musl/package.json new file mode 100644 index 0000000000000..cc240e3fb8119 --- /dev/null +++ b/packages/nx/native-packages/linux-x64-musl/package.json @@ -0,0 +1,23 @@ +{ + "name": "@nrwl/nx-linux-x64-musl", + "version": "0.0.0", + "os": [ + "linux" + ], + "cpu": [ + "x64" + ], + "main": "nx.linux-x64-musl.node", + "files": [ + "nx.linux-x64-musl.node" + ], + "engines": { + "node": ">= 10" + }, + "libc": [ + "musl" + ], + "publishConfig": { + "access": "public" + } +} diff --git a/packages/nx/native-packages/win32-arm64-msvc/README.md b/packages/nx/native-packages/win32-arm64-msvc/README.md new file mode 100644 index 0000000000000..a75b7bcf1f256 --- /dev/null +++ b/packages/nx/native-packages/win32-arm64-msvc/README.md @@ -0,0 +1,3 @@ +# `nx-win32-arm64-msvc` + +This is the **aarch64-pc-windows-msvc** binary for `@nrwl/nx` diff --git a/packages/nx/native-packages/win32-arm64-msvc/package.json b/packages/nx/native-packages/win32-arm64-msvc/package.json new file mode 100644 index 0000000000000..29e791ee7b437 --- /dev/null +++ b/packages/nx/native-packages/win32-arm64-msvc/package.json @@ -0,0 +1,20 @@ +{ + "name": "@nrwl/nx-win32-arm64-msvc", + "version": "0.0.0", + "os": [ + "win32" + ], + "cpu": [ + "arm64" + ], + "main": "nx.win32-arm64-msvc.node", + "files": [ + "nx.win32-arm64-msvc.node" + ], + "engines": { + "node": ">= 10" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/nx/native-packages/win32-x64-msvc/README.md b/packages/nx/native-packages/win32-x64-msvc/README.md new file mode 100644 index 0000000000000..bedb1b96bf4a5 --- /dev/null +++ b/packages/nx/native-packages/win32-x64-msvc/README.md @@ -0,0 +1,3 @@ +# `nx-win32-x64-msvc` + +This is the **x86_64-pc-windows-msvc** binary for `@nrwl/nx` diff --git a/packages/nx/native-packages/win32-x64-msvc/package.json b/packages/nx/native-packages/win32-x64-msvc/package.json new file mode 100644 index 0000000000000..431b2db225636 --- /dev/null +++ b/packages/nx/native-packages/win32-x64-msvc/package.json @@ -0,0 +1,20 @@ +{ + "name": "@nrwl/nx-win32-x64-msvc", + "version": "0.0.0", + "os": [ + "win32" + ], + "cpu": [ + "x64" + ], + "main": "nx.win32-x64-msvc.node", + "files": [ + "nx.win32-x64-msvc.node" + ], + "engines": { + "node": ">= 10" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/nx/package.json b/packages/nx/package.json index d0c9d683f0a40..2622ddd2749ae 100644 --- a/packages/nx/package.json +++ b/packages/nx/package.json @@ -78,6 +78,17 @@ "optional": true } }, + "optionalDependencies": { + "@nrwl/nx-win32-x64-msvc": "*", + "@nrwl/nx-darwin-x64": "*", + "@nrwl/nx-linux-x64-gnu": "*", + "@nrwl/nx-darwin-arm64": "*", + "@nrwl/nx-linux-arm64-gnu": "*", + "@nrwl/nx-linux-arm64-musl": "*", + "@nrwl/nx-win32-arm64-msvc": "*", + "@nrwl/nx-linux-arm-gnueabihf": "*", + "@nrwl/nx-linux-x64-musl": "*" + }, "nx-migrations": { "migrations": "./migrations.json", "packageGroup": [ @@ -116,5 +127,21 @@ "builders": "./executors.json", "publishConfig": { "access": "public" + }, + "napi": { + "name": "nx", + "package": { + "name": "@nrwl/nx" + }, + "triples": { + "additional": [ + "aarch64-apple-darwin", + "aarch64-unknown-linux-gnu", + "aarch64-unknown-linux-musl", + "aarch64-pc-windows-msvc", + "armv7-unknown-linux-gnueabihf", + "x86_64-unknown-linux-musl" + ] + } } } diff --git a/packages/nx/project.json b/packages/nx/project.json index 30077e9e3e390..131d7e97fe1b9 100644 --- a/packages/nx/project.json +++ b/packages/nx/project.json @@ -5,11 +5,28 @@ "projectType": "library", "implicitDependencies": ["graph-client"], "targets": { + "build-native": { + "outputs": ["{projectRoot}/src/native/*.node"], + "executor": "@monodon/rust:napi", + "options": { + "dist": "packages/nx/src/native", + "jsFile": "packages/nx/src/native/index.js", + "release": true + } + }, + "artifacts": { + "command": "yarn napi artifacts -c build/packages/nx/package.json -d ./artifacts --dist build/packages/nx/native-packages" + }, "build-base": { "executor": "@nrwl/js:tsc", "options": { "main": "packages/nx/bin/nx.ts", "assets": [ + { + "input": "packages/nx", + "glob": ".npmignore", + "output": "/" + }, { "input": "packages/nx", "glob": "**/files/**", @@ -46,16 +63,16 @@ } }, "echo": { - "executor": "nx:command", - "options": { - "command": "echo hi" - } + "command": "echo hi" }, "build": { "executor": "nx:run-commands", "outputs": ["{workspaceRoot}/build/packages/nx"], "options": { "commands": [ + { + "command": "node ./scripts/copy-local-native.js nx" + }, { "command": "node ./scripts/copy-graph-client.js" }, @@ -76,6 +93,7 @@ } }, "lint": {}, - "test": {} + "test": {}, + "test-native": {} } } diff --git a/packages/nx/src/hasher/file-hasher.ts b/packages/nx/src/hasher/file-hasher.ts index f84d548a4477d..c11b84cc4e162 100644 --- a/packages/nx/src/hasher/file-hasher.ts +++ b/packages/nx/src/hasher/file-hasher.ts @@ -5,6 +5,7 @@ import { FileHasherBase } from './file-hasher-base'; import { execSync } from 'child_process'; import { existsSync } from 'fs'; import { join } from 'path'; +import { NativeFileHasher } from './native-file-hasher'; function createFileHasher(): FileHasherBase { // special case for unit tests @@ -12,6 +13,10 @@ function createFileHasher(): FileHasherBase { return new NodeBasedFileHasher(); } try { + if (process.env.NX_NATIVE_HASHER) { + return new NativeFileHasher(); + } + execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' }); // we don't use git based hasher when the repo uses git submodules if (!existsSync(join(workspaceRoot, '.git', 'modules'))) { diff --git a/packages/nx/src/hasher/native-file-hasher.ts b/packages/nx/src/hasher/native-file-hasher.ts new file mode 100644 index 0000000000000..5c9cffff07bef --- /dev/null +++ b/packages/nx/src/hasher/native-file-hasher.ts @@ -0,0 +1,34 @@ +import { FileHasherBase } from './file-hasher-base'; +import { performance } from 'perf_hooks'; +import { hashFile, hashFiles } from '../native'; +import { workspaceRoot } from '../utils/app-root'; + +export class NativeFileHasher extends FileHasherBase { + async init(): Promise { + performance.mark('init hashing:start'); + this.clear(); + const filesObject = hashFiles(workspaceRoot); + this.fileHashes = new Map(Object.entries(filesObject)); + + performance.mark('init hashing:end'); + performance.measure( + 'init hashing', + 'init hashing:start', + 'init hashing:end' + ); + } + + async hashFiles(files: string[]): Promise> { + const r = new Map(); + + for (let f of files) { + r.set(f, this.hashFile(f)); + } + + return r; + } + + hashFile(path: string): string { + return hashFile(path).hash; + } +} diff --git a/packages/nx/src/lib.rs b/packages/nx/src/lib.rs new file mode 100644 index 0000000000000..faac2c699cb48 --- /dev/null +++ b/packages/nx/src/lib.rs @@ -0,0 +1,5 @@ +// add all the napi macros globally +#[macro_use] +extern crate napi_derive; + +pub mod native; diff --git a/packages/nx/src/native/index.d.ts b/packages/nx/src/native/index.d.ts new file mode 100644 index 0000000000000..03c8f33809c97 --- /dev/null +++ b/packages/nx/src/native/index.d.ts @@ -0,0 +1,11 @@ +/* tslint:disable */ +/* eslint-disable */ + +/* auto-generated by NAPI-RS */ + +export interface FileData { + file: string + hash: string +} +export function hashFile(file: string): FileData | null +export function hashFiles(workspaceRoot: string): Record diff --git a/packages/nx/src/native/index.js b/packages/nx/src/native/index.js new file mode 100644 index 0000000000000..cd11e59a88059 --- /dev/null +++ b/packages/nx/src/native/index.js @@ -0,0 +1,252 @@ +const { existsSync, readFileSync } = require('fs') +const { join } = require('path') + +const { platform, arch } = process + +let nativeBinding = null +let localFileExisted = false +let loadError = null + +function isMusl() { + // For Node 10 + if (!process.report || typeof process.report.getReport !== 'function') { + try { + const lddPath = require('child_process').execSync('which ldd').toString().trim(); + return readFileSync(lddPath, 'utf8').includes('musl') + } catch (e) { + return true + } + } else { + const { glibcVersionRuntime } = process.report.getReport().header + return !glibcVersionRuntime + } +} + +switch (platform) { + case 'android': + switch (arch) { + case 'arm64': + localFileExisted = existsSync(join(__dirname, 'nx.android-arm64.node')) + try { + if (localFileExisted) { + nativeBinding = require('./nx.android-arm64.node') + } else { + nativeBinding = require('@nrwl/nx-android-arm64') + } + } catch (e) { + loadError = e + } + break + case 'arm': + localFileExisted = existsSync(join(__dirname, 'nx.android-arm-eabi.node')) + try { + if (localFileExisted) { + nativeBinding = require('./nx.android-arm-eabi.node') + } else { + nativeBinding = require('@nrwl/nx-android-arm-eabi') + } + } catch (e) { + loadError = e + } + break + default: + throw new Error(`Unsupported architecture on Android ${arch}`) + } + break + case 'win32': + switch (arch) { + case 'x64': + localFileExisted = existsSync( + join(__dirname, 'nx.win32-x64-msvc.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./nx.win32-x64-msvc.node') + } else { + nativeBinding = require('@nrwl/nx-win32-x64-msvc') + } + } catch (e) { + loadError = e + } + break + case 'ia32': + localFileExisted = existsSync( + join(__dirname, 'nx.win32-ia32-msvc.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./nx.win32-ia32-msvc.node') + } else { + nativeBinding = require('@nrwl/nx-win32-ia32-msvc') + } + } catch (e) { + loadError = e + } + break + case 'arm64': + localFileExisted = existsSync( + join(__dirname, 'nx.win32-arm64-msvc.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./nx.win32-arm64-msvc.node') + } else { + nativeBinding = require('@nrwl/nx-win32-arm64-msvc') + } + } catch (e) { + loadError = e + } + break + default: + throw new Error(`Unsupported architecture on Windows: ${arch}`) + } + break + case 'darwin': + localFileExisted = existsSync(join(__dirname, 'nx.darwin-universal.node')) + try { + if (localFileExisted) { + nativeBinding = require('./nx.darwin-universal.node') + } else { + nativeBinding = require('@nrwl/nx-darwin-universal') + } + break + } catch {} + switch (arch) { + case 'x64': + localFileExisted = existsSync(join(__dirname, 'nx.darwin-x64.node')) + try { + if (localFileExisted) { + nativeBinding = require('./nx.darwin-x64.node') + } else { + nativeBinding = require('@nrwl/nx-darwin-x64') + } + } catch (e) { + loadError = e + } + break + case 'arm64': + localFileExisted = existsSync( + join(__dirname, 'nx.darwin-arm64.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./nx.darwin-arm64.node') + } else { + nativeBinding = require('@nrwl/nx-darwin-arm64') + } + } catch (e) { + loadError = e + } + break + default: + throw new Error(`Unsupported architecture on macOS: ${arch}`) + } + break + case 'freebsd': + if (arch !== 'x64') { + throw new Error(`Unsupported architecture on FreeBSD: ${arch}`) + } + localFileExisted = existsSync(join(__dirname, 'nx.freebsd-x64.node')) + try { + if (localFileExisted) { + nativeBinding = require('./nx.freebsd-x64.node') + } else { + nativeBinding = require('@nrwl/nx-freebsd-x64') + } + } catch (e) { + loadError = e + } + break + case 'linux': + switch (arch) { + case 'x64': + if (isMusl()) { + localFileExisted = existsSync( + join(__dirname, 'nx.linux-x64-musl.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./nx.linux-x64-musl.node') + } else { + nativeBinding = require('@nrwl/nx-linux-x64-musl') + } + } catch (e) { + loadError = e + } + } else { + localFileExisted = existsSync( + join(__dirname, 'nx.linux-x64-gnu.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./nx.linux-x64-gnu.node') + } else { + nativeBinding = require('@nrwl/nx-linux-x64-gnu') + } + } catch (e) { + loadError = e + } + } + break + case 'arm64': + if (isMusl()) { + localFileExisted = existsSync( + join(__dirname, 'nx.linux-arm64-musl.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./nx.linux-arm64-musl.node') + } else { + nativeBinding = require('@nrwl/nx-linux-arm64-musl') + } + } catch (e) { + loadError = e + } + } else { + localFileExisted = existsSync( + join(__dirname, 'nx.linux-arm64-gnu.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./nx.linux-arm64-gnu.node') + } else { + nativeBinding = require('@nrwl/nx-linux-arm64-gnu') + } + } catch (e) { + loadError = e + } + } + break + case 'arm': + localFileExisted = existsSync( + join(__dirname, 'nx.linux-arm-gnueabihf.node') + ) + try { + if (localFileExisted) { + nativeBinding = require('./nx.linux-arm-gnueabihf.node') + } else { + nativeBinding = require('@nrwl/nx-linux-arm-gnueabihf') + } + } catch (e) { + loadError = e + } + break + default: + throw new Error(`Unsupported architecture on Linux: ${arch}`) + } + break + default: + throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`) +} + +if (!nativeBinding) { + if (loadError) { + throw loadError + } + throw new Error(`Failed to load native binding`) +} + +const { hashFile, hashFiles } = nativeBinding + +module.exports.hashFile = hashFile +module.exports.hashFiles = hashFiles diff --git a/packages/nx/src/native/mod.rs b/packages/nx/src/native/mod.rs new file mode 100644 index 0000000000000..88c58ee6281f0 --- /dev/null +++ b/packages/nx/src/native/mod.rs @@ -0,0 +1 @@ +pub mod native_hasher; diff --git a/packages/nx/src/native/native_hasher.rs b/packages/nx/src/native/native_hasher.rs new file mode 100644 index 0000000000000..282cd379ef76f --- /dev/null +++ b/packages/nx/src/native/native_hasher.rs @@ -0,0 +1,167 @@ +#![allow(unused)] + +use crossbeam_channel::unbounded; +use ignore::WalkBuilder; +use std::collections::HashMap; +use std::thread::{self, available_parallelism}; +use xxhash_rust::xxh3; + +type FileHashes = HashMap; + +#[napi(object)] +pub struct FileData { + pub file: String, + pub hash: String, +} + +#[napi] +fn hash_file(file: String) -> Option { + let Ok(content) = std::fs::read(&file) else { + return None; + }; + + let hash = xxh3::xxh3_64(&content).to_string(); + + Some(FileData { hash, file }) +} + +#[napi] +fn hash_files(workspace_root: String) -> HashMap { + let mut walker = WalkBuilder::new(&workspace_root); + let workspace_root = workspace_root + "/"; + walker.add_ignore(workspace_root.clone() + ".nxignore"); + + let git_folder = workspace_root.clone() + ".git"; + // We should make sure to always ignore node_modules + let node_folder = workspace_root.clone() + "node_modules"; + walker.filter_entry(move |entry| { + !(entry.path().starts_with(&git_folder) || entry.path().starts_with(&node_folder)) + }); + + // dot files are hidden by default. We want to make sure we include those here + walker.hidden(false); + + let (sender, reciever) = unbounded::<(String, Vec)>(); + + let receiver_thread = thread::spawn(move || { + let mut collection: HashMap = HashMap::new(); + for (path, content) in reciever { + collection.insert(path, xxh3::xxh3_64(&content).to_string()); + } + collection + }); + + let cpus = available_parallelism().map_or(2, |n| n.get()) - 1; + + walker.threads(cpus).build_parallel().run(|| { + let tx = sender.clone(); + let workspace_root = workspace_root.clone(); + Box::new(move |entry| { + use ignore::WalkState::*; + + #[rustfmt::skip] + let Ok(dir_entry) = entry else { + return Continue; + }; + + let Ok(content) = std::fs::read(dir_entry.path()) else { + return Continue; + }; + + let file_path = dir_entry.path().display().to_string(); + let Some(file_path) = file_path.strip_prefix(&workspace_root) else { + return Continue; + }; + + tx.send((file_path.to_string(), content)).ok(); + + Continue + }) + }); + + drop(sender); + receiver_thread.join().unwrap() +} + +#[cfg(test)] +mod tests { + use super::*; + use assert_fs::prelude::*; + use assert_fs::TempDir; + + /// + /// Setup a temporary directory to do testing in + /// + fn setup_fs() -> TempDir { + let temp = TempDir::new().unwrap(); + temp.child("test.txt").write_str("content").unwrap(); + temp.child("foo.txt").write_str("content1").unwrap(); + temp.child("bar.txt").write_str("content2").unwrap(); + temp.child("baz") + .child("qux.txt") + .write_str("content@qux") + .unwrap(); + temp.child("node_modules") + .child("node-module-dep") + .write_str("content") + .unwrap(); + temp + } + + #[test] + fn it_hashes_a_file() { + // handle non existent files + let content = hash_file("".into()); + assert!(content.is_none()); + + let temp_dir = setup_fs(); + + let test_file_path = temp_dir.display().to_string() + "/test.txt"; + let content = hash_file(test_file_path); + + assert_eq!(content.unwrap().hash, "6193209363630369380"); + } + + #[test] + fn it_hashes_a_directory() { + // handle empty workspaces + let content = hash_files("/does/not/exist".into()); + assert!(content.is_empty()); + + let temp_dir = setup_fs(); + + let content = hash_files(temp_dir.display().to_string()); + // println!("{:?}", content); + assert_eq!( + content, + HashMap::from([ + ("baz/qux.txt".into(), "8039819779822413286".into()), + ("foo.txt".into(), "8455857314690418558".into()), + ("test.txt".into(), "6193209363630369380".into()), + ("bar.txt".into(), "1707056588989152788".into()), + ]) + ); + } + + #[test] + fn handles_nx_ignore() { + let temp_dir = setup_fs(); + + // add nxignore file with baz/ + temp_dir.child(".nxignore").write_str("baz/").unwrap(); + + let content = hash_files(temp_dir.display().to_string()); + assert_eq!( + content, + HashMap::from([ + ("foo.txt".into(), "8455857314690418558".into()), + ("test.txt".into(), "6193209363630369380".into()), + ("bar.txt".into(), "1707056588989152788".into()), + (".nxignore".into(), "5786346484289078730".into()) + ]) + ); + } +} +// + +// diff --git a/packages/nx/src/native/tests/native.spec.ts b/packages/nx/src/native/tests/native.spec.ts new file mode 100644 index 0000000000000..9a029d1c305ba --- /dev/null +++ b/packages/nx/src/native/tests/native.spec.ts @@ -0,0 +1,22 @@ +import { hashFile } from '../index'; + +import { tmpdir } from 'os'; +import { mkdtemp, writeFile } from 'fs-extra'; +import { join } from 'path'; + +describe('native', () => { + it('should hash', async () => { + expect(hashFile).toBeDefined(); + + const tempDirPath = await mkdtemp(join(tmpdir(), 'native-test')); + const tempFilePath = join(tempDirPath, 'temp.txt'); + await writeFile(tempFilePath, 'content'); + + expect(hashFile(tempFilePath).hash).toBe('6193209363630369380'); + }); + + it('should create an instance of NativeHasher', () => { + // const nativeHasher = new NativeFileHasher('/root'); + // expect(nativeHasher instanceof NativeFileHasher).toBe(true); + }); +}); diff --git a/packages/nx/src/project-graph/build-dependencies/explicit-package-json-dependencies.spec.ts b/packages/nx/src/project-graph/build-dependencies/explicit-package-json-dependencies.spec.ts index bca813013ef3f..1e7745c2a18ca 100644 --- a/packages/nx/src/project-graph/build-dependencies/explicit-package-json-dependencies.spec.ts +++ b/packages/nx/src/project-graph/build-dependencies/explicit-package-json-dependencies.spec.ts @@ -1,3 +1,4 @@ +import '../../utils/testing/mock-fs'; import { buildExplicitPackageJsonDependencies } from './explicit-package-json-dependencies'; import { vol } from 'memfs'; import { createProjectFileMap } from '../file-map-utils'; @@ -8,7 +9,6 @@ import { } from '../../config/project-graph'; import { ProjectGraphBuilder } from '../project-graph-builder'; -jest.mock('fs', () => require('memfs').fs); jest.mock('nx/src/utils/workspace-root', () => ({ workspaceRoot: '/root', })); diff --git a/packages/nx/src/project-graph/build-dependencies/explicit-project-dependencies.spec.ts b/packages/nx/src/project-graph/build-dependencies/explicit-project-dependencies.spec.ts index 4c19ac61ee463..017e2ea0aca37 100644 --- a/packages/nx/src/project-graph/build-dependencies/explicit-project-dependencies.spec.ts +++ b/packages/nx/src/project-graph/build-dependencies/explicit-project-dependencies.spec.ts @@ -1,10 +1,10 @@ +import '../../utils/testing/mock-fs'; import { vol } from 'memfs'; import { defaultFileHasher } from '../../hasher/file-hasher'; import { createProjectFileMap } from '../file-map-utils'; import { ProjectGraphBuilder } from '../project-graph-builder'; import { buildExplicitTypeScriptDependencies } from './explicit-project-dependencies'; -jest.mock('fs', () => require('memfs').fs); jest.mock('nx/src/utils/workspace-root', () => ({ workspaceRoot: '/root', })); diff --git a/packages/nx/src/project-graph/build-project-graph.spec.ts b/packages/nx/src/project-graph/build-project-graph.spec.ts index 7e585b922a4dc..5350594f70bb3 100644 --- a/packages/nx/src/project-graph/build-project-graph.spec.ts +++ b/packages/nx/src/project-graph/build-project-graph.spec.ts @@ -1,7 +1,8 @@ +import '../utils/testing/mock-fs'; + import { vol, fs } from 'memfs'; -jest.mock('fs', () => require('memfs').fs); -jest.mock('../utils/workspace-root', () => ({ +jest.mock('nx/src/utils/workspace-root', () => ({ workspaceRoot: '/root', })); import { buildProjectGraph } from './build-project-graph'; diff --git a/packages/nx/src/utils/testing/mock-fs.ts b/packages/nx/src/utils/testing/mock-fs.ts new file mode 100644 index 0000000000000..6e6e96ea7c030 --- /dev/null +++ b/packages/nx/src/utils/testing/mock-fs.ts @@ -0,0 +1,14 @@ +// @ts-ignore +jest.mock('fs', (): Partial => { + const mockFs = require('memfs').fs; + return { + ...mockFs, + existsSync(path: string) { + if (path.endsWith('.node')) { + return true; + } else { + return mockFs.existsSync(path); + } + }, + }; +}); diff --git a/scripts/copy-local-native.js b/scripts/copy-local-native.js new file mode 100644 index 0000000000000..1f27c716a3141 --- /dev/null +++ b/scripts/copy-local-native.js @@ -0,0 +1,11 @@ +//@ts-check +const fs = require('fs'); +const glob = require('fast-glob'); + +const p = process.argv[2]; + +const nativeFiles = glob.sync(`packages/${p}/**/*.node`); + +nativeFiles.forEach((file) => { + fs.copyFileSync(file, `build/${file}`); +}); diff --git a/scripts/depcheck/missing.ts b/scripts/depcheck/missing.ts index 4508309641649..bcf5cd30c8184 100644 --- a/scripts/depcheck/missing.ts +++ b/scripts/depcheck/missing.ts @@ -132,6 +132,21 @@ const IGNORE_MATCHES_IN_PACKAGE = { '@nrwl/angular', '@nestjs/cli', // nx init nest makes use of nestjs cli (which should be available in NestJS CLI app) to parse the nest-cli.json file 'ts-node', // We *may* fall back on ts-node, but we want to encourage the use of @swc-node instead so we don't explicitly list ts-node as an optional dep + '@nrwl/nx-android-arm-eabi', // native optional deps + '@nrwl/nx-android-arm64', // native optional deps + '@nrwl/nx-darwin-arm64', // native optional deps + '@nrwl/nx-darwin-universal', // native optional deps + '@nrwl/nx-darwin-x64', // native optional deps + '@nrwl/nx-freebsd-x64', // native optional deps + '@nrwl/nx-linux-arm-gnueabihf', // native optional deps + '@nrwl/nx-linux-arm64-gnu', // native optional deps + '@nrwl/nx-linux-arm64-musl', // native optional deps + '@nrwl/nx-linux-x64-gnu', // native optional deps + '@nrwl/nx-linux-x64-musl', // native optional deps + '@nrwl/nx-win32-arm64-msvc', // native optional deps + '@nrwl/nx-win32-ia32-msvc', // native optional deps + '@nrwl/nx-win32-x64-msvc', // native optional deps + 'memfs', // used in mock for handling .node files in tests ], web: [ // we don't want to bloat the install of @nrwl/web by including @swc/core and swc-loader as a dependency. diff --git a/scripts/nx-release.ts b/scripts/nx-release.ts index 663a7395e41cf..9c07ed372ec3e 100755 --- a/scripts/nx-release.ts +++ b/scripts/nx-release.ts @@ -5,9 +5,14 @@ import { existsSync, readFileSync, writeFileSync } from 'fs'; import { URL } from 'url'; import { join } from 'path'; +import { parse } from 'semver'; + import * as version from '@lerna/version/index'; import * as publish from '@lerna/publish/index'; +const lernaJsonPath = join(__dirname, '../lerna.json'); +const originalLernaJson = readFileSync(lernaJsonPath); + function hideFromGitIndex(uncommittedFiles: string[]) { execSync(`git update-index --assume-unchanged ${uncommittedFiles.join(' ')}`); @@ -19,23 +24,35 @@ function hideFromGitIndex(uncommittedFiles: string[]) { (async () => { const options = parseArgs(); - if (!options.local && !options.force) { - console.log('Authenticating to NPM'); - execSync('npm adduser', { - stdio: [0, 1, 2], - }); - } if (options.clearLocalRegistry) { execSync('yarn local-registry clear'); } + const currentLatestVersion = execSync('npm view nx version') + .toString() + .trim(); + + const parsedVersion = parse(options.version); + const parsedCurrentLatestVersion = parse(currentLatestVersion); + + const distTag = + parsedVersion?.prerelease.length > 0 + ? 'next' + : parsedVersion?.major < parsedCurrentLatestVersion.major + ? 'previous' + : 'latest'; + const buildCommand = 'yarn build'; console.log(`> ${buildCommand}`); execSync(buildCommand, { stdio: [0, 1, 2], }); + if (options.local) { + updateLernaJsonVersion(currentLatestVersion); + } + if (options.local) { // Force all projects to be not private const projects = JSON.parse( @@ -54,21 +71,26 @@ function hideFromGitIndex(uncommittedFiles: string[]) { } } + if (!options.local && process.env.NPM_TOKEN) { + execSync('npx nx run-many --target=artifacts', { + stdio: [0, 1, 2], + }); + } + const versionOptions = { bump: options.version ? options.version : undefined, conventionalCommits: true, conventionalPrerelease: options.tag === 'next', preid: options.preid, forcePublish: true, - createRelease: options.tag !== 'next' ? 'github' : undefined, - noChangelog: options.tag === 'next', + createRelease: 'github', tagVersionPrefix: '', exact: true, gitRemote: options.gitRemote, - gitTagVersion: options.tag !== 'next', + gitTagVersion: !process.env.NPM_TOKEN, message: 'chore(misc): publish %v', loglevel: options.loglevel ?? 'info', - yes: false, + yes: !!process.env.NPM_TOKEN, }; if (options.local) { @@ -80,12 +102,6 @@ function hideFromGitIndex(uncommittedFiles: string[]) { versionOptions.bump = options.version ? options.version : 'minor'; } - const lernaJsonPath = join(__dirname, '../lerna.json'); - let originalLernaJson: Buffer | undefined; - - if (options.local || options.tag === 'next') { - originalLernaJson = readFileSync(lernaJsonPath); - } if (options.local) { /** * Hide changes from Lerna @@ -104,18 +120,25 @@ function hideFromGitIndex(uncommittedFiles: string[]) { const publishOptions: Record = { gitReset: false, - distTag: options.tag, + distTag: distTag, }; - if (!options.skipPublish) { + if (!options.local && !process.env.NPM_TOKEN) { + execSync('git status --ahead-behind'); + + await version(versionOptions); + console.log( + 'Check github: https://github.com/nrwl/nx/actions/workflows/publish.yml' + ); + } else if (!options.skipPublish) { await publish({ ...versionOptions, ...publishOptions }); } else { await version(versionOptions); console.warn('Not Publishing because --dryRun was passed'); } - if (originalLernaJson) { - writeFileSync(lernaJsonPath, originalLernaJson); + if (options.local) { + restoreOriginalLernaJson(); } })(); @@ -161,17 +184,6 @@ function parseArgs() { 'Alternate git remote name to publish tags to (useful for testing changelog)', default: 'origin', }) - .option('tag', { - type: 'string', - description: 'NPM Tag', - choices: ['next', 'latest', 'previous'], - }) - .option('preid', { - type: 'string', - description: 'The kind of prerelease tag. (1.0.0-[preid].0)', - choices: ['alpha', 'beta', 'rc'], - default: 'beta', - }) .option('loglevel', { type: 'string', description: 'Log Level', @@ -182,23 +194,23 @@ function parseArgs() { `By default, this will locally publish a minor version bump as latest. Great for local development. Most developers should only need this.` ) .example( - '$0 --local false', - `This will really publish a new beta version to npm as next. The version is inferred by the changes.` + '$0 --local false 2.3.4-beta.0', + `This will really publish a new version to npm as next.` ) .example( - '$0 --local false --tag latest', - `This will really publish a new stable version to npm as latest, tag, commit, push, and create a release on GitHub.` + '$0 --local false 2.3.4', + `Given the current latest major version on npm is 2, this will really publish a new version to npm as latest.` ) .example( - '$0 --local false --preid rc', - `This will really publish a new rc version to npm as next.` + '$0 --local false 1.3.4-beta.0', + `Given the current latest major version on npm is 2, this will really publish a new version to npm as previous.` ) .group( ['local', 'clearLocalRegistry'], 'Local Publishing Options for most developers' ) .group( - ['preid', 'tag', 'gitRemote', 'force'], + ['gitRemote', 'force'], 'Real Publishing Options for actually publishing to NPM' ) .check((args) => { @@ -228,6 +240,18 @@ function parseArgs() { return parsedArgs; } +function updateLernaJsonVersion(version: string) { + const json = JSON.parse(readFileSync(lernaJsonPath).toString()); + + json.version = version; + + writeFileSync(lernaJsonPath, JSON.stringify(json)); +} + +function restoreOriginalLernaJson() { + writeFileSync(lernaJsonPath, originalLernaJson); +} + function getRegistry() { return new URL(execSync('npm config get registry').toString().trim()); } diff --git a/scripts/preinstall.js b/scripts/preinstall.js new file mode 100644 index 0000000000000..4de15727d3289 --- /dev/null +++ b/scripts/preinstall.js @@ -0,0 +1,31 @@ +/* +This pre-install script will check that the necessary dependencies are installed +Checks for: + * Node 18+ + * Cargo + */ + +if (process.env.CI) { + process.exit(0); +} + +const childProcess = require('child_process'); + +// Check node version +const nodeVersion = process.version.slice(1).split('.'); +if (+nodeVersion[0] < 18) { + console.error( + 'Please make sure that your installed Node version is greater than v18' + ); + process.exit(1); +} + +// Check for cargo +try { + childProcess.execSync('cargo --version'); +} catch { + console.error( + 'Could not find Cargo. Please make sure that Cargo and Rust is installed with https://rustup.rs' + ); + process.exit(1); +} diff --git a/tsconfig.base.json b/tsconfig.base.json index 69fc5afe50ef2..6a85841df63c8 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -15,6 +15,7 @@ "resolveJsonModule": true, "baseUrl": ".", "rootDir": ".", + "allowJs": true, "paths": { "@nrwl/angular": ["packages/angular"], "@nrwl/angular/*": ["packages/angular/*"], diff --git a/yarn.lock b/yarn.lock index e27400cc0864e..3ed5f757656b3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4114,6 +4114,11 @@ npmlog "^6.0.2" write-file-atomic "^4.0.1" +"@ltd/j-toml@1.24.0": + version "1.24.0" + resolved "https://registry.yarnpkg.com/@ltd/j-toml/-/j-toml-1.24.0.tgz#4c993610586964fb21fd38a84bb41913f6e4f5ff" + integrity sha512-XWEvSNLJ2YeCvlNDd/DQfTMldJqBZWX8+RKgPMY2i3MShqsB9XvtY2UfHqcuPb+eRrNO1WR7w4xlNfzCzop+Ig== + "@markdoc/markdoc@0.1.13": version "0.1.13" resolved "https://registry.yarnpkg.com/@markdoc/markdoc/-/markdoc-0.1.13.tgz#358408d3b4edf5dae90b51c2d8d89d51743dbd18" @@ -4169,6 +4174,15 @@ "@monaco-editor/loader" "^1.3.2" prop-types "^15.7.2" +"@monodon/rust@0.4.4": + version "0.4.4" + resolved "https://registry.yarnpkg.com/@monodon/rust/-/rust-0.4.4.tgz#b0df3b547692e1a66971387efeb7ec48620fadb8" + integrity sha512-sBU0h+6NoFaZYy3lcSqh6uNiGBp8cugj8V/wilsUy0+oEYmYTakO3So9EWwAsLMFRvh15yUOoOEVLuJ4ggIJOA== + dependencies: + "@ltd/j-toml" "1.24.0" + "@nrwl/devkit" "15.3.0" + chalk "4.1.2" + "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" @@ -4237,6 +4251,11 @@ "@napi-rs/canvas-linux-x64-musl" "0.1.30" "@napi-rs/canvas-win32-x64-msvc" "0.1.30" +"@napi-rs/cli@2.14.0": + version "2.14.0" + resolved "https://registry.yarnpkg.com/@napi-rs/cli/-/cli-2.14.0.tgz#ca1c1a75d6922f8af098d8d56f4914e0889963c8" + integrity sha512-hQW+gOTQ80nCoBAWA0hq49HM3QqyC7x879CdF/CEEFHeJNlHT8tgru8nbMQa6YqMP1XADfiudsYzy5V7TxBxCw== + "@nestjs/cli@^9.0.0": version "9.1.8" resolved "https://registry.yarnpkg.com/@nestjs/cli/-/cli-9.1.8.tgz#e4cb06c0cb628bf08ae143c2c6278a7beb38044b" @@ -4731,6 +4750,17 @@ dotenv "~10.0.0" semver "7.3.4" +"@nrwl/devkit@15.3.0": + version "15.3.0" + resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-15.3.0.tgz#4b0fc4c94f0b92413aa3d028f8cc75f586936d27" + integrity sha512-1O9QLB/eYS6ddw4MZnV4yj4CEqLIbpleZZiG/9w1TaiVO/jfNfXVaxc8EA87XSzMpk2W+/4Qggmabt6gAQaabA== + dependencies: + "@phenomnomnominal/tsquery" "4.1.1" + ejs "^3.1.7" + ignore "^5.0.4" + semver "7.3.4" + tslib "^2.3.0" + "@nrwl/devkit@15.6.0-beta.1": version "15.6.0-beta.1" resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-15.6.0-beta.1.tgz#a518608b7632fa95076b12912114c7787d1714ca"