From 38fc9b6db27e018a0418ea394265c73f52937469 Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Thu, 19 May 2022 15:11:22 +0000 Subject: [PATCH] - Initial packaging of Nodejs 18.2.0. For detailed changes since previous versions, see https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V18.md#18.2.0 OBS-URL: https://build.opensuse.org/package/show/devel:languages:nodejs/nodejs18?expand=0&rev=1 --- .gitattributes | 23 + SHASUMS256.txt | 27 + SHASUMS256.txt.sig | Bin 0 -> 310 bytes _constraints | 11 + bash_output_helper.bash | 16 + cares_public_headers.patch | 13 + fix_ci_tests.patch | 144 ++++ flaky_test_rerun.patch | 21 + legacy_python.patch | 26 + linker_lto_jobs.patch | 75 ++ manual_configure.patch | 20 + node-gyp-addon-gypi.patch | 79 ++ node-gyp_7.1.2.tar.xz | 3 + node-v18.2.0.tar.xz | 3 + node_modules.tar.xz | 3 + nodejs-libpath.patch | 64 ++ nodejs.keyring | Bin 0 -> 43398 bytes nodejs18.changes | 8 + nodejs18.spec | 1029 +++++++++++++++++++++++++ npm_search_paths.patch | 32 + openssl_binary_detection.patch | 42 + rsa-pss-revert.patch | 443 +++++++++++ skip_no_console.patch | 29 + sle12_python3_compat.patch | 35 + test-skip-y2038-on-32bit-time_t.patch | 42 + update_npm_tarball.sh | 13 + versioned.patch | 518 +++++++++++++ 27 files changed, 2719 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 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_7.1.2.tar.xz create mode 100644 node-v18.2.0.tar.xz create mode 100644 node_modules.tar.xz create mode 100644 nodejs-libpath.patch create mode 100644 nodejs.keyring create mode 100644 nodejs18.changes create mode 100644 nodejs18.spec create mode 100644 npm_search_paths.patch create mode 100644 openssl_binary_detection.patch create mode 100644 rsa-pss-revert.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..9ae12e0 --- /dev/null +++ b/SHASUMS256.txt @@ -0,0 +1,27 @@ +7bb0a93a3f6b9b0a46194420fc554c1d12682aef7d8822cfd2bbb3639f5b2059 node-v18.2.0-aix-ppc64.tar.gz +d140f15ca709767365e09edd0cb345f10f32f582d82d726f67f63dd7db4443d1 node-v18.2.0-darwin-arm64.tar.gz +c73ea354c84c3bd9889c064346b6e3aaa292c33f1fb4a4793cdee7a155a5a67e node-v18.2.0-darwin-arm64.tar.xz +0b03647ac5805df335c6601d1a1838c6a2f4edbed7d098982bfd39e71b5fd8f8 node-v18.2.0-darwin-x64.tar.gz +e4d277afacb96e7d492dab3613a1612853e9a67a3a528dfc7e124a4c7370f0d6 node-v18.2.0-darwin-x64.tar.xz +c7dba1404ea1457a8c8292821d02fc835c862f716d7f5cab3aab545d6847a814 node-v18.2.0-headers.tar.gz +97a017643b40a91f73f5f3b0d91f4f653406ba05b7dd6e2129454ad6f49c2e28 node-v18.2.0-headers.tar.xz +9dc8ca472c79e842d4faf600876b643ab485936fe4870fbafaa7c19b2d153353 node-v18.2.0-linux-arm64.tar.gz +ad2c1e533db66cfb47e770c1f4af6807e1ce68cdce8aa230d26f025d0926d0c4 node-v18.2.0-linux-arm64.tar.xz +ace6a5da82794e1f364d284ee241b24c08048677c77b24c370c5a677189400f7 node-v18.2.0-linux-armv7l.tar.gz +1d7c6c8fb0715a501b889a58de9d3c7a54a0c62578ea4109d2b17adaf12a99f7 node-v18.2.0-linux-armv7l.tar.xz +d81d0ede439e082971c02e4d64ee95e5215753cfa3891cdfafd266c221767c21 node-v18.2.0-linux-ppc64le.tar.gz +053824eeb17a1afea11e437a2ae9061568e9ab95daa0ea818cfcd4246bfd950c node-v18.2.0-linux-ppc64le.tar.xz +f11f97a74b3a7ae19d8acac166e9de5e3e095a54ba5a0d7afaefd77b589f277f node-v18.2.0-linux-s390x.tar.gz +1dbe758651e66ba47b9f1a5650a295f424fe36bcd709e7ef71f9a4668c2f3081 node-v18.2.0-linux-s390x.tar.xz +73d3f98e96e098587c2154dcaa82a6469a510e89a4881663dc4c86985acf245e node-v18.2.0-linux-x64.tar.gz +22f9d2e71fe682091f1ec5f8be5703868069f5547a866bdddc8e661040b28527 node-v18.2.0-linux-x64.tar.xz +ac92b964ce08c96ac44da76df764e5981f319c7fc0c35dc49deab1188fa5d292 node-v18.2.0.pkg +bb9c117814341676edbfd7c79cfaaac2d809e760a65fe9afe050245d55bb7ca7 node-v18.2.0.tar.gz +2305b15ebf5547474e905b5002f9ba99c7eeef01d7394dfe6f3846cc6bcad66d node-v18.2.0.tar.xz +09586f2af26a5d73cfe95f7b576c058fe359de126c3d3655e00cb010261a97ba node-v18.2.0-win-x64.7z +deaa04e8ba65e568f02452c9313b9e6ee80fcef9c0929062fc5175a401fa05ce node-v18.2.0-win-x64.zip +c10293d857223e8f9afd79f8f2e021d1cf07920d108b9e285cd48bdcad9d5076 node-v18.2.0-x64.msi +09392b4eaa439add5a8e9e1cfb44dedf0b748a7bcad4257aa8ad187a6d0a432a win-x64/node.exe +005cd83dd73e222a2fa36a967b365749feb9e39eddd0078b6ef0df7802494671 win-x64/node.lib +d854462a87392625086808337c716ab4e1a49213b1a93ea47d0f5dc02b57a1e4 win-x64/node_pdb.7z +3cf29058aceac04ee87176285be14bdf933aa7c8cf1bdfb8c206fecf51c29494 win-x64/node_pdb.zip diff --git a/SHASUMS256.txt.sig b/SHASUMS256.txt.sig new file mode 100644 index 0000000000000000000000000000000000000000..c208445885a9c2af8d9df9844ec05e813fd2f47d GIT binary patch literal 310 zcmV-60m=S}0W$;u0SEvc79j*q*Ld|g<6}&BoQKBO1}I3Os{mXD0%C*16aWed5Z4AM zNTI6$Tsw~l0GzLVj^5|FMcF9KF6#>eUZEgk12UCpPIrLi)x6Xvq-1D0YrBzxM)BrU zqGSGtXX@%s+X8|dfHjRqQPhv5u9Eq=Zk0jnH7a}eWL`CymoCHEs>!_8ku5R|fTVYm z&^iJ)6 zg`bI;&jnG4ZNkToDM>7`jv1T2^c;yd70NhNegz4yswS`8f*5V^Lx3yuz8G==A`DYO If7bW>KQG{sGXMYp literal 0 HcmV?d00001 diff --git a/_constraints b/_constraints new file mode 100644 index 0000000..625844a --- /dev/null +++ b/_constraints @@ -0,0 +1,11 @@ + + + + + 8 + + + 10000 + + + 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..a901536 --- /dev/null +++ b/fix_ci_tests.patch @@ -0,0 +1,144 @@ +Author: Adam Majer +Date: Dec 20 09:18:49 UTC 2017 +Summary: Fix CI unit tests framework for OBS building + +Index: node-v16.14.2/test/parallel/test-module-loading-globalpaths.js +=================================================================== +--- node-v16.14.2.orig/test/parallel/test-module-loading-globalpaths.js ++++ node-v16.14.2/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-v16.14.2/test/parallel/test-tls-passphrase.js +=================================================================== +--- node-v16.14.2.orig/test/parallel/test-tls-passphrase.js ++++ node-v16.14.2/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-v16.14.2/test/parallel/test-repl-envvars.js +=================================================================== +--- node-v16.14.2.orig/test/parallel/test-repl-envvars.js ++++ node-v16.14.2/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 REPL = require('internal/repl'); + const assert = require('assert'); +Index: node-v16.14.2/test/common/index.mjs +=================================================================== +--- node-v16.14.2.orig/test/common/index.mjs ++++ node-v16.14.2/test/common/index.mjs +@@ -42,6 +42,7 @@ const { + expectsError, + skipIfInspectorDisabled, + skipIf32Bits, ++ skipIfWorker, + getArrayBufferViews, + getBufferSources, + getTTYfd, +@@ -87,6 +88,7 @@ export { + expectsError, + skipIfInspectorDisabled, + skipIf32Bits, ++ skipIfWorker, + getArrayBufferViews, + getBufferSources, + getTTYfd, +Index: node-v16.14.2/Makefile +=================================================================== +--- node-v16.14.2.orig/Makefile ++++ node-v16.14.2/Makefile +@@ -523,7 +523,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) \ +@@ -716,7 +717,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-v16.14.2/test/parallel/test-crypto-dh.js +=================================================================== +--- node-v16.14.2.orig/test/parallel/test-crypto-dh.js ++++ node-v16.14.2/test/parallel/test-crypto-dh.js +@@ -167,7 +167,7 @@ assert.throws(() => { + dh3.computeSecret(''); + }, { message: common.hasOpenSSL3 ? + 'error:02800080:Diffie-Hellman routines::invalid secret' : +- 'Supplied key is too small' }); ++ /Supplied key is too small|error:05066066:Diffie-Hellman routines:compute_key:invalid public key/ }); + + // Invalid test: curve argument is undefined + assert.throws( +Index: node-v16.14.2/test/parallel/test-zlib-dictionary-fail.js +=================================================================== +--- node-v16.14.2.orig/test/parallel/test-zlib-dictionary-fail.js ++++ node-v16.14.2/test/parallel/test-zlib-dictionary-fail.js +@@ -53,7 +53,7 @@ const input = Buffer.from([0x78, 0xBB, 0 + stream.on('error', common.mustCall(function(err) { + // It's not possible to separate invalid dict and invalid data when using + // the raw format +- assert.match(err.message, /invalid/); ++ assert.match(err.message, /(invalid|Operation-Ending-Supplemental Code is 0x12)/); + })); + + stream.write(input); +Index: node-v16.14.2/test/parallel/test-zlib-flush-drain-longblock.js +=================================================================== +--- node-v16.14.2.orig/test/parallel/test-zlib-flush-drain-longblock.js ++++ node-v16.14.2/test/parallel/test-zlib-flush-drain-longblock.js +@@ -16,7 +16,7 @@ zipper.write('A'.repeat(17000)); + zipper.flush(); + + let received = 0; +-unzipper.on('data', common.mustCall((d) => { ++unzipper.on('data', common.mustCallAtLeast((d) => { + received += d.length; + }, 2)); + +Index: node-v16.14.2/test/parallel/test-zlib-from-string.js +=================================================================== +--- node-v16.14.2.orig/test/parallel/test-zlib-from-string.js ++++ node-v16.14.2/test/parallel/test-zlib-from-string.js +@@ -55,7 +55,9 @@ const expectedBase64Gzip = 'H4sIAAAAAAAA + 'sHnHNzRtagj5AQAA'; + + zlib.deflate(inputString, common.mustCall((err, buffer) => { +- assert.strictEqual(buffer.toString('base64'), expectedBase64Deflate); ++ zlib.unzip(buffer, common.mustCall((err, unzipped) => { ++ assert.strictEqual(unzipped.toString(), inputString); ++ })); + })); + + zlib.gzip(inputString, common.mustCall((err, buffer) => { 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/legacy_python.patch b/legacy_python.patch new file mode 100644 index 0000000..1489af9 --- /dev/null +++ b/legacy_python.patch @@ -0,0 +1,26 @@ +Index: node-v16.5.0/tools/utils.py +=================================================================== +--- node-v16.5.0.orig/tools/utils.py ++++ node-v16.5.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 list diff --git a/linker_lto_jobs.patch b/linker_lto_jobs.patch new file mode 100644 index 0000000..ab0301a --- /dev/null +++ b/linker_lto_jobs.patch @@ -0,0 +1,75 @@ +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-v14.9.0/node.gyp +=================================================================== +--- node-v14.9.0.orig/node.gyp ++++ node-v14.9.0/node.gyp +@@ -1258,20 +1258,21 @@ + 'target_name': 'embedtest', + 'type': 'executable', + + 'dependencies': [ + '<(node_lib_target_name)', + 'deps/histogram/histogram.gyp:histogram', + 'deps/uvwasi/uvwasi.gyp:uvwasi', + 'node_dtrace_header', + 'node_dtrace_ustack', + 'node_dtrace_provider', ++ 'cctest', + ], + + 'includes': [ + 'node.gypi' + ], + + 'include_dirs': [ + 'src', + 'tools/msvs/genfiles', + 'deps/v8/include', +@@ -1317,20 +1318,21 @@ + # So generate_code_cache -> mkcodecache -> node_lib_base, + # node_lib -> node_lib_base & generate_code_cache + { + 'target_name': 'mkcodecache', + 'type': 'executable', + + 'dependencies': [ + '<(node_lib_target_name)', + 'deps/histogram/histogram.gyp:histogram', + 'deps/uvwasi/uvwasi.gyp:uvwasi', ++ 'embedtest', + ], + + 'includes': [ + 'node.gypi' + ], + + 'include_dirs': [ + 'src', + 'tools/msvs/genfiles', + 'deps/v8/include', +@@ -1372,20 +1374,21 @@ + ], + }, # mkcodecache + { + 'target_name': 'node_mksnapshot', + 'type': 'executable', + + 'dependencies': [ + '<(node_lib_target_name)', + 'deps/histogram/histogram.gyp:histogram', + 'deps/uvwasi/uvwasi.gyp:uvwasi', ++ 'mkcodecache' + ], + + 'includes': [ + 'node.gypi' + ], + + 'include_dirs': [ + 'src', + 'tools/msvs/genfiles', + 'deps/v8/include', 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..301420c --- /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/node18/', ++ '/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/node18' ++ 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_7.1.2.tar.xz b/node-gyp_7.1.2.tar.xz new file mode 100644 index 0000000..015b40d --- /dev/null +++ b/node-gyp_7.1.2.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f1c7a232727025211e2c80051c3d4a7b6984e19cc90c1f9943f1d03c05811a41 +size 271084 diff --git a/node-v18.2.0.tar.xz b/node-v18.2.0.tar.xz new file mode 100644 index 0000000..1f804ed --- /dev/null +++ b/node-v18.2.0.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2305b15ebf5547474e905b5002f9ba99c7eeef01d7394dfe6f3846cc6bcad66d +size 36873192 diff --git a/node_modules.tar.xz b/node_modules.tar.xz new file mode 100644 index 0000000..782bc34 --- /dev/null +++ b/node_modules.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6082cd5e67683f11f49ae144922d0dee412054ec2e9e2c1d715864986e44ee52 +size 1059176 diff --git a/nodejs-libpath.patch b/nodejs-libpath.patch new file mode 100644 index 0000000..b02a21e --- /dev/null +++ b/nodejs-libpath.patch @@ -0,0 +1,64 @@ +Index: node-v18.2.0/tools/install.py +=================================================================== +--- node-v18.2.0.orig/tools/install.py ++++ node-v18.2.0/tools/install.py +@@ -7,6 +7,8 @@ import errno + import os + import shutil + import sys ++from distutils import sysconfig ++import re + + # set at init time + node_prefix = '/usr/local' # PREFIX variable from Makefile +@@ -65,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) +@@ -80,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 +@@ -100,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 + +@@ -145,7 +151,7 @@ def files(action): + output_lib = 'libnode.' + variables.get('shlib_suffix') + action([output_prefix + output_lib], 'lib/' + output_lib) + if 'true' == variables.get('node_use_dtrace'): +- action(['out/Release/node.d'], 'lib/dtrace/node.d') ++ action(['out/Release/node.d'], libdir() + '/dtrace/node.d') + + # behave similarly for systemtap + action(['src/node.stp'], 'share/systemtap/tapset/') +Index: node-v18.2.0/lib/internal/modules/cjs/loader.js +=================================================================== +--- node-v18.2.0.orig/lib/internal/modules/cjs/loader.js ++++ node-v18.2.0/lib/internal/modules/cjs/loader.js +@@ -1240,7 +1240,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..05ec84d32842ff00a2cb6eaec9730c136fecf746 GIT binary patch literal 43398 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 UvRN%&TGFapd~PAm{2f;Q14Z>HRsaA1 literal 0 HcmV?d00001 diff --git a/nodejs18.changes b/nodejs18.changes new file mode 100644 index 0000000..8df4ce7 --- /dev/null +++ b/nodejs18.changes @@ -0,0 +1,8 @@ +------------------------------------------------------------------- +Thu May 19 15:01:09 UTC 2022 - Adam Majer + +- Initial packaging of Nodejs 18.2.0. For detailed changes + since previous versions, see + + https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V18.md#18.2.0 + diff --git a/nodejs18.spec b/nodejs18.spec new file mode 100644 index 0000000..537a310 --- /dev/null +++ b/nodejs18.spec @@ -0,0 +1,1029 @@ +# +# spec file for package nodejs18 +# +# 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: nodejs18 +Version: 18.2.0 +Release: 0 + +# Double DWZ memory limits +%define _dwz_low_mem_die_limit 20000000 +%define _dwz_max_die_limit 100000000 + +%define node_version_number 18 + +# 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} >= 1550 || 0%{?sle_version} >= 120500 +%bcond_with intree_openssl +%else +%bcond_without intree_openssl +%endif + +%if 0%{suse_version} >= 1330 +%bcond_with intree_cares +%else +%bcond_without intree_cares +%endif + +%if 0%{?suse_version} >= 1330 +%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 gyp/ | 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 +Patch133: rsa-pss-revert.patch + +# Use versioned binaries and paths +Patch200: versioned.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: gcc10-c++ +%define forced_gcc_version 10 +%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: gcc10-c++ +%define forced_gcc_version 10 +%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 >= 16 + +%if 0%{?suse_version} && 0%{?suse_version} < 1500 +BuildRequires: python36 +%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 + +%if ! 0%{with intree_openssl} + +BuildRequires: pkgconfig(openssl) >= %{openssl_req_ver} + +# require patched openssl library on SLES for nodejs16 +%if 0%{?suse_version} +%if %node_version_number >= 16 && 0%{suse_version} <= 1500 && %{pkg_vcmp openssl-1_1 < '1.1.1e' } && 0%{with openssl_RSA_get0_pss_params} +BuildRequires: openssl-has-RSA_get0_pss_params +Requires: openssl-has-RSA_get0_pss_params +%endif +%endif + +%if 0%{?suse_version} +%if 0%{?suse_version} >= 1500 +BuildRequires: openssl >= %{openssl_req_ver} +%else +BuildRequires: openssl-1_1 >= %{openssl_req_ver} +%endif + +BuildRequires: libopenssl1_1-hmac +# /suse_version +%endif + +%if 0%{?fedora_version} +BuildRequires: openssl >= %{openssl_req_ver} +%endif + +%else +%if %node_version_number <= 12 && 0%{?suse_version} == 1315 && 0%{?sle_version} < 120400 +Provides: bundled(openssl) = 3.0.3 +%else +BuildRequires: bundled_openssl_should_not_be_required +%endif +%endif + +%if ! 0%{with intree_cares} +BuildRequires: pkgconfig(libcares) >= 1.17.0 +%else +Provides: bundled(libcares2) = 1.18.1 +%endif + +%if ! 0%{with intree_icu} +BuildRequires: pkgconfig(icu-i18n) >= 69 +%else +Provides: bundled(icu) = 71.1 +%endif + +%if ! 0%{with intree_nghttp2} +BuildRequires: libnghttp2-devel >= 1.41.0 +%else +Provides: bundled(nghttp2) = 1.47.0 +%endif + +%if 0%{with valgrind_tests} +BuildRequires: valgrind +%endif + +%if %{with libalternatives} +Requires: alts +%else +Requires(postun): %{_sbindir}/update-alternatives +%endif +# either for update-alternatives, or their removal +Requires(post): %{_sbindir}/update-alternatives + +Recommends: npm18 + +#we need ABI virtual provides where SONAMEs aren't enough/not present so deps +#break when binary compatibility is broken +%global nodejs_abi 18.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.12 +Provides: bundled(libuv) = 1.43.0 +Provides: bundled(v8) = 10.1.124.8 +%if %{with intree_brotli} +Provides: bundled(brotli) = 1.0.9 +%else +BuildRequires: pkgconfig(libbrotlidec) +%endif + + +Provides: bundled(llhttp) = 6.0.6 +Provides: bundled(ngtcp2) = 0.1.0-DEV + +Provides: bundled(node-acorn) = 8.7.0 +Provides: bundled(node-acorn-walk) = 8.2.0 +Provides: bundled(node-cjs-module-lexer) = 1.2.2 +Provides: bundled(node-corepack) = 0.10.0 +Provides: bundled(node-undici) = 5.2.0 + +%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 18.x +Group: Development/Languages/NodeJS +Provides: nodejs-devel = %{version} +Requires: npm18 = %{version} +Requires: %{name} = %{version} + +%description devel +This package provides development headers for Node.js needed for creation +of binary modules. + +%package -n npm18 +Summary: Package manager for Node.js +Group: Development/Languages/NodeJS +%if %{with libalternatives} +Requires: nodejs-common >= 5.0 +%else +Requires: nodejs-common +%endif +Requires: nodejs18 = %{version} +Provides: nodejs-npm = %{version} +Obsoletes: nodejs-npm < 4.0.0 +Provides: npm(npm) = 8.9.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-agent-base) = 6.0.2 +Provides: bundled(node-agentkeepalive) = 4.2.1 +Provides: bundled(node-aggregate-error) = 3.1.0 +Provides: bundled(node-ansi-regex) = 5.0.1 +Provides: bundled(node-ansi-styles) = 4.3.0 +Provides: bundled(node-aproba) = 2.0.0 +Provides: bundled(node-archy) = 1.0.0 +Provides: bundled(node-are-we-there-yet) = 3.0.0 +Provides: bundled(node-asap) = 2.0.6 +Provides: bundled(node-balanced-match) = 1.0.2 +Provides: bundled(node-bin-links) = 3.0.1 +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-builtins) = 5.0.0 +Provides: bundled(node-cacache) = 16.0.7 +Provides: bundled(node-chalk) = 4.1.2 +Provides: bundled(node-chownr) = 2.0.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.2 +Provides: bundled(node-clone) = 1.0.4 +Provides: bundled(node-cmd-shim) = 5.0.0 +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-debug) = 4.3.4 +Provides: bundled(node-debuglog) = 1.0.1 +Provides: bundled(node-defaults) = 1.0.3 +Provides: bundled(node-delegates) = 1.0.0 +Provides: bundled(node-depd) = 1.1.2 +Provides: bundled(node-dezalgo) = 1.0.4 +Provides: bundled(node-diff) = 5.0.0 +Provides: bundled(node-emoji-regex) = 8.0.0 +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-fastest-levenshtein) = 1.0.12 +Provides: bundled(node-fs-minipass) = 2.1.0 +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-glob) = 7.2.0 +Provides: bundled(node-glob) = 8.0.1 +Provides: bundled(node-graceful-fs) = 4.2.10 +Provides: bundled(node-has) = 1.0.3 +Provides: bundled(node-has-flag) = 4.0.0 +Provides: bundled(node-has-unicode) = 2.0.1 +Provides: bundled(node-hosted-git-info) = 5.0.0 +Provides: bundled(node-http-cache-semantics) = 4.1.0 +Provides: bundled(node-http-proxy-agent) = 5.0.0 +Provides: bundled(node-https-proxy-agent) = 5.0.0 +Provides: bundled(node-humanize-ms) = 1.2.1 +Provides: bundled(node-iconv-lite) = 0.6.3 +Provides: bundled(node-ignore-walk) = 5.0.1 +Provides: bundled(node-imurmurhash) = 0.1.4 +Provides: bundled(node-indent-string) = 4.0.0 +Provides: bundled(node-infer-owner) = 1.0.4 +Provides: bundled(node-inflight) = 1.0.6 +Provides: bundled(node-inherits) = 2.0.4 +Provides: bundled(node-ini) = 3.0.0 +Provides: bundled(node-init-package-json) = 3.0.2 +Provides: bundled(node-ip) = 1.1.5 +Provides: bundled(node-ip-regex) = 4.3.0 +Provides: bundled(node-is-cidr) = 4.0.2 +Provides: bundled(node-is-core-module) = 2.8.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-json-parse-even-better-errors) = 2.3.1 +Provides: bundled(node-json-stringify-nice) = 1.1.4 +Provides: bundled(node-jsonparse) = 1.3.1 +Provides: bundled(node-just-diff) = 5.0.1 +Provides: bundled(node-just-diff-apply) = 5.2.0 +Provides: bundled(node-libnpmaccess) = 6.0.3 +Provides: bundled(node-libnpmdiff) = 4.0.3 +Provides: bundled(node-libnpmexec) = 4.0.5 +Provides: bundled(node-libnpmfund) = 3.0.2 +Provides: bundled(node-libnpmhook) = 8.0.3 +Provides: bundled(node-libnpmorg) = 4.0.3 +Provides: bundled(node-libnpmpack) = 4.0.3 +Provides: bundled(node-libnpmpublish) = 6.0.4 +Provides: bundled(node-libnpmsearch) = 5.0.3 +Provides: bundled(node-libnpmteam) = 4.0.3 +Provides: bundled(node-libnpmversion) = 3.0.4 +Provides: bundled(node-lru-cache) = 6.0.0 +Provides: bundled(node-lru-cache) = 7.8.1 +Provides: bundled(node-make-fetch-happen) = 10.1.2 +Provides: bundled(node-minimatch) = 3.1.2 +Provides: bundled(node-minimatch) = 5.0.1 +Provides: bundled(node-minipass) = 3.1.6 +Provides: bundled(node-minipass-collect) = 1.0.2 +Provides: bundled(node-minipass-fetch) = 2.1.0 +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-mkdirp-infer-owner) = 2.0.0 +Provides: bundled(node-ms) = 2.1.2 +Provides: bundled(node-ms) = 2.1.3 +Provides: bundled(node-mute-stream) = 0.0.8 +Provides: bundled(node-negotiator) = 0.6.3 +Provides: bundled(node-node-gyp) = 9.0.0 +Provides: bundled(node-nopt) = 5.0.0 +Provides: bundled(node-normalize-package-data) = 4.0.0 +Provides: bundled(node-npm-audit-report) = 3.0.0 +Provides: bundled(node-npm-bundled) = 1.1.2 +Provides: bundled(node-npm-install-checks) = 5.0.0 +Provides: bundled(node-npm-normalize-package-bin) = 1.0.1 +Provides: bundled(node-npm-package-arg) = 9.0.2 +Provides: bundled(node-npm-packlist) = 5.0.2 +Provides: bundled(node-npm-pick-manifest) = 7.0.1 +Provides: bundled(node-npm-profile) = 6.0.3 +Provides: bundled(node-npm-registry-fetch) = 13.1.1 +Provides: bundled(node-npm-user-validate) = 1.0.1 +Provides: bundled(node-npmlog) = 6.0.2 +Provides: bundled(node-once) = 1.4.0 +Provides: bundled(node-opener) = 1.5.2 +Provides: bundled(node-p-map) = 4.0.0 +Provides: bundled(node-pacote) = 13.3.0 +Provides: bundled(node-parse-conflict-json) = 2.0.2 +Provides: bundled(node-path-is-absolute) = 1.0.1 +Provides: bundled(node-proc-log) = 2.0.1 +Provides: bundled(node-promise-all-reject-late) = 1.0.1 +Provides: bundled(node-promise-call-limit) = 1.0.1 +Provides: bundled(node-promise-inflight) = 1.0.1 +Provides: bundled(node-promise-retry) = 2.0.1 +Provides: bundled(node-promzard) = 0.3.0 +Provides: bundled(node-qrcode-terminal) = 0.12.0 +Provides: bundled(node-read) = 1.0.7 +Provides: bundled(node-read-cmd-shim) = 3.0.0 +Provides: bundled(node-read-package-json) = 5.0.1 +Provides: bundled(node-read-package-json-fast) = 2.0.3 +Provides: bundled(node-readable-stream) = 3.6.0 +Provides: bundled(node-readdir-scoped-modules) = 1.1.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.3.7 +Provides: bundled(node-set-blocking) = 2.0.0 +Provides: bundled(node-signal-exit) = 3.0.7 +Provides: bundled(node-smart-buffer) = 4.2.0 +Provides: bundled(node-socks) = 2.6.2 +Provides: bundled(node-socks-proxy-agent) = 6.1.1 +Provides: bundled(node-spdx-correct) = 3.1.1 +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.11 +Provides: bundled(node-ssri) = 9.0.0 +Provides: bundled(node-string_decoder) = 1.3.0 +Provides: bundled(node-string-width) = 4.2.3 +Provides: bundled(node-strip-ansi) = 6.0.1 +Provides: bundled(node-supports-color) = 7.2.0 +Provides: bundled(node-tar) = 6.1.11 +Provides: bundled(node-text-table) = 0.2.0 +Provides: bundled(node-tiny-relative-date) = 1.3.0 +Provides: bundled(node-treeverse) = 2.0.0 +Provides: bundled(node-unique-filename) = 1.1.1 +Provides: bundled(node-unique-slug) = 2.0.2 +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) = 4.0.0 +Provides: bundled(node-walk-up-path) = 1.0.0 +Provides: bundled(node-wcwidth) = 1.0.1 +Provides: bundled(node-which) = 2.0.2 +Provides: bundled(node-wide-align) = 1.1.5 +Provides: bundled(node-wrappy) = 1.0.2 +Provides: bundled(node-write-file-atomic) = 4.0.1 +Provides: bundled(node-yallist) = 4.0.0 + +%description -n npm18 +A package manager for Node.js that allows developers to install and +publish packages to a package registry. + +%package -n corepack18 +Summary: Helper bridge between NodeJS projects and their dependencies +Group: Development/Languages/NodeJS +Requires: nodejs-common >= 5.0 + +%description -n corepack18 +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} <= 10 +rm -r deps/npm/* +tar zxf %{SOURCE9} -C deps/npm --strip-components=1 +tar Jxf %{SOURCE90} -C deps/npm +%endif + +%if %{node_version_number} >= 10 +tar Jxf %{SOURCE11} +%endif + +%patch1 -p1 +%patch3 -p1 +%patch5 -p1 +%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} +%patch133 -p1 +%endif +%patch200 -p1 + +%if %{node_version_number} <= 14 +# 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 + +# downgrade node-gyp to last version that supports python 3.4 for SLE12 +%if 0%{?use_version} && 0%{?suse_version} < 1500 +rm -r deps/npm/node_modules/node-gyp +mkdir deps/npm/node_modules/node-gyp +tar -C deps/npm/node_modules/node-gyp Jxf %{SOURCE5} +%endif + + +%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 + --without-dtrace \ + --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 + +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 +rm -f test/doctool/test-make-doc.js +# DNS lookup doesn't work in build root +rm -f test/parallel/test-dns-cancel-reverse-lookup.js \ + test/parallel/test-dns-resolveany.js +# multicast test fail since no socket? +rm -f test/parallel/test-dgram-membership.js +%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 + +# error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake +# failure:ssl/record/rec_layer_s3.c:1543:SSL alert number 40 +rm -f test/parallel/test-tls-no-sslv3.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 AUTHORS *.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} +%dir %{_datadir}/systemtap +%dir %{_datadir}/systemtap/tapset +%{_datadir}/systemtap/tapset/node%{node_version_number}.stp + +%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..92f3b35 --- /dev/null +++ b/npm_search_paths.patch @@ -0,0 +1,32 @@ +Index: node-v18.2.0/deps/npm/lib/commands/help-search.js +=================================================================== +--- node-v18.2.0.orig/deps/npm/lib/commands/help-search.js ++++ node-v18.2.0/deps/npm/lib/commands/help-search.js +@@ -20,7 +20,7 @@ class HelpSearch extends BaseCommand { + throw this.usageError() + } + +- const docPath = path.resolve(__dirname, '..', '..', 'docs/content') ++ const docPath = '/usr/share/doc/packages/nodejs' + const files = await glob(`${globify(docPath)}/*/*.md`) + const data = await this.readFiles(files) + const results = await this.searchFiles(args, data, files) +Index: node-v18.2.0/deps/npm/lib/npm.js +=================================================================== +--- node-v18.2.0.orig/deps/npm/lib/npm.js ++++ node-v18.2.0/deps/npm/lib/npm.js +@@ -383,7 +383,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 + + * {Object} + * `modulusLength`: {number} Key size in bits (RSA, DSA). + * `publicExponent`: {bigint} Public exponent (RSA). +- * `hashAlgorithm`: {string} Name of the message digest (RSA-PSS). +- * `mgf1HashAlgorithm`: {string} Name of the message digest used by +- MGF1 (RSA-PSS). +- * `saltLength`: {number} Minimal salt length in bytes (RSA-PSS). + * `divisorLength`: {number} Size of `q` in bits (DSA). + * `namedCurve`: {string} Name of the curve (EC). + +@@ -1981,11 +1972,8 @@ this object contains information about t + through this property can be used to uniquely identify a key or to compromise + the security of the key. + +-For RSA-PSS keys, if the key material contains a `RSASSA-PSS-params` sequence, +-the `hashAlgorithm`, `mgf1HashAlgorithm`, and `saltLength` properties will be +-set. +- +-Other key details might be exposed via this API using additional attributes. ++RSA-PSS parameters, DH, or any future key type details might be exposed via this ++API using additional attributes. + + ### `keyObject.asymmetricKeyType` + +Index: node-v17.3.0/src/crypto/crypto_rsa.cc +=================================================================== +--- node-v17.3.0.orig/src/crypto/crypto_rsa.cc ++++ node-v17.3.0/src/crypto/crypto_rsa.cc +@@ -561,84 +561,10 @@ Maybe GetRsaKeyDetail( + reinterpret_cast(public_exponent.data()); + CHECK_EQ(BN_bn2binpad(e, data, len), len); + +- if (target +- ->Set( +- env->context(), +- env->public_exponent_string(), +- public_exponent.ToArrayBuffer()) +- .IsNothing()) { +- return Nothing(); +- } +- +- if (type == EVP_PKEY_RSA_PSS) { +- // Due to the way ASN.1 encoding works, default values are omitted when +- // encoding the data structure. However, there are also RSA-PSS keys for +- // which no parameters are set. In that case, the ASN.1 RSASSA-PSS-params +- // sequence will be missing entirely and RSA_get0_pss_params will return +- // nullptr. If parameters are present but all parameters are set to their +- // default values, an empty sequence will be stored in the ASN.1 structure. +- // In that case, RSA_get0_pss_params does not return nullptr but all fields +- // of the returned RSA_PSS_PARAMS will be set to nullptr. +- +- const RSA_PSS_PARAMS* params = RSA_get0_pss_params(rsa); +- if (params != nullptr) { +- int hash_nid = NID_sha1; +- int mgf_nid = NID_mgf1; +- int mgf1_hash_nid = NID_sha1; +- int64_t salt_length = 20; +- +- if (params->hashAlgorithm != nullptr) { +- hash_nid = OBJ_obj2nid(params->hashAlgorithm->algorithm); +- } +- +- if (target +- ->Set( +- env->context(), +- env->hash_algorithm_string(), +- OneByteString(env->isolate(), OBJ_nid2ln(hash_nid))) +- .IsNothing()) { +- return Nothing(); +- } +- +- if (params->maskGenAlgorithm != nullptr) { +- mgf_nid = OBJ_obj2nid(params->maskGenAlgorithm->algorithm); +- if (mgf_nid == NID_mgf1) { +- mgf1_hash_nid = OBJ_obj2nid(params->maskHash->algorithm); +- } +- } +- +- // If, for some reason, the MGF is not MGF1, then the MGF1 hash function +- // is intentionally not added to the object. +- if (mgf_nid == NID_mgf1) { +- if (target +- ->Set( +- env->context(), +- env->mgf1_hash_algorithm_string(), +- OneByteString(env->isolate(), OBJ_nid2ln(mgf1_hash_nid))) +- .IsNothing()) { +- return Nothing(); +- } +- } +- +- if (params->saltLength != nullptr) { +- if (ASN1_INTEGER_get_int64(&salt_length, params->saltLength) != 1) { +- ThrowCryptoError(env, ERR_get_error(), "ASN1_INTEGER_get_in64 error"); +- return Nothing(); +- } +- } +- +- if (target +- ->Set( +- env->context(), +- env->salt_length_string(), +- Number::New(env->isolate(), static_cast(salt_length))) +- .IsNothing()) { +- return Nothing(); +- } +- } +- } +- +- return Just(true); ++ return target->Set( ++ env->context(), ++ env->public_exponent_string(), ++ public_exponent.ToArrayBuffer()); + } + + namespace RSAAlg { +Index: node-v17.3.0/src/env.h +=================================================================== +--- node-v17.3.0.orig/src/env.h ++++ node-v17.3.0/src/env.h +@@ -271,7 +271,6 @@ constexpr size_t kFsStatsBufferLength = + V(gid_string, "gid") \ + V(h2_string, "h2") \ + V(handle_string, "handle") \ +- V(hash_algorithm_string, "hashAlgorithm") \ + V(help_text_string, "helpText") \ + V(homedir_string, "homedir") \ + V(host_string, "host") \ +@@ -320,7 +319,6 @@ constexpr size_t kFsStatsBufferLength = + V(message_port_string, "messagePort") \ + V(message_string, "message") \ + V(messageerror_string, "messageerror") \ +- V(mgf1_hash_algorithm_string, "mgf1HashAlgorithm") \ + V(minttl_string, "minttl") \ + V(module_string, "module") \ + V(modulus_string, "modulus") \ +@@ -390,7 +388,6 @@ constexpr size_t kFsStatsBufferLength = + V(replacement_string, "replacement") \ + V(require_string, "require") \ + V(retry_string, "retry") \ +- V(salt_length_string, "saltLength") \ + V(scheme_string, "scheme") \ + V(scopeid_string, "scopeid") \ + V(serial_number_string, "serialNumber") \ +Index: node-v17.3.0/test/fixtures/keys/Makefile +=================================================================== +--- node-v17.3.0.orig/test/fixtures/keys/Makefile ++++ node-v17.3.0/test/fixtures/keys/Makefile +@@ -64,11 +64,9 @@ all: \ + rsa_pss_private_2048.pem \ + rsa_pss_private_2048_sha256_sha256_16.pem \ + rsa_pss_private_2048_sha512_sha256_20.pem \ +- rsa_pss_private_2048_sha1_sha1_20.pem \ + rsa_pss_public_2048.pem \ + rsa_pss_public_2048_sha256_sha256_16.pem \ + rsa_pss_public_2048_sha512_sha256_20.pem \ +- rsa_pss_public_2048_sha1_sha1_20.pem \ + ed25519_private.pem \ + ed25519_public.pem \ + x25519_private.pem \ +@@ -710,9 +708,6 @@ rsa_pss_private_2048_sha256_sha256_16.pe + rsa_pss_private_2048_sha512_sha256_20.pem: + openssl genpkey -algorithm RSA-PSS -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537 -pkeyopt rsa_pss_keygen_md:sha512 -pkeyopt rsa_pss_keygen_mgf1_md:sha256 -pkeyopt rsa_pss_keygen_saltlen:20 -out rsa_pss_private_2048_sha512_sha256_20.pem + +-rsa_pss_private_2048_sha1_sha1_20.pem: +- openssl genpkey -algorithm RSA-PSS -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537 -pkeyopt rsa_pss_keygen_md:sha1 -pkeyopt rsa_pss_keygen_mgf1_md:sha1 -pkeyopt rsa_pss_keygen_saltlen:20 -out rsa_pss_private_2048_sha1_sha1_20.pem +- + rsa_pss_public_2048.pem: rsa_pss_private_2048.pem + openssl pkey -in rsa_pss_private_2048.pem -pubout -out rsa_pss_public_2048.pem + +@@ -722,9 +717,6 @@ rsa_pss_public_2048_sha256_sha256_16.pem + rsa_pss_public_2048_sha512_sha256_20.pem: rsa_pss_private_2048_sha512_sha256_20.pem + openssl pkey -in rsa_pss_private_2048_sha512_sha256_20.pem -pubout -out rsa_pss_public_2048_sha512_sha256_20.pem + +-rsa_pss_public_2048_sha1_sha1_20.pem: rsa_pss_private_2048_sha1_sha1_20.pem +- openssl pkey -in rsa_pss_private_2048_sha1_sha1_20.pem -pubout -out rsa_pss_public_2048_sha1_sha1_20.pem +- + ed25519_private.pem: + openssl genpkey -algorithm ED25519 -out ed25519_private.pem + +Index: node-v17.3.0/test/fixtures/keys/rsa_pss_private_2048_sha1_sha1_20.pem +=================================================================== +--- node-v17.3.0.orig/test/fixtures/keys/rsa_pss_private_2048_sha1_sha1_20.pem ++++ /dev/null +@@ -1,28 +0,0 @@ +------BEGIN PRIVATE KEY----- +-MIIEvQIBADANBgkqhkiG9w0BAQowAASCBKcwggSjAgEAAoIBAQCpdutzsPFQ1100 +-ouR5aAwYry8aAtG0c+zX9UqNXGCpRDWzPPpXHUZSB1BmTTL4EhK2tkAfblYNqzRu +-CAYlKHbFpFLs2zLEorfp0WsFNPaBHE9JHpLIM4oXxPCUypZ7JAn56ZYonYCZ8Il5 +-8SzD9aoF41RTEmpcx3XkL2RQa022RiSccYZKx/yzskUUAdTvTvYyujH1MkvsfVP+ +-Ns5bRL6IVqowFd3xv6ctvfQMxz0rltgTC+wOm3CFtn+G63y6P/Z0U2DRdacsNkN6 +-PFGXAIB0kSvKzs8gVocEBiSwMkcT/KD3R68PY18b2auqaGcm8gA+gaVJ36KAW4dO +-AjbY+YitAgMBAAECggEAfPvfFXln0Ra1gE+vMDdjzITPuWBg57Uj9fbMIEwEYnKT +-JHmRrNRDe9Y3HuxK7hjuQmFSE5xdzUD6rzgtyBP63TOfkV7tJ4dXGxS/2JxCPeDy +-PNxWp18Ttwoh4as0pudikDYN8DCRm3eC/TO5r2EtH6CVHZuUZI8bTMsDMiihrQ8F +-B8+KucBG5DDy/OlDeieAZxZA4Y0/c+W0DNZ/LIPGwaqMzYCSZJXyV0t33HytUwM2 +-QZ+RbWqcUcrCI3lFAO8IyEULCi+RnSByZeJ0xwUkdQTI5jT6+G8BrO70Oiab8g+Q +-Rx2s7PxWpIMVS7/JD1PsL4hLrVh3uqh8PZl3/FG9IQKBgQDZWkOR2LA+ixmD6XJb +-Q+7zW2guHnK6wDrQFKmBGLaDdAER64WL1Unt6Umu7FPxth2niYMEgRexBgnj5hQN +-LfPYTiIeXs5ErrU96fVQABsV0Hra1M2Rhve5nynjFFpbHjDXtizzLpE30MsC7YkN +-EqD4YYzjWHrbk/UlQ7tx3eAvtQKBgQDHmNM4TRuyH2yaYxDqnho6fgJv7Z4KgbM0 +-1wcUxi5kPDQsFtaVOzFhNserzsWvotQjLkC2+CK5qlCdm59ZlpUqszF6+YyUs5Gq +-WmHdqryduT1VxSV/pd6wGEQo27fxFV7LsT1JhVMh9Iri8MK0b1BD6+kVUf5NcKDB +-Od2o8A1gGQKBgA5Y3Pj1mrymJesFL91CYLWDpR7WN7CIG9m8Y2v4G6QVtjRenZQb +-YiPoMErxoqDj6pUyiIl1lADFa0W13ED6dYwjrDDhBTCXb7NEjELZnvATsOhc/6zJ +-gfSowvUQVN6K4aJ7jgAHZOKQT7ZDw7YvMpzyo4AmSQXRgG8TR34+rRu5AoGACApP +-9+SjSPmbFl0HQWw9Aj4xOvEHfMTcwzQmRN/23nLOZzhETJ6lzpS2VmVt8TVN9lzW +-nohAXdpOhQrP0HwQZjfxtlJ3J0ZUh9g8OQG3t2LO5bWbXRkBb3aKyFqRflSuDOaG +-4X9NagC/14R7U2loglPuf71d0SDIWQBLvZJt94ECgYEAnY7aKHnWdLszcB8uyEkJ +-EJkUEaa+K/nTqOzqffZ01cTWJmUG7a2KuvQ+UQM2BHk2+wBmUo45Iz/dyePOJY0B +-Fu2agiV4+R4z2XVQnIvXgY5HaPxvLz0THksY/pD58gBmFaLMx4ADEwQ+s4Y2g12H +-ABsKNRHfSnKTwOm/dYvcVqs= +------END PRIVATE KEY----- +Index: node-v17.3.0/test/fixtures/keys/rsa_pss_public_2048_sha1_sha1_20.pem +=================================================================== +--- node-v17.3.0.orig/test/fixtures/keys/rsa_pss_public_2048_sha1_sha1_20.pem ++++ /dev/null +@@ -1,9 +0,0 @@ +------BEGIN PUBLIC KEY----- +-MIIBIjANBgkqhkiG9w0BAQowAAOCAQ8AMIIBCgKCAQEAqXbrc7DxUNddNKLkeWgM +-GK8vGgLRtHPs1/VKjVxgqUQ1szz6Vx1GUgdQZk0y+BIStrZAH25WDas0bggGJSh2 +-xaRS7NsyxKK36dFrBTT2gRxPSR6SyDOKF8TwlMqWeyQJ+emWKJ2AmfCJefEsw/Wq +-BeNUUxJqXMd15C9kUGtNtkYknHGGSsf8s7JFFAHU7072Mrox9TJL7H1T/jbOW0S+ +-iFaqMBXd8b+nLb30DMc9K5bYEwvsDptwhbZ/hut8uj/2dFNg0XWnLDZDejxRlwCA +-dJErys7PIFaHBAYksDJHE/yg90evD2NfG9mrqmhnJvIAPoGlSd+igFuHTgI22PmI +-rQIDAQAB +------END PUBLIC KEY----- +Index: node-v17.3.0/test/parallel/test-crypto-key-objects.js +=================================================================== +--- node-v17.3.0.orig/test/parallel/test-crypto-key-objects.js ++++ node-v17.3.0/test/parallel/test-crypto-key-objects.js +@@ -582,21 +582,11 @@ const privateDsa = fixtures.readKey('dsa + const publicKey = createPublicKey(publicPem); + const privateKey = createPrivateKey(privatePem); + +- // Because no RSASSA-PSS-params appears in the PEM, no defaults should be +- // added for the PSS parameters. This is different from an empty +- // RSASSA-PSS-params sequence (see test below). +- const expectedKeyDetails = { +- modulusLength: 2048, +- publicExponent: 65537n +- }; +- + assert.strictEqual(publicKey.type, 'public'); + assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss'); +- assert.deepStrictEqual(publicKey.asymmetricKeyDetails, expectedKeyDetails); + + assert.strictEqual(privateKey.type, 'private'); + assert.strictEqual(privateKey.asymmetricKeyType, 'rsa-pss'); +- assert.deepStrictEqual(privateKey.asymmetricKeyDetails, expectedKeyDetails); + + assert.throws( + () => publicKey.export({ format: 'jwk' }), +@@ -635,38 +625,6 @@ const privateDsa = fixtures.readKey('dsa + } + + { +- // This key pair enforces sha1 as the message digest and the MGF1 +- // message digest and a salt length of 20 bytes. +- +- const publicPem = fixtures.readKey('rsa_pss_public_2048_sha1_sha1_20.pem'); +- const privatePem = +- fixtures.readKey('rsa_pss_private_2048_sha1_sha1_20.pem'); +- +- const publicKey = createPublicKey(publicPem); +- const privateKey = createPrivateKey(privatePem); +- +- // Unlike the previous key pair, this key pair contains an RSASSA-PSS-params +- // sequence. However, because all values in the RSASSA-PSS-params are set to +- // their defaults (see RFC 3447), the ASN.1 structure contains an empty +- // sequence. Node.js should add the default values to the key details. +- const expectedKeyDetails = { +- modulusLength: 2048, +- publicExponent: 65537n, +- hashAlgorithm: 'sha1', +- mgf1HashAlgorithm: 'sha1', +- saltLength: 20 +- }; +- +- assert.strictEqual(publicKey.type, 'public'); +- assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss'); +- assert.deepStrictEqual(publicKey.asymmetricKeyDetails, expectedKeyDetails); +- +- assert.strictEqual(privateKey.type, 'private'); +- assert.strictEqual(privateKey.asymmetricKeyType, 'rsa-pss'); +- assert.deepStrictEqual(privateKey.asymmetricKeyDetails, expectedKeyDetails); +- } +- +- { + // This key pair enforces sha256 as the message digest and the MGF1 + // message digest and a salt length of at least 16 bytes. + const publicPem = +@@ -724,21 +682,11 @@ const privateDsa = fixtures.readKey('dsa + const publicKey = createPublicKey(publicPem); + const privateKey = createPrivateKey(privatePem); + +- const expectedKeyDetails = { +- modulusLength: 2048, +- publicExponent: 65537n, +- hashAlgorithm: 'sha512', +- mgf1HashAlgorithm: 'sha256', +- saltLength: 20 +- }; +- + assert.strictEqual(publicKey.type, 'public'); + assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss'); +- assert.deepStrictEqual(publicKey.asymmetricKeyDetails, expectedKeyDetails); + + assert.strictEqual(privateKey.type, 'private'); + assert.strictEqual(privateKey.asymmetricKeyType, 'rsa-pss'); +- assert.deepStrictEqual(privateKey.asymmetricKeyDetails, expectedKeyDetails); + + // Node.js usually uses the same hash function for the message and for MGF1. + // However, when a different MGF1 message digest algorithm has been +Index: node-v17.3.0/test/parallel/test-crypto-keygen.js +=================================================================== +--- node-v17.3.0.orig/test/parallel/test-crypto-keygen.js ++++ node-v17.3.0/test/parallel/test-crypto-keygen.js +@@ -309,20 +309,14 @@ const sec1EncExp = (cipher) => getRegExp + assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss'); + assert.deepStrictEqual(publicKey.asymmetricKeyDetails, { + modulusLength: 512, +- publicExponent: 65537n, +- hashAlgorithm: 'sha256', +- mgf1HashAlgorithm: 'sha256', +- saltLength: 16 ++ publicExponent: 65537n + }); + + assert.strictEqual(privateKey.type, 'private'); + assert.strictEqual(privateKey.asymmetricKeyType, 'rsa-pss'); + assert.deepStrictEqual(privateKey.asymmetricKeyDetails, { + modulusLength: 512, +- publicExponent: 65537n, +- hashAlgorithm: 'sha256', +- mgf1HashAlgorithm: 'sha256', +- saltLength: 16 ++ publicExponent: 65537n + }); + + // Unlike RSA, RSA-PSS does not allow encryption. +@@ -381,10 +375,7 @@ const sec1EncExp = (cipher) => getRegExp + }, common.mustSucceed((publicKey, privateKey) => { + const expectedKeyDetails = { + modulusLength: 512, +- publicExponent: 65537n, +- hashAlgorithm: 'sha256', +- mgf1HashAlgorithm: 'sha256', +- saltLength: 16 ++ publicExponent: 65537n + }; + assert.deepStrictEqual(publicKey.asymmetricKeyDetails, expectedKeyDetails); + assert.deepStrictEqual(privateKey.asymmetricKeyDetails, expectedKeyDetails); +@@ -401,10 +392,7 @@ const sec1EncExp = (cipher) => getRegExp + }, common.mustSucceed((publicKey, privateKey) => { + const expectedKeyDetails = { + modulusLength: 512, +- publicExponent: 65537n, +- hashAlgorithm: 'sha512', +- mgf1HashAlgorithm: 'sha512', +- saltLength: 64 ++ publicExponent: 65537n + }; + assert.deepStrictEqual(publicKey.asymmetricKeyDetails, expectedKeyDetails); + assert.deepStrictEqual(privateKey.asymmetricKeyDetails, expectedKeyDetails); +@@ -418,10 +406,7 @@ const sec1EncExp = (cipher) => getRegExp + }, common.mustSucceed((publicKey, privateKey) => { + const expectedKeyDetails = { + modulusLength: 512, +- publicExponent: 65537n, +- hashAlgorithm: 'sha512', +- mgf1HashAlgorithm: 'sha512', +- saltLength: 0 ++ publicExponent: 65537n + }; + assert.deepStrictEqual(publicKey.asymmetricKeyDetails, expectedKeyDetails); + assert.deepStrictEqual(privateKey.asymmetricKeyDetails, expectedKeyDetails); +@@ -1646,20 +1631,14 @@ if (!common.hasOpenSSL3) { + assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss'); + assert.deepStrictEqual(publicKey.asymmetricKeyDetails, { + modulusLength: 512, +- publicExponent: 65537n, +- hashAlgorithm: 'sha256', +- mgf1HashAlgorithm: 'sha256', +- saltLength: 16 ++ publicExponent: 65537n + }); + + assert.strictEqual(privateKey.type, 'private'); + assert.strictEqual(privateKey.asymmetricKeyType, 'rsa-pss'); + assert.deepStrictEqual(privateKey.asymmetricKeyDetails, { + modulusLength: 512, +- publicExponent: 65537n, +- hashAlgorithm: 'sha256', +- mgf1HashAlgorithm: 'sha256', +- saltLength: 16 ++ publicExponent: 65537n + }); + })); + } +Index: node-v17.3.0/test/parallel/test-crypto-keygen-deprecation.js +=================================================================== +--- node-v17.3.0.orig/test/parallel/test-crypto-keygen-deprecation.js ++++ node-v17.3.0/test/parallel/test-crypto-keygen-deprecation.js +@@ -32,20 +32,14 @@ const { generateKeyPair } = require('cry + assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss'); + assert.deepStrictEqual(publicKey.asymmetricKeyDetails, { + modulusLength: 512, +- publicExponent: 65537n, +- hashAlgorithm: 'sha256', +- mgf1HashAlgorithm: 'sha256', +- saltLength: 16 ++ publicExponent: 65537n + }); + + assert.strictEqual(privateKey.type, 'private'); + assert.strictEqual(privateKey.asymmetricKeyType, 'rsa-pss'); + assert.deepStrictEqual(privateKey.asymmetricKeyDetails, { + modulusLength: 512, +- publicExponent: 65537n, +- hashAlgorithm: 'sha256', +- mgf1HashAlgorithm: 'sha256', +- saltLength: 16 ++ publicExponent: 65537n + }); + })); + } diff --git a/skip_no_console.patch b/skip_no_console.patch new file mode 100644 index 0000000..5d562f6 --- /dev/null +++ b/skip_no_console.patch @@ -0,0 +1,29 @@ +Index: node-v14.3.0/test/parallel/test-repl-mode.js +=================================================================== +--- node-v14.3.0.orig/test/parallel/test-repl-mode.js ++++ node-v14.3.0/test/parallel/test-repl-mode.js +@@ -1,9 +1,11 @@ + 'use strict'; +-require('../common'); ++const common = require('../common'); + const assert = require('assert'); + const Stream = require('stream'); + const repl = require('repl'); + ++common.skipIfDumbTerminal(); ++ + const tests = [ + testSloppyMode, + testStrictMode, +Index: node-v14.3.0/test/parallel/test-repl-strict-mode-previews.js +=================================================================== +--- node-v14.3.0.orig/test/parallel/test-repl-strict-mode-previews.js ++++ node-v14.3.0/test/parallel/test-repl-strict-mode-previews.js +@@ -5,6 +5,7 @@ + const common = require('../common'); + + common.skipIfInspectorDisabled(); ++common.skipIfDumbTerminal(); + + if (process.argv[2] === 'child') { + const stream = require('stream'); diff --git a/sle12_python3_compat.patch b/sle12_python3_compat.patch new file mode 100644 index 0000000..1e0632d --- /dev/null +++ b/sle12_python3_compat.patch @@ -0,0 +1,35 @@ +Index: node-v16.13.0/configure +=================================================================== +--- node-v16.13.0.orig/configure ++++ node-v16.13.0/configure +@@ -22,7 +22,7 @@ except ImportError: + from distutils.spawn import find_executable as which + + print('Node.js configure: Found Python {}.{}.{}...'.format(*sys.version_info)) +-acceptable_pythons = ((3, 10), (3, 9), (3, 8), (3, 7), (3, 6)) ++acceptable_pythons = ((3, 10), (3, 9), (3, 8), (3, 7), (3, 6), (3, 4)) + if sys.version_info[:2] in acceptable_pythons: + import configure + else: +Index: node-v16.13.0/deps/npm/node_modules/node-gyp/lib/find-python.js +=================================================================== +--- node-v16.13.0.orig/deps/npm/node_modules/node-gyp/lib/find-python.js ++++ node-v16.13.0/deps/npm/node_modules/node-gyp/lib/find-python.js +@@ -15,7 +15,7 @@ const programFiles = process.env.Program + const programFilesX86 = process.env['ProgramFiles(x86)'] || `${programFiles} (x86)` + + const winDefaultLocationsArray = [] +-for (const majorMinor of ['39', '38', '37', '36']) { ++for (const majorMinor of ['39', '38', '37', '36', '34']) { + if (foundLocalAppData) { + winDefaultLocationsArray.push( + `${localAppData}\\Programs\\Python\\Python${majorMinor}\\python.exe`, +@@ -49,7 +49,7 @@ PythonFinder.prototype = { + log: logWithPrefix(log, 'find Python'), + argsExecutable: ['-c', 'import sys; print(sys.executable);'], + argsVersion: ['-c', 'import sys; print("%s.%s.%s" % sys.version_info[:3]);'], +- semverRange: '>=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..418c402 --- /dev/null +++ b/test-skip-y2038-on-32bit-time_t.patch @@ -0,0 +1,42 @@ +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 armv7l. 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,23 @@ 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() === '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..285749a --- /dev/null +++ b/versioned.patch @@ -0,0 +1,518 @@ +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-v18.2.0/Makefile +=================================================================== +--- node-v18.2.0.orig/Makefile ++++ node-v18.2.0/Makefile +@@ -55,7 +55,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 = node18$(EXEEXT) + NODE ?= ./$(NODE_EXE) + NODE_G_EXE = node_g$(EXEEXT) + NPM ?= ./deps/npm/bin/npm-cli.js +Index: node-v18.2.0/tools/install.py +=================================================================== +--- node-v18.2.0.orig/tools/install.py ++++ node-v18.2.0/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 + '18/' + + # 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 + '18/' + 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', ++ 'npm18': 'bin/npm-cli.js', ++ 'npx18': 'bin/npx-cli.js', + }) + + def corepack_files(action): + package_files(action, 'corepack', { +- 'corepack': 'dist/corepack.js', ++ 'corepack18': 'dist/corepack.js', + # Not the default just yet: + # 'yarn': 'dist/yarn.js', + # 'yarnpkg': 'dist/yarn.js', +@@ -136,7 +136,7 @@ def subdir_files(path, dest, action): + + def files(action): + is_windows = sys.platform == 'win32' +- output_file = 'node' ++ output_file = 'node18' + output_prefix = 'out/Release/' + + if is_windows: +@@ -154,7 +154,7 @@ def files(action): + action(['out/Release/node.d'], libdir() + '/dtrace/node.d') + + # behave similarly for systemtap +- action(['src/node.stp'], 'share/systemtap/tapset/') ++ action(['src/node.stp'], 'share/systemtap/tapset/node18.stp') + + action(['deps/v8/tools/gdbinit'], 'share/doc/node/') + action(['deps/v8/tools/lldb_commands.py'], 'share/doc/node/') +@@ -162,7 +162,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/node18.1') + + if 'true' == variables.get('node_install_npm'): + npm_files(action) +@@ -249,28 +249,28 @@ def headers(action): + 'src/node_buffer.h', + 'src/node_object_wrap.h', + 'src/node_version.h', +- ], 'include/node/') ++ ], 'include/node18/') + + # Add the expfile that is created on AIX + if sys.platform.startswith('aix'): +- action(['out/Release/node.exp'], 'include/node/') ++ action(['out/Release/node.exp'], 'include/node18/') + +- subdir_files('deps/v8/include', 'include/node/', wanted_v8_headers) ++ subdir_files('deps/v8/include', 'include/node18/', wanted_v8_headers) + + if 'false' == variables.get('node_shared_libuv'): +- subdir_files('deps/uv/include', 'include/node/', action) ++ subdir_files('deps/uv/include', 'include/node18/', 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/node18/openssl/', action) ++ subdir_files('deps/openssl/config/archs', 'include/node18/openssl/archs', action) ++ subdir_files('deps/openssl/config', 'include/node18/openssl', action) + + if 'false' == variables.get('node_shared_zlib'): + action([ + 'deps/zlib/zconf.h', + 'deps/zlib/zlib.h', +- ], 'include/node/') ++ ], 'include/node18/') + + if sys.platform == 'zos': + zoslibinc = os.environ.get('ZOSLIB_INCLUDES') +Index: node-v18.2.0/doc/node.1 +=================================================================== +--- node-v18.2.0.orig/doc/node.1 ++++ node-v18.2.0/doc/node.1 +@@ -30,24 +30,24 @@ + .Dt NODE 1 + . + .Sh NAME +-.Nm node ++.Nm node18 + .Nd server-side JavaScript runtime + . + .\"====================================================================== + .Sh SYNOPSIS +-.Nm node ++.Nm node18 + .Op Ar options + .Op Ar v8-options + .Op Fl e Ar string | Ar script.js | Fl + .Op Fl - + .Op Ar arguments ... + . +-.Nm node ++.Nm node18 + .Cm inspect + .Op Fl e Ar string | Ar script.js | Fl | Ar : + .Ar ... + . +-.Nm node ++.Nm node18 + .Op Fl -v8-options + . + .\"====================================================================== +Index: node-v18.2.0/src/node.stp +=================================================================== +--- node-v18.2.0.orig/src/node.stp ++++ node-v18.2.0/src/node.stp +@@ -19,7 +19,7 @@ + // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + // USE OR OTHER DEALINGS IN THE SOFTWARE. + +-probe node_net_server_connection = process("node").mark("net__server__connection") ++probe node_net_server_connection = process("node18").mark("net__server__connection") + { + remote = user_string($arg2); + port = $arg3; +@@ -32,7 +32,7 @@ probe node_net_server_connection = proce + fd); + } + +-probe node_net_stream_end = process("node").mark("net__stream__end") ++probe node_net_stream_end = process("node18").mark("net__stream__end") + { + remote = user_string($arg2); + port = $arg3; +@@ -45,7 +45,7 @@ probe node_net_stream_end = process("nod + fd); + } + +-probe node_http_server_request = process("node").mark("http__server__request") ++probe node_http_server_request = process("node18").mark("http__server__request") + { + remote = user_string($arg3); + port = $arg4; +@@ -62,7 +62,7 @@ probe node_http_server_request = process + fd); + } + +-probe node_http_server_response = process("node").mark("http__server__response") ++probe node_http_server_response = process("node18").mark("http__server__response") + { + remote = user_string($arg2); + port = $arg3; +@@ -75,7 +75,7 @@ probe node_http_server_response = proces + fd); + } + +-probe node_http_client_request = process("node").mark("http__client__request") ++probe node_http_client_request = process("node18").mark("http__client__request") + { + remote = user_string($arg3); + port = $arg4; +@@ -92,7 +92,7 @@ probe node_http_client_request = process + fd); + } + +-probe node_http_client_response = process("node").mark("http__client__response") ++probe node_http_client_response = process("node18").mark("http__client__response") + { + remote = user_string($arg2); + port = $arg3; +@@ -105,7 +105,7 @@ probe node_http_client_response = proces + fd); + } + +-probe node_gc_start = process("node").mark("gc__start") ++probe node_gc_start = process("node18").mark("gc__start") + { + scavenge = 1 << 0; + compact = 1 << 1; +@@ -125,7 +125,7 @@ probe node_gc_start = process("node").ma + flags); + } + +-probe node_gc_stop = process("node").mark("gc__done") ++probe node_gc_stop = process("node18").mark("gc__done") + { + scavenge = 1 << 0; + compact = 1 << 1; +Index: node-v18.2.0/deps/npm/man/man1/npm.1 +=================================================================== +--- node-v18.2.0.orig/deps/npm/man/man1/npm.1 ++++ node-v18.2.0/deps/npm/man/man1/npm.1 +@@ -1,6 +1,6 @@ + .TH "NPM" "1" "May 2022" "" "" + .SH "NAME" +-\fBnpm\fR \- javascript package manager ++\fBnpm18\fR \- javascript package manager + .SS Synopsis + .SS Version + .P +@@ -15,7 +15,7 @@ It is extremely configurable to support + commonly, you use it to publish, discover, install, and develop node + programs\. + .P +-Run \fBnpm help\fP to get a list of available commands\. ++Run \fBnpm18 help\fP to get a list of available commands\. + .SS Important + .P + npm comes preconfigured to use npm's public registry at +@@ -31,14 +31,14 @@ their terms of use\. + You probably got npm because you want to install stuff\. + .P + The very first thing you will most likely want to run in any node +-program is \fBnpm install\fP to install its dependencies\. ++program is \fBnpm18 install\fP to install its dependencies\. + .P +-You can also run \fBnpm install blerg\fP to install the latest version of ++You can also run \fBnpm18 install blerg\fP to install the latest version of + "blerg"\. Check out npm help \fBinstall\fP for more + info\. It can do a lot of stuff\. + .P +-Use the \fBnpm search\fP command to show everything that's available in the +-public registry\. Use \fBnpm ls\fP to show everything you've installed\. ++Use the \fBnpm18 search\fP command to show everything that's available in the ++public registry\. Use \fBnpm18 ls\fP to show everything you've installed\. + .SS Dependencies + .P + If a package lists a dependency using a git URL, npm will install that +@@ -87,7 +87,7 @@ npm help \fBpackage\.json\fP\|\. + .IP \(bu 2 + link: + Links your current working code into Node's path, so that you don't +-have to reinstall every time you make a change\. Use npm help \fBnpm ++have to reinstall every time you make a change\. Use npm help \fBnpm18 + link\fP to do this\. + .IP \(bu 2 + install: +@@ -170,18 +170,18 @@ https://github\.com/npm/rfcs + .SS See Also + .RS 0 + .IP \(bu 2 +-npm help help ++npm18 help help + .IP \(bu 2 +-npm help package\.json ++npm18 help package\.json + .IP \(bu 2 +-npm help npmrc ++npm18 help npmrc + .IP \(bu 2 +-npm help config ++npm18 help config + .IP \(bu 2 +-npm help install ++npm18 help install + .IP \(bu 2 +-npm help prefix ++npm18 help prefix + .IP \(bu 2 +-npm help publish ++npm18 help publish + + .RE +Index: node-v18.2.0/src/node_main.cc +=================================================================== +--- node-v18.2.0.orig/src/node_main.cc ++++ node-v18.2.0/src/node_main.cc +@@ -122,6 +122,7 @@ int main(int argc, char* argv[]) { + #endif + // Disable stdio buffering, it interacts poorly with printf() + // calls elsewhere in the program (e.g., any logging from V8.) ++ setenv("NODE_VERSION", "18", 0); + setvbuf(stdout, nullptr, _IONBF, 0); + setvbuf(stderr, nullptr, _IONBF, 0); + return node::Start(argc, argv); +Index: node-v18.2.0/tools/test.py +=================================================================== +--- node-v18.2.0.orig/tools/test.py ++++ node-v18.2.0/tools/test.py +@@ -935,7 +935,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/node18' + else: + name = 'out/%s.%s/node' % (arch, mode) + +Index: node-v18.2.0/node.gyp +=================================================================== +--- node-v18.2.0.orig/node.gyp ++++ node-v18.2.0/node.gyp +@@ -24,8 +24,8 @@ + 'node_use_openssl%': 'true', + 'node_shared_openssl%': 'false', + 'node_v8_options%': '', +- 'node_core_target_name%': 'node', +- 'node_lib_target_name%': 'libnode', ++ 'node_core_target_name%': 'node18', ++ 'node_lib_target_name%': 'libnode18', + 'node_intermediate_lib_type%': 'static_library', + 'node_builtin_modules_path%': '', + # We list the deps/ files out instead of globbing them in js2c.py since we +Index: node-v18.2.0/deps/npm/man/man1/npx.1 +=================================================================== +--- node-v18.2.0.orig/deps/npm/man/man1/npx.1 ++++ node-v18.2.0/deps/npm/man/man1/npx.1 +@@ -5,10 +5,10 @@ + .P + .RS 2 + .nf +-npx \-\- [@] [args\.\.\.] +-npx \-\-package=[@] \-\- [args\.\.\.] +-npx \-c ' [args\.\.\.]' +-npx \-\-package=foo \-c ' [args\.\.\.]' ++npx18 \-\- [@] [args\.\.\.] ++npx18 \-\-package=[@] \-\- [args\.\.\.] ++npx18 \-c ' [args\.\.\.]' ++npx18 \-\-package=foo \-c ' [args\.\.\.]' + .fi + .RE + .SS Description +@@ -57,9 +57,9 @@ no bin entries, or none of them match th + To run a binary \fIother than\fR the named binary, specify one or more + \fB\-\-package\fP options, which will prevent npm from inferring the package from + the first command argument\. +-.SS \fBnpx\fP vs \fBnpm exec\fP ++.SS \fBnpx18\fP vs \fBnpm exec\fP + .P +-When run via the \fBnpx\fP binary, all flags and options \fImust\fR be set prior to ++When run via the \fBnpx18\fP binary, all flags and options \fImust\fR be set prior to + any positional arguments\. When run via \fBnpm exec\fP, a double\-hyphen \fB\-\-\fP + flag can be used to suppress npm's parsing of switches and options that + should be sent to the executed command\. +@@ -68,7 +68,7 @@ For example: + .P + .RS 2 + .nf +-$ npx foo@latest bar \-\-package=@npmcli/foo ++$ npx18 foo@latest bar \-\-package=@npmcli/foo + .fi + .RE + .P +@@ -89,7 +89,7 @@ different: + .P + .RS 2 + .nf +-$ npm exec foo@latest bar \-\-package=@npmcli/foo ++$ npm18 exec foo@latest bar \-\-package=@npmcli/foo + .fi + .RE + .P +@@ -105,11 +105,11 @@ $ foo@latest bar + .P + The double\-hyphen character is recommended to explicitly tell npm to stop + parsing command line options and switches\. The following command would +-thus be equivalent to the \fBnpx\fP command above: ++thus be equivalent to the \fBnpx18\fP command above: + .P + .RS 2 + .nf +-$ npm exec \-\- foo@latest bar \-\-package=@npmcli/foo ++$ npm18 exec \-\- foo@latest bar \-\-package=@npmcli/foo + .fi + .RE + .SS Examples +@@ -119,8 +119,8 @@ arguments: + .P + .RS 2 + .nf +-$ npm exec \-\- tap \-\-bail test/foo\.js +-$ npx tap \-\-bail test/foo\.js ++$ npm18 exec \-\- tap \-\-bail test/foo\.js ++$ npx18 tap \-\-bail test/foo\.js + .fi + .RE + .P +@@ -129,9 +129,9 @@ by specifying a \fB\-\-package\fP option + .P + .RS 2 + .nf +-$ npm exec \-\-package=foo \-\- bar \-\-bar\-argument ++$ npm18 exec \-\-package=foo \-\- bar \-\-bar\-argument + # ~ or ~ +-$ npx \-\-package=foo bar \-\-bar\-argument ++$ npx18 \-\-package=foo bar \-\-bar\-argument + .fi + .RE + .P +@@ -139,14 +139,14 @@ Run an arbitrary shell script, in the co + .P + .RS 2 + .nf +-$ npm x \-c 'eslint && say "hooray, lint passed"' +-$ npx \-c 'eslint && say "hooray, lint passed"' ++$ npm18 x \-c 'eslint && say "hooray, lint passed"' ++$ npx18 \-c 'eslint && say "hooray, lint passed"' + .fi + .RE + .SS Compatibility with Older npx Versions + .P +-The \fBnpx\fP binary was rewritten in npm v7\.0\.0, and the standalone \fBnpx\fP +-package deprecated at that time\. \fBnpx\fP uses the \fBnpm exec\fP ++The \fBnpx18\fP binary was rewritten in npm v7\.0\.0, and the standalone \fBnpx18\fP ++package deprecated at that time\. \fBnpx18\fP uses the \fBnpm18 exec\fP + command instead of a separate argument parser and install process, with + some affordances to maintain backwards compatibility with the arguments it + accepted in previous versions\. +@@ -154,10 +154,10 @@ accepted in previous versions\. + This resulted in some shifts in its functionality: + .RS 0 + .IP \(bu 2 +-Any \fBnpm\fP config value may be provided\. ++Any \fBnpm18\fP config value may be provided\. + .IP \(bu 2 + To prevent security and user\-experience problems from mistyping package +-names, \fBnpx\fP prompts before installing anything\. Suppress this ++names, \fBnpx18\fP prompts before installing anything\. Suppress this + prompt with the \fB\-y\fP or \fB\-\-yes\fP option\. + .IP \(bu 2 + The \fB\-\-no\-install\fP option is deprecated, and will be converted to \fB\-\-no\fP\|\. +@@ -165,13 +165,13 @@ The \fB\-\-no\-install\fP option is depr + Shell fallback functionality is removed, as it is not advisable\. + .IP \(bu 2 + The \fB\-p\fP argument is a shorthand for \fB\-\-parseable\fP in npm, but shorthand +-for \fB\-\-package\fP in npx\. This is maintained, but only for the \fBnpx\fP ++for \fB\-\-package\fP in npx\. This is maintained, but only for the \fBnpx18\fP + executable\. + .IP \(bu 2 + The \fB\-\-ignore\-existing\fP option is removed\. Locally installed bins are + always present in the executed process \fBPATH\fP\|\. + .IP \(bu 2 +-The \fB\-\-npm\fP option is removed\. \fBnpx\fP will always use the \fBnpm\fP it ships ++The \fB\-\-npm18\fP option is removed\. \fBnpx18\fP will always use the \fBnpm18\fP it ships + with\. + .IP \(bu 2 + The \fB\-\-node\-arg\fP and \fB\-n\fP options are removed\. +@@ -179,26 +179,26 @@ The \fB\-\-node\-arg\fP and \fB\-n\fP op + The \fB\-\-always\-spawn\fP option is redundant, and thus removed\. + .IP \(bu 2 + The \fB\-\-shell\fP option is replaced with \fB\-\-script\-shell\fP, but maintained +-in the \fBnpx\fP executable for backwards compatibility\. ++in the \fBnpx18\fP executable for backwards compatibility\. + + .RE + .SS See Also + .RS 0 + .IP \(bu 2 +-npm help run\-script ++npm18 help run\-script + .IP \(bu 2 +-npm help scripts ++npm18 help scripts + .IP \(bu 2 +-npm help test ++npm18 help test + .IP \(bu 2 +-npm help start ++npm18 help start + .IP \(bu 2 +-npm help restart ++npm18 help restart + .IP \(bu 2 +-npm help stop ++npm18 help stop + .IP \(bu 2 +-npm help config ++npm18 help config + .IP \(bu 2 +-npm help exec ++npm18 help exec + + .RE