From a5cdf6b60e54b7e1cc3bb1e23a31759174571c36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Schr=C3=B6ter?= Date: Fri, 24 Nov 2023 16:11:26 +0100 Subject: [PATCH] Sync from SUSE:ALP:Source:Standard:1.0 nodejs20 revision 6ec43a7e681b6260efb64d1a8ccc7474 --- .gitattributes | 23 + SHASUMS256.txt | 41 + SHASUMS256.txt.sig | Bin 0 -> 438 bytes _constraints | 32 + bash_output_helper.bash | 16 + cares_public_headers.patch | 13 + fix_ci_tests.patch | 98 +++ flaky_test_rerun.patch | 21 + gcc13.patch | 36 + legacy_python.patch | 26 + linker_lto_jobs.patch | 25 + manual_configure.patch | 20 + node-gyp-addon-gypi.patch | 79 ++ node-gyp-config.patch | 13 + node-gyp_7.1.2.tar.xz | 3 + node-v20.8.1.tar.xz | 3 + node_modules.tar.xz | 3 + nodejs-libpath.patch | 54 ++ nodejs.keyring | Bin 0 -> 61373 bytes nodejs20-zlib-1.3.patch | 13 + nodejs20.changes | 228 +++++ nodejs20.spec | 1151 +++++++++++++++++++++++++ npm_search_paths.patch | 32 + openssl_binary_detection.patch | 42 + qemu_timeouts_arches.patch | 14 + skip_no_console.patch | 29 + sle12_python3_compat.patch | 35 + test-skip-y2038-on-32bit-time_t.patch | 45 + update_npm_tarball.sh | 13 + versioned.patch | 188 ++++ 30 files changed, 2296 insertions(+) create mode 100644 .gitattributes create mode 100644 SHASUMS256.txt create mode 100644 SHASUMS256.txt.sig create mode 100644 _constraints create mode 100644 bash_output_helper.bash create mode 100644 cares_public_headers.patch create mode 100644 fix_ci_tests.patch create mode 100644 flaky_test_rerun.patch create mode 100644 gcc13.patch create mode 100644 legacy_python.patch create mode 100644 linker_lto_jobs.patch create mode 100644 manual_configure.patch create mode 100644 node-gyp-addon-gypi.patch create mode 100644 node-gyp-config.patch create mode 100644 node-gyp_7.1.2.tar.xz create mode 100644 node-v20.8.1.tar.xz create mode 100644 node_modules.tar.xz create mode 100644 nodejs-libpath.patch create mode 100644 nodejs.keyring create mode 100644 nodejs20-zlib-1.3.patch create mode 100644 nodejs20.changes create mode 100644 nodejs20.spec create mode 100644 npm_search_paths.patch create mode 100644 openssl_binary_detection.patch create mode 100644 qemu_timeouts_arches.patch create mode 100644 skip_no_console.patch create mode 100644 sle12_python3_compat.patch create mode 100644 test-skip-y2038-on-32bit-time_t.patch create mode 100644 update_npm_tarball.sh create mode 100644 versioned.patch diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fecc750 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/SHASUMS256.txt b/SHASUMS256.txt new file mode 100644 index 0000000..345ef2c --- /dev/null +++ b/SHASUMS256.txt @@ -0,0 +1,41 @@ +eea26c68c1f4799fc3ac3f2da9bfd4038b987d51d19d9c4ba8b145b3eee53c7d node-v20.8.1-aix-ppc64.tar.gz +93a5796c02c4e97378d6d0e2fcd8ac7b39418d97c21cf9aa6d9aa605814a1bff node-v20.8.1-arm64.msi +5451f3651c89cd8f224e74961c84e68f4c8d63fe288431a3223b0465cc8b961e node-v20.8.1-darwin-arm64.tar.gz +147e700ec86f8dbb8428600675673de303eb8710273b531031e5e9f3cde64644 node-v20.8.1-darwin-arm64.tar.xz +92b00b357c311eb45dd86516b032d80c63894aa069821c3ae3c8b3bbd00fdb9a node-v20.8.1-darwin-x64.tar.gz +679843744b44ac897479fd53340fdc6d96e5b5c139e90b9cdcbad8a403eaf807 node-v20.8.1-darwin-x64.tar.xz +b2db83feb961721f17142e792643974b04456cf2da34c22da3ac29cd00123226 node-v20.8.1-headers.tar.gz +298e41b8d7fd17738049f9c5f6e315bb0f935ab90f9b542d1a55cf6488cc3d67 node-v20.8.1-headers.tar.xz +c0420fef5f6e637888be3f400e99297bb844932166fbad5ffa4f188ce59cfcdf node-v20.8.1-linux-arm64.tar.gz +fec6edefa7ff959b29c7887735582ff2a2211b36a65a539da0f37db6797b7cff node-v20.8.1-linux-arm64.tar.xz +679fb1cc74ecc460b4a8178b90be2847af28ee817fa2f39d986c832405c0ee1e node-v20.8.1-linux-armv7l.tar.gz +f8370aaecd2cc2f26f8571aed7ffcf8efb6dc884a9a5e8e7a5e225e5ccfe6b74 node-v20.8.1-linux-armv7l.tar.xz +162bbf69b2c1aefc8163c371324cfd70582b8527e7623436d6e53823987a23d2 node-v20.8.1-linux-ppc64le.tar.gz +648d80fcb4a160e3078a66b3fc8c8eac669d28de3cfa533abed0bf8cb5af5785 node-v20.8.1-linux-ppc64le.tar.xz +d6a384293f18ba49b7507b67ce2ca1958050930768cae817d4705c3d3e672af2 node-v20.8.1-linux-s390x.tar.gz +4aa14458f2bac422989cc4526c431b14743c2f07889559fd1f2163cc6f3071f4 node-v20.8.1-linux-s390x.tar.xz +a42ac1f81704b14c7d07ddde989a8e290087b0487ee3f47185eb0240ba518195 node-v20.8.1-linux-x64.tar.gz +44096f6276cf735f3b25f47ffaaa1629b0abad4d9932c3a77d9dcdc743a3ff92 node-v20.8.1-linux-x64.tar.xz +abd016ae0dd943b196510e67277542c9cd31d24fbfa6834116a485d2c1d2b882 node-v20.8.1-win-arm64.7z +fbf7709c815f37577995d04b2cc41764033f06545c2c142d253ed257fe497960 node-v20.8.1-win-arm64.zip +6b3cb0e8d347ac52f0c45ba27a8c6f099b8053f18dfe7f6802e21c0b312aaedf node-v20.8.1-win-x64.7z +90b27dab351a582edd3a8de2e8aaa80d95c41f19fe92ebbef83b9a45bac95d00 node-v20.8.1-win-x64.zip +ea692ad4bb1e80156aa6143c39afda2cfd0d46c36e14a1e03064a5bd084f05cc node-v20.8.1-win-x86.7z +ba90977d0bee226db2dc89f55a3964eee4d844caef96e4db6994e1800d9c7dce node-v20.8.1-win-x86.zip +c364cda2bab611b08404d5f8c93913b0007b3a19830a27dee5ff5d466807f5eb node-v20.8.1-x64.msi +4f3daffb3124c08a31ebeca0a6b9aa4e4effcd5650c1fe1274c61343fb46689c node-v20.8.1-x86.msi +097897aa8489962e955700d75238230e8295fbc02a27bcdd53d4462ead2c8c7e node-v20.8.1.pkg +18aed385341bc16c7802e9d03189d1d0ad17b87923b2cdf11714d36534783b6a node-v20.8.1.tar.gz +f799c66f6a6386bb8ac2c75a378f740c455e97f1fe964393dd39c9f9f6efbc70 node-v20.8.1.tar.xz +60a3d73fb1d376e6ed0a8b8e6734ab6c80aaa031fa023fd1be42276cc80dff93 win-arm64/node.exe +90cb9fbf80b276f2ed039533a8b67f1aeaf204f0aaf6396b290ae9c4dcd6d690 win-arm64/node.lib +6887174c70c5ca8941b9e2bad9b02bb5413158590ec5457f4497bb66d685a545 win-arm64/node_pdb.7z +3824fb4b85c8f8086f0c33c4e906c1ac448cd6259949a06d6956e2b1b300befe win-arm64/node_pdb.zip +ccc62758d85434502141611b18af5fdbbc5c9087facaf4a7900d454f3d2fdd48 win-x64/node.exe +45d2519b3be3655e7b52ffcee613a484c38e768a59e9b9d4f08a3580d76a768a win-x64/node.lib +e98706e1126309275692c0d318a0f1c54a50ae2447c11e3bcc1c6c261dced63a win-x64/node_pdb.7z +9840a61ea4dea5128c20632f367e1bed2d2ace5fa008fe29b3ae28a9f4c21805 win-x64/node_pdb.zip +1c6ddd284a55664f0b2514bed7fcfe1fafcfec06f6dd07e82fefad9bb10aac60 win-x86/node.exe +0809f4b2f415581f7d932d80be4ac3ff7c4344421f7cccb34ff2f30c18c2ba0c win-x86/node.lib +63f95d51077f2dd0360c57cc4286cc74a740391b04b63fd04914583007e8cf10 win-x86/node_pdb.7z +108b21fc46465197cb4c07df4b25143b2a5d348b30e0d64c2536472fd94cba3e win-x86/node_pdb.zip diff --git a/SHASUMS256.txt.sig b/SHASUMS256.txt.sig new file mode 100644 index 0000000000000000000000000000000000000000..0ff68fc2513cc090de6a03ac76a8593b220b9187 GIT binary patch literal 438 zcmV;n0ZIOe0kZ@E0SEvc79j+Q3<%qWc@{734f)%P>a^d_RbKQ30%a+xJpc*`5R2-x z-_KQE^!myR|4S3QN_0@TE(I>K$jEuv0LAD=(YoHh0Apm1EelP&!Mz~7t&HvlCQ=gI zERmp<53`C~i_uKQdhzUY5#VvmNOjt))7(cGi8QaKJU?8@udK#rW+SaS3uJa^#-#V6^Ml7bfqxJhf|3?@bs@jEi8M07@k9*0|3cuk|vh_p$!GDb3Y!Dhr+g zgKuj8pEnG-opc?*0|>?xmBniQ;S4ZWBV8Bdnyrh8P+<%g1yR`PyDQ3YZohe`JQSje z>Q$U__KK5j_wh0+^d)HuZFHMZ!Hg?uMZDf%uh3@gu+i1Lcl|0W_ g + + + + 8 + + + 10000 + + + + + aarch64 + + + + asimdrdm + + + + + + armv6l + armv7l + + + + 5 + + + + diff --git a/bash_output_helper.bash b/bash_output_helper.bash new file mode 100644 index 0000000..d5a74bd --- /dev/null +++ b/bash_output_helper.bash @@ -0,0 +1,16 @@ +# +# Node can break stdin/stdout/stderr by setting them O_NONBLOCK +# and then not resetting it back to blocking mode on exit +# This function redirects stdio descriptors via new logging pipe +# + + +function decoupled_cmd +{ + mkfifo _log + ($@) < /dev/null > _log 2>_log & + cat _log + rm _log + wait $! +} + diff --git a/cares_public_headers.patch b/cares_public_headers.patch new file mode 100644 index 0000000..bd004ca --- /dev/null +++ b/cares_public_headers.patch @@ -0,0 +1,13 @@ +Index: node-v14.17.5/src/cares_wrap.h +=================================================================== +--- node-v14.17.5.orig/src/cares_wrap.h ++++ node-v14.17.5/src/cares_wrap.h +@@ -22,7 +22,7 @@ + # include + #endif // __POSIX__ + +-# include ++#include + + namespace node { + namespace cares_wrap { diff --git a/fix_ci_tests.patch b/fix_ci_tests.patch new file mode 100644 index 0000000..f0e81c2 --- /dev/null +++ b/fix_ci_tests.patch @@ -0,0 +1,98 @@ +Author: Adam Majer +Date: Dec 20 09:18:49 UTC 2017 +Summary: Fix CI unit tests framework for OBS building + +Index: node-v20.8.1/test/parallel/test-module-loading-globalpaths.js +=================================================================== +--- node-v20.8.1.orig/test/parallel/test-module-loading-globalpaths.js ++++ node-v20.8.1/test/parallel/test-module-loading-globalpaths.js +@@ -11,6 +11,9 @@ const { addLibraryPath } = require('../c + + addLibraryPath(process.env); + ++common.skip('hardcoded global paths'); ++return; ++ + if (process.argv[2] === 'child') { + console.log(require(pkgName).string); + } else { +Index: node-v20.8.1/test/parallel/test-tls-passphrase.js +=================================================================== +--- node-v20.8.1.orig/test/parallel/test-tls-passphrase.js ++++ node-v20.8.1/test/parallel/test-tls-passphrase.js +@@ -223,7 +223,7 @@ server.listen(0, common.mustCall(functio + }, onSecureConnect()); + })).unref(); + +-const errMessageDecrypt = /bad decrypt/; ++const errMessageDecrypt = /bad (decrypt|password read)/; + + // Missing passphrase + assert.throws(function() { +Index: node-v20.8.1/test/parallel/test-repl-envvars.js +=================================================================== +--- node-v20.8.1.orig/test/parallel/test-repl-envvars.js ++++ node-v20.8.1/test/parallel/test-repl-envvars.js +@@ -2,7 +2,9 @@ + + // Flags: --expose-internals + +-require('../common'); ++const common = require('../common'); ++common.skip('Not running test in OBS'); ++ + const stream = require('stream'); + const { describe, test } = require('node:test'); + const REPL = require('internal/repl'); +Index: node-v20.8.1/Makefile +=================================================================== +--- node-v20.8.1.orig/Makefile ++++ node-v20.8.1/Makefile +@@ -545,7 +545,8 @@ test-ci-js: | clear-stalled + .PHONY: test-ci + # Related CI jobs: most CI tests, excluding node-test-commit-arm-fanned + test-ci: LOGLEVEL := info +-test-ci: | clear-stalled bench-addons-build build-addons build-js-native-api-tests build-node-api-tests doc-only ++test-ci: | clear-stalled bench-addons-build build-addons build-js-native-api-tests build-node-api-tests ++ strip $(NODE_EXE) + out/Release/cctest --gtest_output=xml:out/junit/cctest.xml + $(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \ + --mode=$(BUILDTYPE_LOWER) --flaky-tests=$(FLAKY_TESTS) \ +@@ -726,7 +727,8 @@ apidocs_json = $(addprefix out/,$(apidoc + apiassets = $(subst api_assets,api/assets,$(addprefix out/,$(wildcard doc/api_assets/*))) + + tools/doc/node_modules: tools/doc/package.json +- @if [ "$(shell $(node_use_openssl))" != "true" ]; then \ ++ echo "Skipping tools/doc/node_modules" ++# @if [ "$(shell $(node_use_openssl))" != "true" ]; then \ + echo "Skipping tools/doc/node_modules (no crypto)"; \ + else \ + cd tools/doc && $(call available-node,$(run-npm-ci)) \ +Index: node-v20.8.1/tools/test.py +=================================================================== +--- node-v20.8.1.orig/tools/test.py ++++ node-v20.8.1/tools/test.py +@@ -1361,7 +1361,7 @@ def BuildOptions(): + result.add_option("-s", "--suite", help="A test suite", + default=[], action="append") + result.add_option("-t", "--timeout", help="Timeout in seconds", +- default=120, type="int") ++ default=1200, type="int") + result.add_option("--arch", help='The architecture to run tests for', + default='none') + result.add_option("--snapshot", help="Run the tests with snapshot turned on", +Index: node-v20.8.1/test/parallel/test-crypto-dh.js +=================================================================== +--- node-v20.8.1.orig/test/parallel/test-crypto-dh.js ++++ node-v20.8.1/test/parallel/test-crypto-dh.js +@@ -87,9 +87,7 @@ const crypto = require('crypto'); + + assert.throws(() => { + dh3.computeSecret(''); +- }, { message: common.hasOpenSSL3 ? +- 'error:02800080:Diffie-Hellman routines::invalid secret' : +- 'Supplied key is too small' }); ++ }, /(error:02800080:Diffie-Hellman routines::invalid secret|error:05066066:Diffie-Hellman routines:compute_key:invalid public key|Supplied key is too small)/); + } + + // Through a fluke of history, g=0 defaults to DH_GENERATOR (2). diff --git a/flaky_test_rerun.patch b/flaky_test_rerun.patch new file mode 100644 index 0000000..b1bccad --- /dev/null +++ b/flaky_test_rerun.patch @@ -0,0 +1,21 @@ +Index: node-v16.13.0/tools/test.py +=================================================================== +--- node-v16.13.0.orig/tools/test.py ++++ node-v16.13.0/tools/test.py +@@ -586,6 +586,16 @@ class TestCase(object): + self.context.store_unexpected_output) + + def Run(self): ++ reruns = 0 ++ while (reruns < 5): ++ reruns += 1 ++ result = self.OriginalRun() ++ if (not result.HasFailed()): ++ break ++ print("FLAKY TEST rerun: ", self.GetCommand()) ++ return result ++ ++ def OriginalRun(self): + try: + result = self.RunCommand(self.GetCommand(), { + "TEST_SERIAL_ID": "%d" % self.serial_id, diff --git a/gcc13.patch b/gcc13.patch new file mode 100644 index 0000000..68dbd9c --- /dev/null +++ b/gcc13.patch @@ -0,0 +1,36 @@ +Index: node-v20.0.0/deps/v8/src/builtins/builtins-array-gen.cc +=================================================================== +--- node-v20.0.0.orig/deps/v8/src/builtins/builtins-array-gen.cc ++++ node-v20.0.0/deps/v8/src/builtins/builtins-array-gen.cc +@@ -18,6 +18,7 @@ + #include "src/objects/arguments-inl.h" + #include "src/objects/elements-kind.h" + #include "src/objects/property-cell.h" ++#include "src/wasm/wasm-objects.h" + + namespace v8 { + namespace internal { +Index: node-v20.0.0/deps/v8/src/builtins/builtins-array.cc +=================================================================== +--- node-v20.0.0.orig/deps/v8/src/builtins/builtins-array.cc ++++ node-v20.0.0/deps/v8/src/builtins/builtins-array.cc +@@ -22,6 +22,7 @@ + #include "src/objects/objects-inl.h" + #include "src/objects/prototype.h" + #include "src/objects/smi.h" ++#include "src/wasm/wasm-objects.h" + + namespace v8 { + namespace internal { +Index: node-v20.0.0/deps/v8/src/codegen/tnode.h +=================================================================== +--- node-v20.0.0.orig/deps/v8/src/codegen/tnode.h ++++ node-v20.0.0/deps/v8/src/codegen/tnode.h +@@ -6,6 +6,7 @@ + #define V8_CODEGEN_TNODE_H_ + + #include "src/codegen/machine-type.h" ++#include "src/wasm/wasm-objects.h" + + namespace v8 { + namespace internal { diff --git a/legacy_python.patch b/legacy_python.patch new file mode 100644 index 0000000..00fef03 --- /dev/null +++ b/legacy_python.patch @@ -0,0 +1,26 @@ +Index: node-v18.11.0/tools/utils.py +=================================================================== +--- node-v18.11.0.orig/tools/utils.py ++++ node-v18.11.0/tools/utils.py +@@ -26,10 +26,10 @@ + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-import glob + import platform + import re + import sys ++from pathlib import Path + + + # Reads a .list file into an array of strings +@@ -109,7 +109,8 @@ def IsWindows(): + + + def SearchFiles(dir, ext): +- list = glob.glob(dir+ '/**/*.' + ext, recursive=True) ++ list = Path(dir).glob('**/*.' + ext) ++ list = [ str(x) for x in list ] + if sys.platform == 'win32': + list = [ x.replace('\\', '/')for x in list] + return sorted(list) diff --git a/linker_lto_jobs.patch b/linker_lto_jobs.patch new file mode 100644 index 0000000..1d856f9 --- /dev/null +++ b/linker_lto_jobs.patch @@ -0,0 +1,25 @@ +Purpose of these dependencies is to make sure that the linker +is run serially over these binaries instead of in parallel. +OBS workers run out of memory as each executable seems to require +upward of 5G RAM + +Index: node-v19.7.0/node.gyp +=================================================================== +--- node-v19.7.0.orig/node.gyp ++++ node-v19.7.0/node.gyp +@@ -951,6 +951,7 @@ + 'deps/uvwasi/uvwasi.gyp:uvwasi', + 'deps/simdutf/simdutf.gyp:simdutf', + 'deps/ada/ada.gyp:ada', ++ 'fuzz_env' + ], + + 'includes': [ +@@ -1047,6 +1048,7 @@ + 'deps/histogram/histogram.gyp:histogram', + 'deps/uvwasi/uvwasi.gyp:uvwasi', + 'deps/ada/ada.gyp:ada', ++ 'cctest' + ], + + 'includes': [ diff --git a/manual_configure.patch b/manual_configure.patch new file mode 100644 index 0000000..7a40b92 --- /dev/null +++ b/manual_configure.patch @@ -0,0 +1,20 @@ +Author: Adam Majer +Date: Wed May 23 14:13:33 CEST 2018 +Summary: This config.h is defined by hand + +Gyp doesn't run autotools, so this config is not quite correct. +Update to prevent implicit defines to be used. + +Index: node-git.8dae89b396/deps/nghttp2/lib/includes/config.h +=================================================================== +--- node-git.8dae89b396.orig/deps/nghttp2/lib/includes/config.h ++++ node-git.8dae89b396/deps/nghttp2/lib/includes/config.h +@@ -71,7 +71,7 @@ typedef intptr_t ssize_t; + /* #undef HAVE_NETDB_H */ + + /* Define to 1 if you have the header file. */ +-/* #undef HAVE_NETINET_IN_H */ ++#define HAVE_NETINET_IN_H 1 + + /* Define to 1 if you have the header file. */ + /* #undef HAVE_PWD_H */ diff --git a/node-gyp-addon-gypi.patch b/node-gyp-addon-gypi.patch new file mode 100644 index 0000000..6007c5a --- /dev/null +++ b/node-gyp-addon-gypi.patch @@ -0,0 +1,79 @@ +Index: node-git.b4f0a18b5a/addon-rpm.gypi +=================================================================== +--- /dev/null ++++ node-git.b4f0a18b5a/addon-rpm.gypi +@@ -0,0 +1,35 @@ ++{ ++ 'target_defaults': { ++ 'type': 'loadable_module', ++ 'product_prefix': '', ++ 'include_dirs': [ ++ '/usr/include/node20/', ++ '/usr/include/' ++ ], ++ ++ 'target_conditions': [ ++ ['_type=="loadable_module"', { ++ 'product_extension': 'node', ++ 'defines': [ 'BUILDING_NODE_EXTENSION' ], ++ }] ++ ], ++ ++ 'conditions': [ ++ [ 'OS=="mac"', { ++ 'libraries': [ '-undefined dynamic_lookup' ], ++ 'xcode_settings': { ++ 'DYLIB_INSTALL_NAME_BASE': '@rpath' ++ }, ++ }], ++ [ 'OS=="win"', { ++ 'libraries': [ '-l<(node_root_dir)/$(Configuration)/node.lib' ], ++ # warning C4251: 'node::ObjectWrap::handle_' : class 'v8::Persistent' ++ # needs to have dll-interface to be used by clients of class 'node::ObjectWrap' ++ 'msvs_disabled_warnings': [ 4251 ], ++ }], ++ [ 'OS=="freebsd" or OS=="openbsd" or OS=="solaris" or (OS=="linux" and target_arch!="ia32")', { ++ 'cflags': [ '-fPIC' ], ++ }] ++ ] ++ } ++} +Index: node-git.b4f0a18b5a/deps/npm/node_modules/node-gyp/lib/configure.js +=================================================================== +--- node-git.b4f0a18b5a.orig/deps/npm/node_modules/node-gyp/lib/configure.js ++++ node-git.b4f0a18b5a/deps/npm/node_modules/node-gyp/lib/configure.js +@@ -46,10 +46,6 @@ function configure (gyp, argv, callback) + if ('v' + release.version !== process.version) { + // if --target was given, then determine a target version to compile for + log.verbose('get node dir', 'compiling against --target node version: %s', release.version) +- } else { +- // if no --target was specified then use the current host node version +- log.verbose('get node dir', 'no --target version specified, falling back to host node version: %s', release.version) +- } + + if (!release.semver) { + // could not parse the version string with semver +@@ -68,6 +64,12 @@ function configure (gyp, argv, callback) + nodeDir = path.resolve(gyp.devDir, release.versionDir) + createBuildDir() + }) ++ } else { ++ // if no --target was specified then use RPM-installed headers ++ log.verbose('get node dir', 'no --target version specified, falling back to RPM installed headers') ++ nodeDir = '/usr/include/node20' ++ createBuildDir() ++ } + } + } + +@@ -282,7 +284,9 @@ function configure (gyp, argv, callback) + + // this logic ported from the old `gyp_addon` python file + var gypScript = path.resolve(__dirname, '..', 'gyp', 'gyp_main.py') +- var addonGypi = path.resolve(__dirname, '..', 'addon.gypi') ++ var addon_gypi_file = gyp.opts.target || gyp.opts.nodedir ? 'addon.gypi' : 'addon-rpm.gypi' ++ ++ var addonGypi = path.resolve(__dirname, '..', addon_gypi_file) + var commonGypi = path.resolve(nodeDir, 'include/node/common.gypi') + fs.stat(commonGypi, function (err) { + if (err) { diff --git a/node-gyp-config.patch b/node-gyp-config.patch new file mode 100644 index 0000000..b046710 --- /dev/null +++ b/node-gyp-config.patch @@ -0,0 +1,13 @@ +Index: node-v19.1.0/deps/npm/node_modules/node-gyp/lib/configure.js +=================================================================== +--- node-v19.1.0.orig/deps/npm/node_modules/node-gyp/lib/configure.js ++++ node-v19.1.0/deps/npm/node_modules/node-gyp/lib/configure.js +@@ -96,7 +96,7 @@ function configure (gyp, argv, callback) + + log.verbose('build/' + configFilename, 'creating config file') + +- var config = process.config || {} ++ var config = JSON.parse(JSON.stringify(process.config || {})) + var defaults = config.target_defaults + var variables = config.variables + diff --git a/node-gyp_7.1.2.tar.xz b/node-gyp_7.1.2.tar.xz new file mode 100644 index 0000000..12dc4bc --- /dev/null +++ b/node-gyp_7.1.2.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:172cd1f46b5b20cb4f443a83b24995ad35477c3ccdffe228b8e96ca4199d6103 +size 1245896 diff --git a/node-v20.8.1.tar.xz b/node-v20.8.1.tar.xz new file mode 100644 index 0000000..b914389 --- /dev/null +++ b/node-v20.8.1.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f799c66f6a6386bb8ac2c75a378f740c455e97f1fe964393dd39c9f9f6efbc70 +size 41863408 diff --git a/node_modules.tar.xz b/node_modules.tar.xz new file mode 100644 index 0000000..8d9a271 --- /dev/null +++ b/node_modules.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7834b0aa267b76199167f8523b90cd61b3d562ecf50259e93723379cd7665977 +size 1071008 diff --git a/nodejs-libpath.patch b/nodejs-libpath.patch new file mode 100644 index 0000000..2152360 --- /dev/null +++ b/nodejs-libpath.patch @@ -0,0 +1,54 @@ +Index: node-v18.9.0/tools/install.py +=================================================================== +--- node-v18.9.0.orig/tools/install.py ++++ node-v18.9.0/tools/install.py +@@ -7,6 +7,7 @@ import errno + import os + import shutil + import sys ++from distutils import sysconfig + import re + + # set at init time +@@ -66,6 +67,10 @@ def try_copy(path, dst): + try_unlink(target_path) # prevent ETXTBSY errors + return shutil.copy2(source_path, target_path) + ++def libdir(): ++ libdir_fq = sysconfig.get_config_var("LIBDIR") ++ return re.sub("^" + re.escape(node_prefix + "/"), "", libdir_fq) ++ + def try_remove(path, dst): + source_path, target_path = mkpaths(path, dst) + print('removing %s' % target_path) +@@ -81,7 +86,7 @@ def uninstall(paths, dst): + try_remove(path, dst) + + def package_files(action, name, bins): +- target_path = 'lib/node_modules/' + name + '/' ++ target_path = libdir() + '/node_modules/' + name + '/' + + # don't install npm if the target path is a symlink, it probably means + # that a dev version of npm is installed there +@@ -101,7 +106,7 @@ def package_files(action, name, bins): + if action == uninstall: + action([link_path], 'bin/' + bin_name) + elif action == install: +- try_symlink('../lib/node_modules/' + name + '/' + bin_target, link_path) ++ try_symlink('../' + libdir() + '/node_modules/' + name + '/' + bin_target, link_path) + else: + assert 0 # unhandled action type + +Index: node-v18.9.0/lib/internal/modules/cjs/loader.js +=================================================================== +--- node-v18.9.0.orig/lib/internal/modules/cjs/loader.js ++++ node-v18.9.0/lib/internal/modules/cjs/loader.js +@@ -1254,7 +1254,7 @@ Module._initPaths = function() { + path.resolve(process.execPath, '..') : + path.resolve(process.execPath, '..', '..'); + +- const paths = [path.resolve(prefixDir, 'lib', 'node')]; ++ const paths = ['/usr/lib/node']; + + if (homeDir) { + ArrayPrototypeUnshift(paths, path.resolve(homeDir, '.node_libraries')); diff --git a/nodejs.keyring b/nodejs.keyring new file mode 100644 index 0000000000000000000000000000000000000000..aa22d759f4a9b2e1eaed11180337d9a4d50f322a GIT binary patch literal 61373 zcma&NbCl%mmMmPhZQEV8ZQHhO+qP}nwrzCTMt4qMocO8`tAZ|FBZ0lHPI&S80n;AL8s1qCtpjJo^pqsuO))Agh_kw)0_&N?w@777#p;O0C|mqA zAe*lnTK7rF2i8CdB!Gq%eF9^C*7(dqxHvGT{e+4&T`hj?bV<6pJV*525G>u|3iyq0 zzZD5?Z{TCY{1BTdRiodFtHYbR*5SH5{Da3Z#B+bK9);*BV?KpkN9oyR?Nl9i3H_O2}KLbOr_r9-B!GHQ!kN z*i=_DHjg@8m6A7O;NV0%pS4T52yQISsab%?B0V4!!)gHWj!7FykkrC+J~nCP{RoQMQ~5)%`@NU`7_Yle0s1?358qt-Vc_c=$jp zEcpv5Z9VbI7hP>VTD&6pjD8OC!-w*%n-;*YddFGEI($m2@2w|{8-chxvYWO%L$7L- zx|~G8Ju0@&o{>;lt{ z*~Ee)xih{b9xcke2%cv2f2%n=<3CkrW=3b{_+JXIDE|Mo@CpVX0OE`FdL&&oIKdT$ zp7oerlUI7}(ityYD@Hr%3a=Z_aM>7EH~B`_Cx(^~q#Xu_#-+Qer88`UL* zOT}|bHUu=PG2;g(0k?i@yGl@jMxaSz9p|te`^`u1Rz19he&Y&oE`82;zX=i)`S2tX~;|43X9|^R}o-&DWFc`okDEr{5 zyYEikG1JDZS+O3xEWi?(Q&B#Fz_3LMu#SCAmA^3D&->shits)qV;E>ruh+hxp0GH_ z7pv;qdesZfOMj69#%XHB?jQ5m=%4)f7Q>#a{XRsGO$76C14Or8Jew~`Fq6`MyB!`* z*{&~D2y0C94suvQM4q)HY2Rk6k8dW6Z13Bv3$kWuQ27z)S$EhE1`mJll%4^gmh#gz z;M`5tsNPF!BWcg%Ti3*zqob2X2V(8RnZ9 zKf8)en;p(df%R^hc>qdLNs{q%UJ;}TczlAvD<mh5=o{nMdpUDESDQv6o+Er#vr zk1BH{^cAw*5#)3fhoaN^e|P*#4J;(v?tOpT(s)2W7p?098hS=`5kvPGLHL+9 zze`0!qu87Cu9YqILy8lty81k?Q_V^D3mYPaUX7C>8f!W>(e24m25kJ& zfj>|X+OFTH3XijKlGepGP(y-Em1-?c&1bl!7%ooisw8*LUBITM9j?`Cea?2mf2Ryy z6g&P28sO+0cqaNu*`CVfe&X>9|MqV+5CMn}g7Js>A^*wzF#k^QYWENTEtV{&6!+Hs zA*`Z6!m=kUSfJp{eH2Qr=O+OL1%q++O!M@UQ>OfcG7sqqSU49*i>KfOa|4P9((n0W z)u8%m67hUxkAnU�z>p88ZS{C%;RGsz_2S1zcy)eeOC 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≥&1?531 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 literal 0 HcmV?d00001 diff --git a/nodejs20-zlib-1.3.patch b/nodejs20-zlib-1.3.patch new file mode 100644 index 0000000..da9e44d --- /dev/null +++ b/nodejs20-zlib-1.3.patch @@ -0,0 +1,13 @@ +Index: node-v20.8.1/test/parallel/test-process-versions.js +=================================================================== +--- node-v20.8.1.orig/test/parallel/test-process-versions.js ++++ node-v20.8.1/test/parallel/test-process-versions.js +@@ -61,7 +61,7 @@ assert.match(process.versions.brotli, co + assert.match(process.versions.llhttp, commonTemplate); + assert.match(process.versions.node, commonTemplate); + assert.match(process.versions.uv, commonTemplate); +-assert.match(process.versions.zlib, /^\d+(?:\.\d+){2,3}(?:-.*)?$/); ++assert.match(process.versions.zlib, /^\d+(?:\.\d+){1,3}(?:-.*)?$/); + + if (hasUndici) { + assert.match(process.versions.undici, commonTemplate); diff --git a/nodejs20.changes b/nodejs20.changes new file mode 100644 index 0000000..17ac0a6 --- /dev/null +++ b/nodejs20.changes @@ -0,0 +1,228 @@ +------------------------------------------------------------------- +Fri Oct 27 09:10:38 UTC 2023 - Adam Majer + +- fix_ci_tests.patch: adapt for openssl 3.1.4 + +-------------------------------------------------------------------- +Tue Oct 24 11:21:41 UTC 2023 - Dominique Leuenberger + +- Add nodejs20-zlib-1.3.patch: Support zlib version with only + major.minor versions, like zlib 1.3. + +------------------------------------------------------------------ +Mon Oct 16 09:28:06 UTC 2023 - Adam Majer - 20.8.1 + +- Security fixes relase 20.8.1 + * (CVE-2023-44487, bsc#1216190): nghttp2 Security Release + * (CVE-2023-45143, bsc#1216205): undici Security Release + * (CVE-2023-39332, bsc#1216271): Path traversal through path stored in Uint8Array + * (CVE-2023-39331, bsc#1216270): Permission model improperly protects against path traversal + * (CVE-2023-38552, bsc#1216272): Integrity checks according to policies can be circumvented + * (CVE-2023-39333, bsc#1216273): Code injection via WebAssembly export names + +- fix_ci_tests.patch: refreshed + +------------------------------------------------------------------- +Thu Oct 5 13:45:41 UTC 2023 - Adam Majer - 20.8.0 + +- Update to 20.8.0: + * Stream performance improvements + * Rework of memory management in vm APIs with the importModuleDynamically + option + * test_runner: + + accept testOnly in run + + add junit reporter + +- fix_ci_tests.patch: refreshed + +------------------------------------------------------------------- +Tue Sep 19 14:40:13 UTC 2023 - Adam Majer - 20.7.0 + +- Update to 20.7.0: + * src: support multiple --env-file declarations + * deps: upgrade npm to 10.1.0 + * doc: move and rename loaders section + * lib: add api to detect whether source-maps are enabled + * src,permission: add multiple allow-fs-* flags + * test_runner: expose location of tests + +- z13.patch: upstreamed + +------------------------------------------------------------------- +Mon Sep 18 10:08:42 UTC 2023 - Adam Majer + +- Update to 20.6.1: + * f0ff63fbc32ea55f3d92c5c89fdb91ec47786859.patch: removed, upstreamed + +------------------------------------------------------------------- +Fri Sep 8 10:46:20 UTC 2023 - Adam Majer + +- f0ff63fbc32ea55f3d92c5c89fdb91ec47786859.patch: fixes issues with + Angular and other software that tries to load ECM modules in + somewhat circular fashion ending up with multiple executions. + +------------------------------------------------------------------- +Tue Sep 5 09:29:49 UTC 2023 - Adam Majer - 20.6.0 + +- Update to 20.6.0: + * add support for .env files to configure envrionment variables + * import.meta.resolve unflagged + * deps: npm updated to 9.8.1 +- nodejs.keyring: updated to include current upstream releasers + +------------------------------------------------------------------- +Fri Aug 25 14:34:21 UTC 2023 - Adam Majer + +- Temporarily bundle ICU for SLE15 SP6 (jsc#PED-4819) + +------------------------------------------------------------------- +Thu Aug 10 13:51:20 UTC 2023 - Adam Majer + +- Update to version 20.5.1: + * (CVE-2023-32002, bsc#1214150): Policies can be bypassed + via Module._load (High) + * (CVE-2023-32558, bsc#1214155): process.binding() can bypass + the permission model through path traversal (High) + * (CVE-2023-32004, bsc#1214152): Permission model can be bypassed + by specifying a path traversal sequence in a Buffer (High) + * (CVE-2023-32006, bsc#1214156): Policies can be bypassed + by module.constructor.createRequire (Medium) + * (CVE-2023-32559, bsc#1214154): Policies can be bypassed + via process.binding (Medium) + * (CVE-2023-32005, bsc#1214153): fs.statfs can bypass + the permission model (Low) + * (CVE-2023-32003, bsc#1214151): fs.mkdtemp() and fs.mkdtempSync() + can bypass the permission model (Low) +- Changes in 20.5.0: + * events: allow safely adding listener to abortSignal + * fs: add a fast-path for readFileSync utf-8 + * test_runner: add shards support +- Changes in 20.4.0: + * tls: add ALPNCallback server option for dynamic ALPN negotiation + * adds support for ECMAScript Explicit Resource Management + * adds Mock Timer support to test module + +For details see, +https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V20.md#20.5.1 + +versioned.patch: refreshed + +------------------------------------------------------------------- +Wed Jun 21 11:24:39 UTC 2023 - Adam Majer + +- Update to version 20.3.1 (security fixes only). The following + CVEs are fixed in this release: + * (CVE-2023-30581, bsc#1212574): mainModule.__proto__ Bypass + Experimental Policy Mechanism (High) + * (CVE-2023-30584, bsc#1212575): Path Traversal Bypass in + Experimental Permission Model (High) + * (CVE-2023-30587, bsc#1212576): Bypass of Experimental + Permission Model via Node.js Inspector (High) + * (CVE-2023-30582, bsc#1212577): Inadequate Permission Model + Allows Unauthorized File Watching (Medium) + * (CVE-2023-30583, bsc#1212578): Bypass of Experimental + Permission Model via fs.openAsBlob() (Medium) + * (CVE-2023-30585, bsc#1212579): Privilege escalation via + Malicious Registry Key manipulation during Node.js + installer repair process (Medium) + * (CVE-2023-30586, bsc#1212580): Bypass of Experimental + Permission Model via Arbitrary OpenSSL Engines (Medium) + * (CVE-2023-30588, bsc#1212581): Process interuption due to invalid + Public Key information in x509 certificates (Medium) + * (CVE-2023-30589, bsc#1212582): HTTP Request Smuggling via + Empty headers separated by CR (Medium) + * (CVE-2023-30590, bsc#1212583): DiffieHellman does not + generate keys after setting a private key (Medium) + +------------------------------------------------------------------- +Thu Jun 15 11:25:18 UTC 2023 - Adam Majer + +- Update to version 20.3.0: + * deps: upgrade to libuv 1.45.0, including significant performance + improvements to file system operations on Linux + * module: change default resolver to not throw on unknown scheme + * stream: deprecate asIndexedPairs + +- versioned.patch, fix_ci_tests.patch: refreshed +- openssl3_1-adapt_tests.patch: upstreamed and removed + +For details see, +https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V20.md#20.3.0 + +------------------------------------------------------------------- +Mon May 22 14:45:27 UTC 2023 - Adam Majer + +- Fix build on SLE12SP5 + +------------------------------------------------------------------- +Fri May 19 12:17:15 UTC 2023 - Adam Majer + +- Update to version 20.2.0: + * http: prevent writing to the body when not allowed by HTTP spec + * sea: add option to disable the experimental SEA warning + * test_runner: add skip, todo, and only shorthands to test + * url: add value argument to URLSearchParams has and delete methods + +For details see, +https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V20.md#20.2.0 + +------------------------------------------------------------------- +Mon May 15 14:03:24 UTC 2023 - Adam Majer + +- fix_ci_tests.patch: increase default timeout on unit tests + to 20min from 2min. This seems to have lead to build failures + on some platforms, like s390x in Factory. (bsc#1211407) + +------------------------------------------------------------------- +Fri May 12 07:52:30 UTC 2023 - Adam Majer + +- z13.patch: fixes illegal instruction error on z13 and older s390 + +------------------------------------------------------------------- +Thu May 10 13:09:58 UTC 2023 - Otto Hollmann + +- Adapt tests for OpenSSL 3.1 [bsc#1209430] + * Add openssl3_1-adapt_tests.patch + +------------------------------------------------------------------- +Thu May 4 13:26:26 UTC 2023 - Adam Majer - 20.1.0 + +- Update to version 20.1.0 + assert: deprecate CallTracker + dns: expose getDefaultResultOrder + doc: add KhafraDev to collaborators + fs: add recursive option to readdir and opendir + fs: add support for mode flag to specify the copy behavior + of the cp methods + http: add highWaterMark option http.createServer + stream: preserve object mode in compose + test_runner: add testNamePatterns to run API + test_runner: execute before hook on test + test_runner: support combining coverage reports + wasi: make returnOnExit true by default + +------------------------------------------------------------------- +Wed Apr 19 13:16:54 UTC 2023 - Adam Majer - 20.0.0 + +- Package new version 20.0.0 + For overview of changes and details since 19.x and earlier see + https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V20.md#20.0.0 + +- imported the following patches from prior patches: + + cares_public_headers.patch + + fix_ci_tests.patch + + flaky_test_rerun.patch + + legacy_python.patch + + linker_lto_jobs.patch + + manual_configure.patch + + node-gyp-addon-gypi.patch + + node-gyp-config.patch + + nodejs-libpath.patch + + npm_search_paths.patch + + openssl_binary_detection.patch + + qemu_timeouts_arches.patch + + skip_no_console.patch + + sle12_python3_compat.patch + + test-skip-y2038-on-32bit-time_t.patch + + versioned.patch + diff --git a/nodejs20.spec b/nodejs20.spec new file mode 100644 index 0000000..948ac32 --- /dev/null +++ b/nodejs20.spec @@ -0,0 +1,1151 @@ +# +# spec file for package nodejs20 +# +# Copyright (c) 2022 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + +########################################################### +# +# WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! +# +# This spec file is generated from a template hosted at +# https://github.com/AdamMajer/nodejs-packaging +# +########################################################### + +# Fedora doesn't have rpm-config-SUSE which provides +# ext_man in /usr/lib/rpm/macros.d/macros.obs +%if 0%{?fedora_version} +%define ext_man .gz +%endif + +Name: nodejs20 +Version: 20.8.1 +Release: 0 + +# Double DWZ memory limits +%define _dwz_low_mem_die_limit 20000000 +%define _dwz_max_die_limit 100000000 + +%define node_version_number 20 + +# openssl bsc#1192489 - fix released +%bcond_without openssl_RSA_get0_pss_params + +%if 0%{?suse_version} > 1500 || 0%{?fedora_version} +%bcond_without libalternatives +%else +%bcond_with libalternatives +%endif + +%if %node_version_number >= 12 +%define openssl_req_ver 1.1.1 +%else +%if %node_version_number >= 10 +%define openssl_req_ver 1.1.0 +%else +%define openssl_req_ver 1.0.2 +%endif +%endif + +%bcond_with valgrind_tests + +%if %{node_version_number} >= 12 + +# turn on LTO only on non-32bit arches +%ifarch %{ix86} %{arm} +%bcond_with nodejs_lto +%else +%bcond_without nodejs_lto +%endif + +%else +%bcond_with nodejs_lto +%endif + +%if !0%{?with nodejs_lto} +%define _lto_cflags %{nil} +%endif + +%if 0%{?suse_version} == 1110 +%define _libexecdir %{_exec_prefix}/lib +%endif + +%if 0%{?suse_version} >= 1500 || 0%{?sle_version} >= 120400 || 0%{?fedora_version} >= 35 +%bcond_with intree_openssl +%else +%bcond_without intree_openssl +%endif + +%if 0%{?suse_version} >= 1330 || 0%{?fedora_version} >= 35 +%bcond_with intree_cares +%else +%bcond_without intree_cares +%endif + +%if 0%{?suse_version} >= 1330 || 0%{?fedora_version} >= 35 +%bcond_with intree_icu +%else +%bcond_without intree_icu +%endif + +%if 0%{?suse_version} >= 1550 +%bcond_with intree_nghttp2 +%else +%bcond_without intree_nghttp2 +%endif + +%if 0%{?suse_version} >= 1550 +%bcond_with intree_brotli +%else +%bcond_without intree_brotli +%endif + +%ifnarch x86_64 %{ix86} +%bcond_with gdb +%else +%bcond_without gdb +%endif + +%define git_node 0 + +Summary: Evented I/O for V8 JavaScript +License: MIT +Group: Development/Languages/NodeJS +URL: https://nodejs.org +Source: https://nodejs.org/dist/v%{version}/node-v%{version}.tar.xz +Source1: https://nodejs.org/dist/v%{version}/SHASUMS256.txt +Source2: https://nodejs.org/dist/v%{version}/SHASUMS256.txt.sig +Source3: nodejs.keyring + +# Python 3.4 compatible node-gyp +### https://github.com/nodejs/node-gyp.git +### git archive v7.1.2 | xz > node-gyp_7.1.2.tar.xz +Source5: node-gyp_7.1.2.tar.xz +# Only required to run unit tests in NodeJS 10+ +Source10: update_npm_tarball.sh +Source11: node_modules.tar.xz +Source20: bash_output_helper.bash + +## Patches not distribution specific +Patch1: cares_public_headers.patch +Patch3: fix_ci_tests.patch +Patch5: sle12_python3_compat.patch +Patch7: manual_configure.patch +Patch13: openssl_binary_detection.patch + + + +## Patches specific to SUSE and openSUSE +Patch100: linker_lto_jobs.patch +# PATCH-FIX-OPENSUSE -- set correct path for dtrace if it is built +Patch101: nodejs-libpath.patch +# PATCH-FIX-UPSTREAM -- use custom addon.gypi by default instead of +# downloading node source +Patch102: node-gyp-addon-gypi.patch +# PATCH-FIX-SLE -- configure script uses Python check_output method +# which isn't included in Python 2.6 (used in SLE 11). +# PATCH-FIX-OPENSUSE -- install user global npm packages to /usr/local +# instead of /usr +Patch104: npm_search_paths.patch +Patch106: skip_no_console.patch +Patch110: legacy_python.patch + +Patch120: flaky_test_rerun.patch + +Patch132: test-skip-y2038-on-32bit-time_t.patch + +# Use versioned binaries and paths +Patch200: versioned.patch + +Patch305: qemu_timeouts_arches.patch +Patch308: node-gyp-config.patch +Patch309: gcc13.patch +Patch311: nodejs20-zlib-1.3.patch + +BuildRequires: pkg-config +BuildRequires: fdupes +BuildRequires: procps +BuildRequires: xz +BuildRequires: zlib-devel + +%if 0%{?suse_version} +BuildRequires: config(netcfg) +%endif + +# SLE-11 target only +# Node.js 6 requires GCC 4.8.5+. +# +# For Node.js 8.x, upstream requires GCC 4.9.4+, as GCC 4.8 may have +# slightly buggy C++11 support: https://github.com/nodejs/node/pull/13466 +# +# If the default compiler is not supported, use the most recent compiler +# version available. +%if 0%{?suse_version} == 1110 +# GCC 5 is only available in the SUSE:SLE-11:SP4:Update repository (SDK). +%if %node_version_number >= 8 +BuildRequires: gcc5-c++ +%define forced_gcc_version 5 +%else +BuildRequires: gcc48-c++ +%define forced_gcc_version 4.8 +%endif +%endif +# sles == 11 block + +# Pick and stick with "latest" compiler at time of LTS release +# for SLE-12:Update targets +%if 0%{?suse_version} == 1315 +%if %node_version_number >= 17 +BuildRequires: gcc12-c++ +%define forced_gcc_version 12 +%else +%if %node_version_number >= 14 +BuildRequires: gcc9-c++ +%define forced_gcc_version 9 +%else +%if %node_version_number >= 8 +BuildRequires: gcc7-c++ +%define forced_gcc_version 7 +%endif +%endif +%endif +%endif + +%if 0%{?suse_version} == 1500 +%if %node_version_number >= 17 +BuildRequires: gcc12-c++ +%define forced_gcc_version 12 +%endif +%endif +# compiler selection + +# No special version defined, use default. +%if ! 0%{?forced_gcc_version:1} +BuildRequires: gcc-c++ +%endif + + +# Python dependencies +%if %node_version_number >= 14 + +%if 0%{?suse_version} && 0%{?suse_version} < 1500 +BuildRequires: python36 +%define forced_python_version 3.6m +%else +BuildRequires: python3 +%endif + +%else +%if %node_version_number >= 12 +BuildRequires: python3 + +%else +%if 0%{?suse_version} >= 1500 +BuildRequires: python2 +%else +BuildRequires: python +%endif + +%endif +%endif + +%if 0%{?suse_version} >= 1500 && %{node_version_number} >= 10 +BuildRequires: user(nobody) +BuildRequires: group(nobody) +%endif + +# shared openssl +%if ! 0%{with intree_openssl} + +BuildRequires: pkgconfig(openssl) >= %{openssl_req_ver} + +%if 0%{?suse_version} + +%if 0%{?suse_version} >= 1500 +BuildRequires: openssl >= %{openssl_req_ver} +BuildRequires: (libopenssl1_1-hmac if libopenssl-1_1-devel) +BuildRequires: (libopenssl3-hmac if libopenssl-3-devel) +%else +BuildRequires: openssl-1_1 >= %{openssl_req_ver} +BuildRequires: libopenssl1_1-hmac +%endif + + +# /suse_version +%endif + +%if 0%{?fedora_version} +BuildRequires: openssl >= %{openssl_req_ver} +%endif + +%else +# bundled openssl +%if %node_version_number <= 12 && 0%{?suse_version} == 1315 && 0%{?sle_version} < 120400 +Provides: bundled(openssl) = 3.0.10 +%else +BuildRequires: bundled_openssl_should_not_be_required +%endif + +# /bundled openssl +%endif + +%if ! 0%{with intree_cares} +BuildRequires: pkgconfig(libcares) >= 1.17.0 +%else +Provides: bundled(libcares2) = 1.19.1 +%endif + +%if ! 0%{with intree_icu} +BuildRequires: pkgconfig(icu-i18n) >= 71 +%else +Provides: bundled(icu) = 73.2 +%endif + +%if ! 0%{with intree_nghttp2} +BuildRequires: libnghttp2-devel >= 1.41.0 +%else +Provides: bundled(nghttp2) = 1.57.0 +%endif + +%if 0%{with valgrind_tests} +BuildRequires: valgrind +%endif + +%if %{with libalternatives} +Suggests: alts +%else +Requires(postun): %{_sbindir}/update-alternatives +%endif +# either for update-alternatives, or their removal +Requires(post): %{_sbindir}/update-alternatives + +Recommends: npm20 + +#we need ABI virtual provides where SONAMEs aren't enough/not present so deps +#break when binary compatibility is broken +%global nodejs_abi 20.0 +Provides: nodejs(abi) = %{nodejs_abi} + +#this corresponds to the "engine" requirement in package.json +Provides: nodejs(engine) = %{version} + +# Multiple versions of NodeJS can be installed at a time, but +# to properly allow correct version execution from 3rd party +# npm software, `env node` requires further help than only +# update-alternatives can provide. +Provides: nodejs = %{version} +%if %{with libalternatives} +Requires: nodejs-common >= 5.0 +%else +Requires: nodejs-common +%endif + +# For SLE11, to be able to use the certificate store we need to have properly +# symlinked certificates. The compatability symlinks are provided by the +# openssl1 library in the Security Module +%if 0%{?suse_version} == 1110 +Requires: openssl1 +%endif + +%if %node_version_number >= 12 +%ifarch s390 +ExclusiveArch: not_buildable +%endif +%endif + +Provides: bundled(uvwasi) = 0.0.18 +Provides: bundled(libuv) = 1.46.0 +Provides: bundled(v8) = 11.3.244.8 +%if %{with intree_brotli} +Provides: bundled(brotli) = 1.0.9 +%else +BuildRequires: pkgconfig(libbrotlidec) +%endif + + +Provides: bundled(llhttp) = 8.1.1 +Provides: bundled(ngtcp2) = 0.8.1 +Provides: bundled(base64) = 0.5.0 +Provides: bundled(simdutf) = 3.2.17 +# bundled url-ada parser, not ada +Provides: bundled(ada) = 2.6.0 + +Provides: bundled(node-acorn) = 8.10.0 +Provides: bundled(node-acorn-walk) = 8.2.0 +Provides: bundled(node-balanced-match) = 1.0.2 +Provides: bundled(node-brace-expansion) = 2.0.1 +Provides: bundled(node-busboy) = 1.6.0 +Provides: bundled(node-cjs-module-lexer) = 1.2.2 +Provides: bundled(node-corepack) = 0.20.0 +Provides: bundled(node-minimatch) = 9.0.3 +Provides: bundled(node-streamsearch) = 1.1.0 +Provides: bundled(node-undici) = 5.26.3 +Provides: bundled(node-undici-types) = 5.25.1 + +%description +Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js +uses an event-driven, non-blocking I/O model. Node.js has a package ecosystem +provided by npm. + +%package devel +Summary: Development headers for NodeJS 20.x +Group: Development/Languages/NodeJS +Provides: nodejs-devel = %{version} +Requires: npm20 = %{version} +Requires: %{name} = %{version} + +%description devel +This package provides development headers for Node.js needed for creation +of binary modules. + +%package -n npm20 +Summary: Package manager for Node.js +Group: Development/Languages/NodeJS +%if %{with libalternatives} +Requires: nodejs-common >= 5.0 +%else +Requires: nodejs-common +%endif +Requires: nodejs20 = %{version} +Provides: nodejs-npm = %{version} +Obsoletes: nodejs-npm < 4.0.0 +Provides: npm(npm) = 10.1.0 +Provides: npm = %{version} +%if 0%{?suse_version} >= 1500 +%if %{node_version_number} >= 10 +Requires: user(nobody) +Requires: group(nobody) +%endif +%endif +Provides: bundled(node-abbrev) = 1.1.1 +Provides: bundled(node-abbrev) = 2.0.0 +Provides: bundled(node-abort-controller) = 3.0.0 +Provides: bundled(node-agent-base) = 6.0.2 +Provides: bundled(node-agent-base) = 7.1.0 +Provides: bundled(node-agentkeepalive) = 4.5.0 +Provides: bundled(node-aggregate-error) = 3.1.0 +Provides: bundled(node-ansi-regex) = 5.0.1 +Provides: bundled(node-ansi-regex) = 6.0.1 +Provides: bundled(node-ansi-styles) = 4.3.0 +Provides: bundled(node-ansi-styles) = 6.2.1 +Provides: bundled(node-aproba) = 2.0.0 +Provides: bundled(node-archy) = 1.0.0 +Provides: bundled(node-are-we-there-yet) = 3.0.1 +Provides: bundled(node-are-we-there-yet) = 4.0.0 +Provides: bundled(node-balanced-match) = 1.0.2 +Provides: bundled(node-base64-js) = 1.5.1 +Provides: bundled(node-bin-links) = 4.0.2 +Provides: bundled(node-binary-extensions) = 2.2.0 +Provides: bundled(node-brace-expansion) = 1.1.11 +Provides: bundled(node-brace-expansion) = 2.0.1 +Provides: bundled(node-buffer) = 6.0.3 +Provides: bundled(node-builtins) = 5.0.1 +Provides: bundled(node-cacache) = 17.1.4 +Provides: bundled(node-cacache) = 18.0.0 +Provides: bundled(node-chalk) = 5.3.0 +Provides: bundled(node-chownr) = 2.0.0 +Provides: bundled(node-ci-info) = 3.8.0 +Provides: bundled(node-cidr-regex) = 3.1.1 +Provides: bundled(node-clean-stack) = 2.2.0 +Provides: bundled(node-cli-columns) = 4.0.0 +Provides: bundled(node-cli-table3) = 0.6.3 +Provides: bundled(node-clone) = 1.0.4 +Provides: bundled(node-cmd-shim) = 6.0.1 +Provides: bundled(node-color-convert) = 2.0.1 +Provides: bundled(node-color-name) = 1.1.4 +Provides: bundled(node-color-support) = 1.1.3 +Provides: bundled(node-columnify) = 1.6.0 +Provides: bundled(node-common-ancestor-path) = 1.0.1 +Provides: bundled(node-concat-map) = 0.0.1 +Provides: bundled(node-console-control-strings) = 1.1.0 +Provides: bundled(node-cross-spawn) = 7.0.3 +Provides: bundled(node-cssesc) = 3.0.0 +Provides: bundled(node-debug) = 4.3.4 +Provides: bundled(node-defaults) = 1.0.4 +Provides: bundled(node-delegates) = 1.0.0 +Provides: bundled(node-diff) = 5.1.0 +Provides: bundled(node-eastasianwidth) = 0.2.0 +Provides: bundled(node-emoji-regex) = 8.0.0 +Provides: bundled(node-emoji-regex) = 9.2.2 +Provides: bundled(node-encoding) = 0.1.13 +Provides: bundled(node-env-paths) = 2.2.1 +Provides: bundled(node-err-code) = 2.0.3 +Provides: bundled(node-event-target-shim) = 5.0.1 +Provides: bundled(node-events) = 3.3.0 +Provides: bundled(node-exponential-backoff) = 3.1.1 +Provides: bundled(node-fastest-levenshtein) = 1.0.16 +Provides: bundled(node-foreground-child) = 3.1.1 +Provides: bundled(node-fs-minipass) = 2.1.0 +Provides: bundled(node-fs-minipass) = 3.0.3 +Provides: bundled(node-fs.realpath) = 1.0.0 +Provides: bundled(node-function-bind) = 1.1.1 +Provides: bundled(node-gauge) = 4.0.4 +Provides: bundled(node-gauge) = 5.0.1 +Provides: bundled(node-glob) = 10.3.3 +Provides: bundled(node-glob) = 7.2.3 +Provides: bundled(node-graceful-fs) = 4.2.11 +Provides: bundled(node-has) = 1.0.3 +Provides: bundled(node-has-unicode) = 2.0.1 +Provides: bundled(node-hosted-git-info) = 7.0.0 +Provides: bundled(node-http-cache-semantics) = 4.1.1 +Provides: bundled(node-http-proxy-agent) = 5.0.0 +Provides: bundled(node-http-proxy-agent) = 7.0.0 +Provides: bundled(node-https-proxy-agent) = 5.0.1 +Provides: bundled(node-https-proxy-agent) = 7.0.1 +Provides: bundled(node-humanize-ms) = 1.2.1 +Provides: bundled(node-iconv-lite) = 0.6.3 +Provides: bundled(node-ieee754) = 1.2.1 +Provides: bundled(node-ignore-walk) = 6.0.3 +Provides: bundled(node-imurmurhash) = 0.1.4 +Provides: bundled(node-indent-string) = 4.0.0 +Provides: bundled(node-inflight) = 1.0.6 +Provides: bundled(node-inherits) = 2.0.4 +Provides: bundled(node-ini) = 4.1.1 +Provides: bundled(node-init-package-json) = 6.0.0 +Provides: bundled(node-ip) = 2.0.0 +Provides: bundled(node-ip-regex) = 4.3.0 +Provides: bundled(node-is-cidr) = 4.0.2 +Provides: bundled(node-is-core-module) = 2.12.1 +Provides: bundled(node-is-fullwidth-code-point) = 3.0.0 +Provides: bundled(node-is-lambda) = 1.0.1 +Provides: bundled(node-isexe) = 2.0.0 +Provides: bundled(node-isexe) = 3.1.1 +Provides: bundled(node-jackspeak) = 2.2.1 +Provides: bundled(node-json-parse-even-better-errors) = 3.0.0 +Provides: bundled(node-json-stringify-nice) = 1.1.4 +Provides: bundled(node-jsonparse) = 1.3.1 +Provides: bundled(node-just-diff) = 6.0.2 +Provides: bundled(node-just-diff-apply) = 5.5.0 +Provides: bundled(node-libnpmaccess) = 8.0.0 +Provides: bundled(node-libnpmdiff) = 6.0.1 +Provides: bundled(node-libnpmexec) = 7.0.1 +Provides: bundled(node-libnpmfund) = 4.1.1 +Provides: bundled(node-libnpmhook) = 10.0.0 +Provides: bundled(node-libnpmorg) = 6.0.0 +Provides: bundled(node-libnpmpack) = 6.0.1 +Provides: bundled(node-libnpmpublish) = 9.0.0 +Provides: bundled(node-libnpmsearch) = 7.0.0 +Provides: bundled(node-libnpmteam) = 6.0.0 +Provides: bundled(node-libnpmversion) = 5.0.0 +Provides: bundled(node-lru-cache) = 10.0.1 +Provides: bundled(node-lru-cache) = 6.0.0 +Provides: bundled(node-lru-cache) = 7.18.3 +Provides: bundled(node-make-fetch-happen) = 11.1.1 +Provides: bundled(node-make-fetch-happen) = 13.0.0 +Provides: bundled(node-minimatch) = 3.1.2 +Provides: bundled(node-minimatch) = 9.0.3 +Provides: bundled(node-minipass) = 3.3.6 +Provides: bundled(node-minipass) = 5.0.0 +Provides: bundled(node-minipass) = 7.0.3 +Provides: bundled(node-minipass-collect) = 1.0.2 +Provides: bundled(node-minipass-fetch) = 3.0.4 +Provides: bundled(node-minipass-flush) = 1.0.5 +Provides: bundled(node-minipass-json-stream) = 1.0.1 +Provides: bundled(node-minipass-pipeline) = 1.2.4 +Provides: bundled(node-minipass-sized) = 1.0.3 +Provides: bundled(node-minizlib) = 2.1.2 +Provides: bundled(node-mkdirp) = 1.0.4 +Provides: bundled(node-ms) = 2.1.2 +Provides: bundled(node-ms) = 2.1.3 +Provides: bundled(node-mute-stream) = 1.0.0 +Provides: bundled(node-negotiator) = 0.6.3 +Provides: bundled(node-node-gyp) = 9.4.0 +Provides: bundled(node-nopt) = 6.0.0 +Provides: bundled(node-nopt) = 7.2.0 +Provides: bundled(node-normalize-package-data) = 6.0.0 +Provides: bundled(node-npm-audit-report) = 5.0.0 +Provides: bundled(node-npm-bundled) = 3.0.0 +Provides: bundled(node-npm-install-checks) = 6.2.0 +Provides: bundled(node-npm-normalize-package-bin) = 3.0.1 +Provides: bundled(node-npm-package-arg) = 11.0.0 +Provides: bundled(node-npm-packlist) = 8.0.0 +Provides: bundled(node-npm-pick-manifest) = 9.0.0 +Provides: bundled(node-npm-profile) = 9.0.0 +Provides: bundled(node-npm-registry-fetch) = 16.0.0 +Provides: bundled(node-npm-user-validate) = 2.0.0 +Provides: bundled(node-npmlog) = 6.0.2 +Provides: bundled(node-npmlog) = 7.0.1 +Provides: bundled(node-once) = 1.4.0 +Provides: bundled(node-p-map) = 4.0.0 +Provides: bundled(node-pacote) = 17.0.4 +Provides: bundled(node-parse-conflict-json) = 3.0.1 +Provides: bundled(node-path-is-absolute) = 1.0.1 +Provides: bundled(node-path-key) = 3.1.1 +Provides: bundled(node-path-scurry) = 1.10.1 +Provides: bundled(node-postcss-selector-parser) = 6.0.13 +Provides: bundled(node-proc-log) = 3.0.0 +Provides: bundled(node-process) = 0.11.10 +Provides: bundled(node-promise-all-reject-late) = 1.0.1 +Provides: bundled(node-promise-call-limit) = 1.0.2 +Provides: bundled(node-promise-inflight) = 1.0.1 +Provides: bundled(node-promise-retry) = 2.0.1 +Provides: bundled(node-promzard) = 1.0.0 +Provides: bundled(node-qrcode-terminal) = 0.12.0 +Provides: bundled(node-read) = 2.1.0 +Provides: bundled(node-read-cmd-shim) = 4.0.0 +Provides: bundled(node-read-package-json) = 7.0.0 +Provides: bundled(node-read-package-json-fast) = 3.0.2 +Provides: bundled(node-readable-stream) = 3.6.2 +Provides: bundled(node-readable-stream) = 4.4.0 +Provides: bundled(node-retry) = 0.12.0 +Provides: bundled(node-rimraf) = 3.0.2 +Provides: bundled(node-safe-buffer) = 5.2.1 +Provides: bundled(node-safer-buffer) = 2.1.2 +Provides: bundled(node-semver) = 7.5.4 +Provides: bundled(node-set-blocking) = 2.0.0 +Provides: bundled(node-shebang-command) = 2.0.0 +Provides: bundled(node-shebang-regex) = 3.0.0 +Provides: bundled(node-signal-exit) = 3.0.7 +Provides: bundled(node-signal-exit) = 4.0.2 +Provides: bundled(node-sigstore) = 2.1.0 +Provides: bundled(node-smart-buffer) = 4.2.0 +Provides: bundled(node-socks) = 2.7.1 +Provides: bundled(node-socks-proxy-agent) = 7.0.0 +Provides: bundled(node-socks-proxy-agent) = 8.0.1 +Provides: bundled(node-spdx-correct) = 3.2.0 +Provides: bundled(node-spdx-exceptions) = 2.3.0 +Provides: bundled(node-spdx-expression-parse) = 3.0.1 +Provides: bundled(node-spdx-license-ids) = 3.0.13 +Provides: bundled(node-ssri) = 10.0.5 +Provides: bundled(node-string_decoder) = 1.3.0 +Provides: bundled(node-string-width) = 4.2.3 +Provides: bundled(node-string-width) = 5.1.2 +Provides: bundled(node-strip-ansi) = 6.0.1 +Provides: bundled(node-strip-ansi) = 7.1.0 +Provides: bundled(node-supports-color) = 9.4.0 +Provides: bundled(node-tar) = 6.1.15 +Provides: bundled(node-text-table) = 0.2.0 +Provides: bundled(node-tiny-relative-date) = 1.3.0 +Provides: bundled(node-treeverse) = 3.0.0 +Provides: bundled(node-tuf-js) = 2.1.0 +Provides: bundled(node-unique-filename) = 3.0.0 +Provides: bundled(node-unique-slug) = 4.0.0 +Provides: bundled(node-util-deprecate) = 1.0.2 +Provides: bundled(node-validate-npm-package-license) = 3.0.4 +Provides: bundled(node-validate-npm-package-name) = 5.0.0 +Provides: bundled(node-walk-up-path) = 3.0.1 +Provides: bundled(node-wcwidth) = 1.0.1 +Provides: bundled(node-which) = 2.0.2 +Provides: bundled(node-which) = 4.0.0 +Provides: bundled(node-wide-align) = 1.1.5 +Provides: bundled(node-wrap-ansi) = 7.0.0 +Provides: bundled(node-wrap-ansi) = 8.1.0 +Provides: bundled(node-wrappy) = 1.0.2 +Provides: bundled(node-write-file-atomic) = 5.0.1 +Provides: bundled(node-yallist) = 4.0.0 + +%description -n npm20 +A package manager for Node.js that allows developers to install and +publish packages to a package registry. + +%package -n corepack20 +Summary: Helper bridge between NodeJS projects and their dependencies +Group: Development/Languages/NodeJS +Requires: nodejs-common >= 5.0 + +%description -n corepack20 +Zero-runtime-dependency package acting as bridge between Node projects +and their package managers. + +%package docs +Summary: Node.js API documentation +Group: Documentation/Other +%if 0%{?suse_version} >= 1200 +# using noarch subpackage seems to break debuginfo on older releases +BuildArch: noarch +%endif + +%description docs +The API documentation for the Node.js JavaScript runtime. + +%prep +%if ! %{git_node} +echo "`grep node-v%{version}.tar.xz %{S:1} | head -n1 | cut -c1-64` %{S:0}" | sha256sum -c +%setup -q -n node-v%{version} +%else +%setup -q -n node-%{version} +%endif + +%if %{node_version_number} == 16 +tar zxf %{S:12} +%endif + +%if %{node_version_number} <= 10 +rm -r deps/npm/* +pushd deps/npm +tar zxf %{SOURCE9} --strip-components=1 +tar Jxf %{SOURCE90} +popd +%endif + +%if %{node_version_number} >= 10 +tar Jxf %{SOURCE11} +%endif + +# downgrade node-gyp to last version that supports python 3.4 for SLE12 +%if 0%{?suse_version} && 0%{?suse_version} < 1500 && %{node_version_number} >= 16 +rm -r deps/npm/node_modules/node-gyp +mkdir deps/npm/node_modules/node-gyp +pushd deps/npm/node_modules/node-gyp +tar Jxf %{SOURCE5} +popd + +%if %{node_version_number} >= 19 +%patch308 -p1 +%endif +%endif + +%patch1 -p1 +%patch3 -p1 +%if %{node_version_number} <= 12 && 0%{?suse_version} < 1500 +%patch5 -p1 +%endif +%patch7 -p1 +%if 0%{with valgrind_tests} +%endif +%patch13 -p1 +%patch100 -p1 +%patch101 -p1 +%patch102 -p1 +# Add check_output to configure script (not part of Python 2.6 in SLE11). +%if 0%{?suse_version} == 1110 +%endif +%patch104 -p1 +%patch106 -p1 +%patch110 -p1 +%patch120 -p1 +%patch132 -p1 +%if ! 0%{with openssl_RSA_get0_pss_params} +%endif +%patch200 -p1 + +%patch305 -p1 +%patch309 -p1 +%patch311 -p1 + +%if %{node_version_number} == 12 +# minimist security update - patch50 +rm -r deps/npm/node_modules/mkdirp/node_modules/minimist +rmdir ./deps/npm/node_modules/mkdirp/node_modules +%endif + +# remove backup files, if any +find -name \*~ -print0 -delete + +# abnormalities from patching +find \( -name \*.js.orig -or -name \*.md.orig -or -name \*.1.orig \) -delete + + + +%build +# normalize shebang +%if %{node_version_number} >= 12 +find -type f -exec sed -i -e '1 s,^#!\s\?/usr/bin/env python\d*$,#!/usr/bin/python3,' -e '1 s,^#!\s\?/usr/bin/python$,#!/usr/bin/python3,' {} + +%else +find -type f -exec sed -i '1 s,^#!\s\?/usr/bin/env python$,#!/usr/bin/python,' {} + +%endif +find deps/npm -type f -exec sed -i '1 s,^#!\s\?/usr/bin/env node$,#!/usr/bin/node%{node_version_number},' {} + +find deps/npm -type f -exec sed -i '1 s,^#!\s\?/usr/bin/env \(bash\|sh\)\?$,#!/bin/bash,' {} + + +. %{SOURCE20} +# Make sure nothing gets included from bundled deps: +# We only delete the source and header files, because +# the remaining build scripts are still used. +%if ! 0%{with intree_openssl} +find deps/openssl -name *.[ch] -delete +%endif + +%if ! 0%{with intree_icu} +rm -rf deps/icu-small +%endif + +%if ! 0%{with intree_cares} +find deps/cares -name *.[ch] -delete +%endif + +find deps/zlib -name *.[ch] -delete + +cat > spec.build.config <= 8 || 0%{?suse_version} > 1500 || 0%{?fedora_version} >= 35 +export CXXFLAGS="\${CXXFLAGS} -Wno-class-memaccess" +%endif +export LDFLAGS="%{?build_ldflags}" + +%if !0%{?with nodejs_lto} +export LDFLAGS="\${LDFLAGS} -fno-lto" +%endif + +# reduce disk space pressure +export CFLAGS="\${CFLAGS} -g1" +export CXXFLAGS="\${CXXFLAGS} -g1" +export LDFLAGS="\${LDFLAGS} -Wl,--reduce-memory-overhead" + +%if 0%{?forced_gcc_version:1} +export CC=gcc-%{forced_gcc_version} +export CXX=g++-%{forced_gcc_version} +%endif + +EOF + +. ./spec.build.config + +# Node.js 4.x does not include the ICU database in the source tarball. +%define has_small_icu %(test -d "deps/icu-small" && echo 1 || echo 0) + +./configure \ + --prefix=%{_prefix} \ +%if 0%{?with nodejs_lto} + --enable-lto \ +%endif +%if ! 0%{with intree_openssl} + --shared-openssl \ +%endif + --shared-zlib \ +%if ! 0%{with intree_cares} + --shared-cares \ +%endif +%if ! 0%{with intree_icu} + --with-intl=system-icu \ +%else +%if %{has_small_icu} + --with-intl=small-icu \ + --with-icu-source=deps/icu-small \ +%endif +%endif +%if ! 0%{with intree_nghttp2} + --shared-nghttp2 \ +%endif +%if ! 0%{with intree_brotli} + --shared-brotli \ +%endif +%if 0%{with gdb} + --gdb \ +%endif +%if %{node_version_number} < 19 + --without-dtrace \ +%endif +%if %{node_version_number} >= 16 && (0%{?suse_version} > 1550 || 0%{?sle_version} >= 150400) + --openssl-default-cipher-list=PROFILE=SYSTEM \ +%endif + --openssl-use-def-ca-store + +decoupled_cmd make %{?_smp_mflags} + +# Fix documentation permissions +find doc/api -type f -exec chmod 0644 {} + + +%install +. %{SOURCE20} +. ./spec.build.config + +decoupled_cmd %make_install %{?_smp_mflags} +rm %{buildroot}%{_datadir}/doc/node/gdbinit +rm -f %{buildroot}%{_datadir}/doc/node/lldbinit +rm -f %{buildroot}%{_datadir}/doc/node/lldb_commands.py + +# remove .bak files, if any +find %{buildroot} -name \*.bak -print -delete + +# npm/npx man page +install -D -m 644 deps/npm/man/man1/npm.1 %{buildroot}%{_mandir}/man1/npm%{node_version_number}.1 +install -D -m 644 deps/npm/man/man1/npx.1 %{buildroot}%{_mandir}/man1/npx%{node_version_number}.1 + +#node-gyp needs common.gypi too +install -D -m 644 common.gypi \ + %{buildroot}%{_libdir}/node_modules/npm%{node_version_number}/node_modules/node-gyp/common.gypi +# %%{buildroot}%%{_datadir}/node/common.gypi +# install addon-rpm.gypi +install -D -m 644 addon-rpm.gypi \ + %{buildroot}%{_libdir}/node_modules/npm%{node_version_number}/node_modules/node-gyp/addon-rpm.gypi + +# clean +# hidden files and directories +find %{buildroot}%{_libdir}/node_modules/npm%{node_version_number} -name ".*" -exec rm -Rf -- {} + +# windows stuff +find %{buildroot}%{_libdir}/node_modules/npm%{node_version_number} -name "*.bat" -delete +find %{buildroot}%{_libdir}/node_modules/npm%{node_version_number} -name "*.cmd" -delete +# build stuff +find %{buildroot}%{_libdir}/node_modules/npm%{node_version_number} -name "Makefile" -delete +rm -rf %{buildroot}%{_libdir}/node_modules/npm%{node_version_number}/{test,scripts} +find %{buildroot}%{_libdir}/node_modules/npm%{node_version_number}/node_modules -name "*.sh" -delete +rm -rf %{buildroot}%{_libdir}/node_modules/npm%{node_version_number}/node_modules/node-gyp/src +# remove examples/tests/benchmark stuff +find %{buildroot}%{_libdir}/node_modules/npm%{node_version_number}/node_modules -name "example*" -exec rm -Rf -- {} + +find %{buildroot}%{_libdir}/node_modules/npm%{node_version_number}/node_modules -name "*_test.*" -delete +find %{buildroot}%{_libdir}/node_modules/npm%{node_version_number}/node_modules -type d -name "benchmark" -exec rm -Rf -- {} + + +# fix permissions +chmod 0755 %{buildroot}%{_libdir}/node_modules/npm%{node_version_number}/bin/np*-cli.js +! test -f %{buildroot}%{_libdir}/node_modules/npm%{node_version_number}/bin/node-gyp-bin/node-gyp || \ + chmod 0755 %{buildroot}%{_libdir}/node_modules/npm%{node_version_number}/bin/node-gyp-bin/node-gyp +chmod 0755 %{buildroot}%{_libdir}/node_modules/npm%{node_version_number}/node_modules/node-gyp/bin/node-gyp.js +! test -f %{buildroot}%{_libdir}/node_modules/npm%{node_version_number}/node_modules/npm-lifecycle/node-gyp-bin/node-gyp || \ + chmod 0755 %{buildroot}%{_libdir}/node_modules/npm%{node_version_number}/node_modules/npm-lifecycle/node-gyp-bin/node-gyp + +# browser.js is useless for npm cli +find %{buildroot}%{_libdir}/node_modules/npm%{node_version_number} -name "browser.js" -delete + +# file duplicates +%fdupes %{buildroot}%{_libdir}/node_modules/npm%{node_version_number} +%fdupes %{buildroot}%{_includedir}/node%{node_version_number} + +# Update alternatives +%if ! %{with libalternatives} +mkdir -p %{buildroot}%{_sysconfdir}/alternatives +ln -s -f node-default %{buildroot}%{_sysconfdir}/alternatives/node-default +ln -s -f node.1%{ext_man} %{buildroot}%{_sysconfdir}/alternatives/node.1%{ext_man} +ln -s -f npm-default %{buildroot}%{_sysconfdir}/alternatives/npm-default +ln -s -f npm.1%{ext_man} %{buildroot}%{_sysconfdir}/alternatives/npm.1%{ext_man} +ln -s %{_sysconfdir}/alternatives/node-default %{buildroot}%{_bindir}/node-default +ln -s %{_sysconfdir}/alternatives/node.1%{ext_man} %{buildroot}%{_mandir}/man1/node.1%{ext_man} +ln -s %{_sysconfdir}/alternatives/npm-default %{buildroot}%{_bindir}/npm-default +ln -s %{_sysconfdir}/alternatives/npm.1%{ext_man} %{buildroot}%{_mandir}/man1/npm.1%{ext_man} +ln -s -f npx-default %{buildroot}%{_sysconfdir}/alternatives/npx-default +ln -s -f npx.1%{ext_man} %{buildroot}%{_sysconfdir}/alternatives/npx.1%{ext_man} +ln -s %{_sysconfdir}/alternatives/npx-default %{buildroot}%{_bindir}/npx-default +ln -s %{_sysconfdir}/alternatives/npx.1%{ext_man} %{buildroot}%{_mandir}/man1/npx.1%{ext_man} +%endif + +# libalternatives - can always ship +mkdir -p %{buildroot}%{_datadir}/libalternatives/{node,npm,npx}; +cat > %{buildroot}%{_datadir}/libalternatives/node/%{node_version_number}.conf < %{buildroot}%{_datadir}/libalternatives/npm/%{node_version_number}.conf < %{buildroot}%{_datadir}/libalternatives/npx/%{node_version_number}.conf <= 12 +find test \( -name \*.out -or -name \*.js \) -exec sed -i 's,Use `node ,Use `node%{node_version_number} ,' {} \; +%endif + +%if %{node_version_number} >= 20 +rm test/parallel/test-strace-openat-openssl.js +%endif + +# Update the python3 executable name to point at forced python version +# needed to fix build on SLE12 SP5 +%if 0%{?forced_python_version:1} +sed -i -e "s,'python3','python%{forced_python_version}'," test/parallel/test-child-process-set-blocking.js +test -e tools/pseudo-tty.py && sed -i -e "s,^#!/usr/bin/env python3$,#!/usr/bin/python%{forced_python_version}," tools/pseudo-tty.py ||: +%endif + +ln addon-rpm.gypi deps/npm/node_modules/node-gyp/addon-rpm.gypi +# Tarball doesn't have eslint package distributed, so disable some tests +find test -name \*-eslint-\* -print -delete +# No documentation is generated, don't bother checking it, and check broken on older nodejs +%if %{node_version_number} <= 10 +rm test/doctool/test-make-doc.js +%endif +# DNS lookup doesn't work in build root +rm test/parallel/test-dns-cancel-reverse-lookup.js \ + test/parallel/test-dns-resolveany.js +# multicast test fail since no socket? +rm test/parallel/test-dgram-membership.js + +%if %{node_version_number} >= 18 +# OBS broken /etc/hosts -- https://github.com/openSUSE/open-build-service/issues/13104 +rm test/parallel/test-net-socket-connect-without-cb.js test/parallel/test-tcp-wrap-listen.js +%endif + +%if 0%{?fedora_version} +# test/parallel/test-crypto-certificate.js requires OPENSSL_ENABLE_MD5_VERIFY=1 +# as SPKAC required MD5 for verification +# https://src.fedoraproject.org/rpms/openssl/blob/rawhide/f/0006-Disable-signature-verification-with-totally-unsafe-h.patch +export OPENSSL_ENABLE_MD5_VERIFY=1 + +# test failures +# error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake +# failure:ssl/record/rec_layer_s3.c:1543:SSL alert number 40 +rm test/parallel/test-tls-no-sslv3.js +%if %{node_version_number} >= 18 +rm -r test/addons/openssl-providers +rm test/parallel/test-crypto-fips.js +%endif + +%endif +# fedora + +# qemu test failures +%if %{node_version_number} >= 18 && 0%{?qemu_user_space_build} +# sequential/test-debugger-*: timeout hit? +rm -v test/*/test-debugger-*.js +# parallel tests are not parallel under qemu +rm -v test/parallel/test-*.js test/parallel/test-*.mjs +# RuntimeError: memory access out of bounds +rm -v test/wasi/test-*.js +# ESM import hits assertion, timeout error? +rm -v test/es-module/test-esm-*.js +# AssertionError [ERR_ASSERTION]: Missing expected exception +rm -v test/js-native-api/test_constructor/test*.js +# Too slow for performance tests +rm -v test/sequential/test-perf-*.js test/sequential/test-diagnostic-*.js +%endif + +# Run CI tests +%if 0%{with valgrind_tests} +# valgrind may have false positives, so do not fail on these by default +make test-valgrind ||: +%endif +make test-ci + +%files +%defattr(-, root, root) +%license LICENSE +%doc doc/changelogs/CHANGELOG_V%{node_version_number}.md +%doc *.md +%doc deps/v8/tools/gdbinit +%dir %{_libdir}/node_modules +%dir %{_datadir}/libalternatives +%dir %{_datadir}/libalternatives/node +%{_datadir}/libalternatives/node/%{node_version_number}.conf +%{_bindir}/node%{node_version_number} +%{_mandir}/man1/node%{node_version_number}.1%{ext_man} +%if ! 0%{with libalternatives} +%ghost %{_bindir}/node-default +%ghost %{_mandir}/man1/node.1%{ext_man} +%ghost %{_sysconfdir}/alternatives/node-default +%ghost %{_sysconfdir}/alternatives/node.1%{ext_man} +%endif +%exclude %{_libdir}/node_modules/npm%{node_version_number} +# We need to own directory on old versions of SLE +%if 0%{?suse_version} < 1500 +%dir %{_defaultlicensedir} +%endif + +%files -n npm%{node_version_number} +%defattr(-, root, root) +%dir %{_datadir}/libalternatives +%dir %{_datadir}/libalternatives/npm +%dir %{_datadir}/libalternatives/npx +%{_datadir}/libalternatives/npm/%{node_version_number}.conf +%{_datadir}/libalternatives/npx/%{node_version_number}.conf +%{_bindir}/npm%{node_version_number} +%{_libdir}/node_modules/npm%{node_version_number} +%{_mandir}/man1/npm%{node_version_number}.1%{ext_man} +%if ! 0%{with libalternatives} +%ghost %{_bindir}/npm-default +%ghost %{_mandir}/man1/npm.1%{ext_man} +%ghost %{_sysconfdir}/alternatives/npm-default +%ghost %{_sysconfdir}/alternatives/npm.1%{ext_man} +%endif + +%{_bindir}/npx%{node_version_number} +%{_mandir}/man1/npx%{node_version_number}.1%{ext_man} +%if ! %{with libalternatives} +%ghost %{_bindir}/npx-default +%ghost %{_mandir}/man1/npx.1%{ext_man} +%ghost %{_sysconfdir}/alternatives/npx-default +%ghost %{_sysconfdir}/alternatives/npx.1%{ext_man} +%endif + +%if %{node_version_number} >= 14 +%files -n corepack%{node_version_number} +%defattr(-, root, root) +%{_bindir}/corepack%{node_version_number} +%{_libdir}/node_modules/corepack%{node_version_number} +%endif + +%files devel +%defattr(-, root, root) +%{_includedir}/node%{node_version_number} +%if %{node_version_number} < 19 +%dir %{_datadir}/systemtap +%dir %{_datadir}/systemtap/tapset +%{_datadir}/systemtap/tapset/node%{node_version_number}.stp +%endif + +%files docs +%defattr(-,root,root) +%doc doc/api + +%if %{with libalternatives} + +%post +update-alternatives --remove node-default %{_bindir}/node%{node_version_number} + +%post -n npm%{node_version_number} +update-alternatives --remove npm-default %{_bindir}/npm%{node_version_number} +update-alternatives --remove npx-default %{_bindir}/npx%{node_version_number} + +%else +%pre +# remove files that are no longer owned but provided by update-alternatives +if ! [ -L %{_mandir}/man1/node.1%{ext_man} ]; then + rm -f %{_mandir}/man1/node.1%{ext_man} +fi + +%post +update-alternatives \ + --install %{_bindir}/node-default node-default %{_bindir}/node%{node_version_number} %{node_version_number} \ + --slave %{_mandir}/man1/node.1%{ext_man} node.1%{ext_man} %{_mandir}/man1/node%{node_version_number}.1%{ext_man} + +%postun +if [ ! -f %{_bindir}/node%{node_version_number} ] ; then + update-alternatives --remove node-default %{_bindir}/node%{node_version_number} +fi + +%pre -n npm%{node_version_number} +# remove files that are no longer owned but provided by update-alternatives +if ! [ -L %{_mandir}/man1/npm.1%{ext_man} ]; then + rm -f %{_mandir}/man1/npm.1%{ext_man} +fi + +%post -n npm%{node_version_number} +update-alternatives \ + --install %{_bindir}/npm-default npm-default %{_bindir}/npm%{node_version_number} %{node_version_number} \ + --slave %{_mandir}/man1/npm.1%{ext_man} npm.1%{ext_man} %{_mandir}/man1/npm%{node_version_number}.1%{ext_man} +update-alternatives \ + --install %{_bindir}/npx-default npx-default %{_bindir}/npx%{node_version_number} %{node_version_number} \ + --slave %{_mandir}/man1/npx.1%{ext_man} npx.1%{ext_man} %{_mandir}/man1/npx%{node_version_number}.1%{ext_man} + +%postun -n npm%{node_version_number} +if [ ! -f %{_bindir}/npm%{node_version_number} ] ; then + update-alternatives --remove npm-default %{_bindir}/npm%{node_version_number} +fi +if [ ! -f %{_bindir}/npx%{node_version_number} ] ; then + update-alternatives --remove npx-default %{_bindir}/npx%{node_version_number} +fi + +%endif + +%changelog diff --git a/npm_search_paths.patch b/npm_search_paths.patch new file mode 100644 index 0000000..9ee3d33 --- /dev/null +++ b/npm_search_paths.patch @@ -0,0 +1,32 @@ +Index: node-v19.9.0/deps/npm/lib/commands/help-search.js +=================================================================== +--- node-v19.9.0.orig/deps/npm/lib/commands/help-search.js ++++ node-v19.9.0/deps/npm/lib/commands/help-search.js +@@ -16,7 +16,7 @@ class HelpSearch extends BaseCommand { + throw this.usageError() + } + +- const docPath = path.resolve(this.npm.npmRoot, 'docs/content') ++ const docPath = '/usr/share/doc/packages/nodejs' + let files = await glob(`${globify(docPath)}/*/*.md`) + // preserve glob@8 behavior + files = files.sort((a, b) => a.localeCompare(b, 'en')) +Index: node-v19.9.0/deps/npm/lib/npm.js +=================================================================== +--- node-v19.9.0.orig/deps/npm/lib/npm.js ++++ node-v19.9.0/deps/npm/lib/npm.js +@@ -408,7 +408,13 @@ class Npm extends EventEmitter { + } + + get globalPrefix () { +- return this.config.globalPrefix ++ let prefix = this.config.globalPrefix ++ ++ // don't poop all over distro territory - use /usr/local instead ++ if (prefix === '/usr') ++ return '/usr/local' ++ ++ return prefix; + } + + set globalPrefix (r) { diff --git a/openssl_binary_detection.patch b/openssl_binary_detection.patch new file mode 100644 index 0000000..c13bb13 --- /dev/null +++ b/openssl_binary_detection.patch @@ -0,0 +1,42 @@ +Allow non-standard openssl binary names + +Index: node-v14.15.1/test/common/index.js +=================================================================== +--- node-v14.15.1.orig/test/common/index.js ++++ node-v14.15.1/test/common/index.js +@@ -797,20 +797,28 @@ const common = { + get opensslCli() { + if (opensslCli !== null) return opensslCli; + ++ let cli_candidates = []; ++ + if (process.config.variables.node_shared_openssl) { + // Use external command +- opensslCli = 'openssl'; ++ cli_candidates = cli_candidates.concat(['openssl-1_1', 'openssl']); + } else { + // Use command built from sources included in Node.js repository +- opensslCli = path.join(path.dirname(process.execPath), 'openssl-cli'); ++ cli_candidates.push(path.join(path.dirname(process.execPath), 'openssl-cli')); + } + +- if (exports.isWindows) opensslCli += '.exe'; ++ let checkOpensslCli = function(opensslCli) { ++ if (exports.isWindows) opensslCli += '.exe'; ++ const opensslCmd = spawnSync(opensslCli, ['version']); ++ if (opensslCmd.status !== 0 || opensslCmd.error !== undefined) { ++ // OpenSSL command cannot be executed ++ opensslCli = false; ++ } ++ return opensslCli; ++ }; + +- const opensslCmd = spawnSync(opensslCli, ['version']); +- if (opensslCmd.status !== 0 || opensslCmd.error !== undefined) { +- // OpenSSL command cannot be executed +- opensslCli = false; ++ for (let i=0; i=3.6.0', ++ semverRange: '>=3.4.0', + + // These can be overridden for testing: + execFile: cp.execFile, diff --git a/test-skip-y2038-on-32bit-time_t.patch b/test-skip-y2038-on-32bit-time_t.patch new file mode 100644 index 0000000..1e3b16b --- /dev/null +++ b/test-skip-y2038-on-32bit-time_t.patch @@ -0,0 +1,45 @@ +Skip 'test/parallel/test-fs-utimes-y2K38.js' on some platforms. + +This test fails if coreutils' touch was built with 64-bit time_t, +while nodejs was built with 32-bit time_t. This is currently the case +on i586, ppc and arm. Skip the failing last command on those +platforms. + +The failure was seen since coreutils-9.0. + +Remove this patch once nodejs(1) also builds with 64-bit time_t. +--- + test/parallel/test-fs-utimes-y2K38.js | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +Index: node-v16.6.2/test/parallel/test-fs-utimes-y2K38.js +=================================================================== +--- node-v16.6.2.orig/test/parallel/test-fs-utimes-y2K38.js ++++ node-v16.6.2/test/parallel/test-fs-utimes-y2K38.js +@@ -20,6 +20,26 @@ if (!common.isWindows) { + common.skip('File system appears to lack Y2K38 support (touch failed)'); + } + ++ // SUSE: touch-9.0 may succeed on platforms with 32-bit time_t, ++ // but the test would fail. Skip on those platforms for now. ++ const unameResult = spawnSync('uname', ++ ['-m'], ++ { encoding: 'utf8' }); ++ if (unameResult.status === 0) { ++ if (unameResult.stdout.trim() === 'i686') { ++ common.skip('SUSE: test skipped on platforms with 32-bit time_t'); ++ } ++ if (unameResult.stdout.trim() === 'ppc') { ++ common.skip('SUSE: test skipped on platforms with 32-bit time_t'); ++ } ++ if (unameResult.stdout.trim() === 'armv6l') { ++ common.skip('SUSE: test skipped on platforms with 32-bit time_t'); ++ } ++ if (unameResult.stdout.trim() === 'armv7l') { ++ common.skip('SUSE: test skipped on platforms with 32-bit time_t'); ++ } ++ } ++ + // On some file systems that lack Y2K38 support, `touch` will succeed but + // the time will be incorrect. + const dateResult = spawnSync('date', diff --git a/update_npm_tarball.sh b/update_npm_tarball.sh new file mode 100644 index 0000000..342bcc3 --- /dev/null +++ b/update_npm_tarball.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# +# Fetch npm module tarball that is required to run unit tests +# which are not provided by upstream tarball +# +set -e + +tar Jxf node-v*.tar.xz +cd node-v.*/tools/doc +npm ci +cd ../.. +exec tar Jcf ../node_modules.tar.xz tools/doc/node_modules diff --git a/versioned.patch b/versioned.patch new file mode 100644 index 0000000..10023db --- /dev/null +++ b/versioned.patch @@ -0,0 +1,188 @@ +Author: Adam Majer +Date: Fri May 11 16:10:16 CEST 2018 +Summary: Generate versioned binaries + +Generate versioned binaries and install paths +so we can allow concurrent installations and +management via update_alternatives. + +This is also important for generation of binary +modules for multiple versions of NodeJS +Index: node-v20.5.1/Makefile +=================================================================== +--- node-v20.5.1.orig/Makefile ++++ node-v20.5.1/Makefile +@@ -76,7 +76,7 @@ BUILDTYPE_LOWER := $(shell echo $(BUILDT + EXEEXT := $(shell $(PYTHON) -c \ + "import sys; print('.exe' if sys.platform == 'win32' else '')") + +-NODE_EXE = node$(EXEEXT) ++NODE_EXE = node20$(EXEEXT) + NODE ?= ./$(NODE_EXE) + NODE_G_EXE = node_g$(EXEEXT) + NPM ?= ./deps/npm/bin/npm-cli.js +Index: node-v20.5.1/tools/install.py +=================================================================== +--- node-v20.5.1.orig/tools/install.py ++++ node-v20.5.1/tools/install.py +@@ -86,7 +86,7 @@ def uninstall(paths, dst): + try_remove(path, dst) + + def package_files(action, name, bins): +- target_path = libdir() + '/node_modules/' + name + '/' ++ target_path = libdir() + '/node_modules/' + name + '20/' + + # don't install npm if the target path is a symlink, it probably means + # that a dev version of npm is installed there +@@ -106,19 +106,19 @@ def package_files(action, name, bins): + if action == uninstall: + action([link_path], 'bin/' + bin_name) + elif action == install: +- try_symlink('../' + libdir() + '/node_modules/' + name + '/' + bin_target, link_path) ++ try_symlink('../' + libdir() + '/node_modules/' + name + '20/' + bin_target, link_path) + else: + assert 0 # unhandled action type + + def npm_files(action): + package_files(action, 'npm', { +- 'npm': 'bin/npm-cli.js', +- 'npx': 'bin/npx-cli.js', ++ 'npm20': 'bin/npm-cli.js', ++ 'npx20': 'bin/npx-cli.js', + }) + + def corepack_files(action): + package_files(action, 'corepack', { +- 'corepack': 'dist/corepack.js', ++ 'corepack20': 'dist/corepack.js', + # Not the default just yet: + # 'yarn': 'dist/yarn.js', + # 'yarnpkg': 'dist/yarn.js', +@@ -147,7 +147,7 @@ def subdir_files(path, dest, action): + + def files(action): + is_windows = sys.platform == 'win32' +- output_file = 'node' ++ output_file = 'node20' + output_prefix = 'out/Release/' + + if is_windows: +@@ -189,7 +189,7 @@ def files(action): + if 'freebsd' in sys.platform or 'openbsd' in sys.platform: + action(['doc/node.1'], 'man/man1/') + else: +- action(['doc/node.1'], 'share/man/man1/') ++ action(['doc/node.1'], 'share/man/man1/node20.1') + + if 'true' == variables.get('node_install_npm'): + npm_files(action) +@@ -276,28 +276,28 @@ def headers(action): + 'src/node_buffer.h', + 'src/node_object_wrap.h', + 'src/node_version.h', +- ], 'include/node/') ++ ], 'include/node20/') + + # Add the expfile that is created on AIX + if sys.platform.startswith('aix') or sys.platform == "os400": +- action(['out/Release/node.exp'], 'include/node/') ++ action(['out/Release/node.exp'], 'include/node20/') + +- subdir_files('deps/v8/include', 'include/node/', wanted_v8_headers) ++ subdir_files('deps/v8/include', 'include/node20/', wanted_v8_headers) + + if 'false' == variables.get('node_shared_libuv'): +- subdir_files('deps/uv/include', 'include/node/', action) ++ subdir_files('deps/uv/include', 'include/node20/', action) + + if 'true' == variables.get('node_use_openssl') and \ + 'false' == variables.get('node_shared_openssl'): +- subdir_files('deps/openssl/openssl/include/openssl', 'include/node/openssl/', action) +- subdir_files('deps/openssl/config/archs', 'include/node/openssl/archs', action) +- subdir_files('deps/openssl/config', 'include/node/openssl', action) ++ subdir_files('deps/openssl/openssl/include/openssl', 'include/node20/openssl/', action) ++ subdir_files('deps/openssl/config/archs', 'include/node20/openssl/archs', action) ++ subdir_files('deps/openssl/config', 'include/node20/openssl', action) + + if 'false' == variables.get('node_shared_zlib'): + action([ + 'deps/zlib/zconf.h', + 'deps/zlib/zlib.h', +- ], 'include/node/') ++ ], 'include/node20/') + + if sys.platform == 'zos': + zoslibinc = os.environ.get('ZOSLIB_INCLUDES') +Index: node-v20.5.1/doc/node.1 +=================================================================== +--- node-v20.5.1.orig/doc/node.1 ++++ node-v20.5.1/doc/node.1 +@@ -31,24 +31,24 @@ + .Dt NODE 1 + . + .Sh NAME +-.Nm node ++.Nm node20 + .Nd server-side JavaScript runtime + . + .\"====================================================================== + .Sh SYNOPSIS +-.Nm node ++.Nm node20 + .Op Ar options + .Op Ar v8-options + .Op Fl e Ar string | Ar script.js | Fl + .Op Fl - + .Op Ar arguments ... + . +-.Nm node ++.Nm node20 + .Cm inspect + .Op Fl e Ar string | Ar script.js | Fl | Ar : + .Ar ... + . +-.Nm node ++.Nm node20 + .Op Fl -v8-options + . + .\"====================================================================== +Index: node-v20.5.1/src/node_main.cc +=================================================================== +--- node-v20.5.1.orig/src/node_main.cc ++++ node-v20.5.1/src/node_main.cc +@@ -94,6 +94,7 @@ int wmain(int argc, wchar_t* wargv[]) { + // UNIX + + int main(int argc, char* argv[]) { ++ setenv("NODE_VERSION", "20", 0); + return node::Start(argc, argv); + } + #endif +Index: node-v20.5.1/tools/test.py +=================================================================== +--- node-v20.5.1.orig/tools/test.py ++++ node-v20.5.1/tools/test.py +@@ -947,7 +947,7 @@ class Context(object): + if self.vm is not None: + return self.vm + if arch == 'none': +- name = 'out/Debug/node' if mode == 'debug' else 'out/Release/node' ++ name = 'out/Debug/node' if mode == 'debug' else 'out/Release/node20' + else: + name = 'out/%s.%s/node' % (arch, mode) + +Index: node-v20.5.1/node.gyp +=================================================================== +--- node-v20.5.1.orig/node.gyp ++++ node-v20.5.1/node.gyp +@@ -23,8 +23,8 @@ + 'node_shared_openssl%': 'false', + 'node_v8_options%': '', + 'node_enable_v8_vtunejit%': 'false', +- 'node_core_target_name%': 'node', +- 'node_lib_target_name%': 'libnode', ++ 'node_core_target_name%': 'node20', ++ 'node_lib_target_name%': 'libnode20', + 'node_intermediate_lib_type%': 'static_library', + 'node_builtin_modules_path%': '', + 'linked_module_files': [