#!/bin/sh # Uses Argbash to generate command argument parsing. To update # arguments, make sure to call # `argbash nodejs-tarball.sh -o nodejs-tarball.sh` # ARG_POSITIONAL_SINGLE([version],[Node.js release version]) # ARG_OPTIONAL_BOOLEAN([push],[],[Whether to upload to the lookaside cache],[on]) # ARG_OPTIONAL_BOOLEAN([debug],[],[Print all commands],[off]) # ARG_DEFAULTS_POS([]) # ARG_HELP([Tool to aid in Node.js packaging of new releases]) # ARGBASH_GO() # needed because of Argbash --> m4_ignore([ ### START OF CODE GENERATED BY Argbash v2.10.0 one line above ### # Argbash is a bash code generator used to get arguments parsing right. # Argbash is FREE SOFTWARE, see https://argbash.io for more info die() { local _ret="${2:-1}" test "${_PRINT_HELP:-no}" = yes && print_help >&2 echo "$1" >&2 exit "${_ret}" } begins_with_short_option() { local first_option all_short_options='h' first_option="${1:0:1}" test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0 } # THE DEFAULTS INITIALIZATION - POSITIONALS _positionals=() _arg_version= # THE DEFAULTS INITIALIZATION - OPTIONALS _arg_push="on" _arg_debug="off" _arg_install_missing_tools="off" print_help() { printf '%s\n' "Tool to aid in Node.js packaging of new releases" printf 'Usage: %s [--(no-)push] [--(no-)debug] [-h|--help] \n' "$0" printf '\t%s\n' ": Node.js release version" printf '\t%s\n' "--push, --no-push: Whether to upload to the lookaside cache (on by default)" printf '\t%s\n' "--debug, --no-debug: Print all commands (off by default)" printf '\t%s\n' "--install-missing-tools, --no-install-missing-tools: Automatically install missing tools that this script requires (off by default)" printf '\t%s\n' "-h, --help: Prints help" } parse_commandline() { _positionals_count=0 while test $# -gt 0 do _key="$1" case "$_key" in --no-push|--push) _arg_push="on" test "${1:0:5}" = "--no-" && _arg_push="off" ;; --no-debug|--debug) _arg_debug="on" test "${1:0:5}" = "--no-" && _arg_debug="off" ;; --no-install-missing-tools|--install-missing-tools) _arg_install_missing_tools="on" test "${1:0:5}" = "--no-" && _arg_install_missing_tools="off" ;; -h|--help) print_help exit 0 ;; -h*) print_help exit 0 ;; *) _last_positional="$1" _positionals+=("$_last_positional") _positionals_count=$((_positionals_count + 1)) ;; esac shift done } handle_passed_args_count() { local _required_args_string="'version'" test "${_positionals_count}" -ge 1 || _PRINT_HELP=yes die "FATAL ERROR: Not enough positional arguments - we require exactly 1 (namely: $_required_args_string), but got only ${_positionals_count}." 1 test "${_positionals_count}" -le 1 || _PRINT_HELP=yes die "FATAL ERROR: There were spurious positional arguments --- we expect exactly 1 (namely: $_required_args_string), but got ${_positionals_count} (the last one was: '${_last_positional}')." 1 } assign_positional_args() { local _positional_name _shift_for=$1 _positional_names="_arg_version " shift "$_shift_for" for _positional_name in ${_positional_names} do test $# -gt 0 || break eval "$_positional_name=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1 shift done } parse_commandline "$@" handle_passed_args_count assign_positional_args 1 "${_positionals[@]}" # OTHER STUFF GENERATED BY Argbash ### END OF CODE GENERATED BY Argbash (sortof) ### ]) # [ <-- needed because of Argbash if [ $_arg_debug = 'on' ]; then set -x fi SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" alias wget='wget --quiet' # wget is actually provided by wget2-wget in F40 and RHEL 10 and beyond, # so let's figure out a correct package name based on the current system # to not try to find a package that is called differently. Otherwise we # would try to install a package that is not necessary or available. wget_name=$( . /etc/os-release ; if [ "${PLATFORM_ID:9:2}" = "f4" ] || [ "${PLATFORM_ID:9:3}" = el1 ] ; then echo wget2-wget ; else echo wget ; fi) packages=("jq" "$wget_name" "tar" "fedpkg" "grep" "sed" "python3-jinja2-cli" "nodejs") rpm -q ${packages[@]} >/dev/null if [ $? -ne 0 ]; then echo "Some of the required tools missing: ${packages[@]}" >&2 if [ $_arg_install_missing_tools = 'on' ]; then echo "Installing them automatically" >&2 sudo dnf -y install ${packages[@]} else die "Please, install them manually or specify --install-missing-tools=on argument." fi fi set -e version=$_arg_version NODE_MAJOR=$(echo $version | cut -d. -f1) NODE_MINOR=$(echo $version | cut -d. -f2) NODE_PATCH=$(echo $version | cut -d. -f3) # Treat odd-numbered major releases as pre-releases for the # next LTS release. if [[ $((NODE_MAJOR % 2)) -eq 0 ]]; then NODE_PKG_MAJOR=${NODE_MAJOR}; else NODE_PKG_MAJOR=$((NODE_MAJOR + 1)); fi FEDORA_DEFAULT_RELEASE_LOW=$((NODE_PKG_MAJOR + 19)) FEDORA_DEFAULT_RELEASE_HIGH=$((NODE_PKG_MAJOR + 20)) if [[ $((NODE_PKG_MAJOR)) -eq 20 ]] then RHEL_DEFAULT_RELEASE=" || 0%{?rhel} == 10" elif [[ $((NODE_PKG_MAJOR)) -eq 22 ]]; then RHEL_DEFAULT_RELEASE=" || 0%{?rhel} == 11" fi rm -rf node-v${version}.tar.gz \ node-v${version}-stripped.tar.gz \ node-v${version}/ \ wasi-sdk-* \ cjs-module-lexer* \ undici* \ SHASUMS256.txt echo Downloading node-v${version}.tar.gz wget http://nodejs.org/dist/v${version}/node-v${version}.tar.gz \ http://nodejs.org/dist/v${version}/SHASUMS256.txt echo Validating sha256sum sha256sum -c SHASUMS256.txt --ignore-missing rm -f SHASUMS256.txt tar -zxf node-v${version}.tar.gz # Remove bundled OpenSSL # We will link to the system version rm -rf node-v${version}/deps/openssl tar -zcf node-v${version}-stripped.tar.gz node-v${version} # Record the bundled cjs-module-lexer version LEXER_VERSION=$(jq -r '.version' node-v${version}/deps/cjs-module-lexer/package.json) # Record the bundled undici version UNDICI_VERSION=$(jq -r '.version' node-v${version}/deps/undici/src/package.json) ICU_MAJOR=$(jq -r '.[0].url' node-v${version}/tools/icu/current_ver.dep | sed --expression='s/.*release-\([[:digit:]]\+\)-\([[:digit:]]\+\).*/\1/g') ICU_MINOR=$(jq -r '.[0].url' node-v${version}/tools/icu/current_ver.dep | sed --expression='s/.*release-\([[:digit:]]\+\)-\([[:digit:]]\+\).*/\2/g') # Download the ICU binary data files rm -Rf icu4c-${ICU_MAJOR}_${ICU_MINOR}-data-bin-*.zip wget $(grep Source3 packaging/nodejs.spec.j2 | sed --expression="s/.*http/http/g" --expression="s/\(\%{icu_major}\)/${ICU_MAJOR}/g" --expression="s/\(\%{icu_minor}\)/${ICU_MINOR}/g") wget $(grep Source4 packaging/nodejs.spec.j2 | sed --expression="s/.*http/http/g" --expression="s/\(\%{icu_major}\)/${ICU_MAJOR}/g" --expression="s/\(\%{icu_minor}\)/${ICU_MINOR}/g") rm -f node-v${version}.tar.gz set +e # Determine the bundled versions of the various packages echo "Included software versions" echo "-------------------------" echo echo "Node.js version" echo "=========================" echo "${version}" echo echo "libnode shared object version" echo "=========================" NODE_SOVERSION=$(grep -oP '(?<=#define NODE_MODULE_VERSION )\d+' node-v${version}/src/node_version.h) echo "${NODE_SOVERSION}" echo echo "V8" echo "=========================" V8_MAJOR=$(grep -oP '(?<=#define V8_MAJOR_VERSION )\d+' node-v${version}/deps/v8/include/v8-version.h) V8_MINOR=$(grep -oP '(?<=#define V8_MINOR_VERSION )\d+' node-v${version}/deps/v8/include/v8-version.h) V8_BUILD=$(grep -oP '(?<=#define V8_BUILD_NUMBER )\d+' node-v${version}/deps/v8/include/v8-version.h) V8_PATCH=$(grep -oP '(?<=#define V8_PATCH_LEVEL )\d+' node-v${version}/deps/v8/include/v8-version.h) echo "${V8_MAJOR}.${V8_MINOR}.${V8_BUILD}.${V8_PATCH}" echo echo "c-ares" echo "=========================" C_ARES_VERSION=$(grep -oP '(?<=#define ARES_VERSION_STR ).*\"' node-v${version}/deps/cares/include/ares_version.h |sed -e 's/^"//' -e 's/"$//') echo $C_ARES_VERSION echo echo "llhttp" echo "=========================" LLHTTP_MAJOR=$(grep -oP '(?<=#define LLHTTP_VERSION_MAJOR )\d+' node-v${version}/deps/llhttp/include/llhttp.h) LLHTTP_MINOR=$(grep -oP '(?<=#define LLHTTP_VERSION_MINOR )\d+' node-v${version}/deps/llhttp/include/llhttp.h) LLHTTP_PATCH=$(grep -oP '(?<=#define LLHTTP_VERSION_PATCH )\d+' node-v${version}/deps/llhttp/include/llhttp.h) LLHTTP_VERSION="${LLHTTP_MAJOR}.${LLHTTP_MINOR}.${LLHTTP_PATCH}" echo $LLHTTP_VERSION echo echo "libuv" echo "=========================" UV_MAJOR=$(grep -oP '(?<=#define UV_VERSION_MAJOR )\d+' node-v${version}/deps/uv/include/uv/version.h) UV_MINOR=$(grep -oP '(?<=#define UV_VERSION_MINOR )\d+' node-v${version}/deps/uv/include/uv/version.h) UV_PATCH=$(grep -oP '(?<=#define UV_VERSION_PATCH )\d+' node-v${version}/deps/uv/include/uv/version.h) LIBUV_VERSION="${UV_MAJOR}.${UV_MINOR}.${UV_PATCH}" echo $LIBUV_VERSION echo echo "nghttp2" echo "=========================" NGHTTP2_VERSION=$(grep -oP '(?<=#define NGHTTP2_VERSION ).*\"' node-v${version}/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h |sed -e 's/^"//' -e 's/"$//') echo $NGHTTP2_VERSION echo echo "nghttp3" echo "=========================" NGHTTP3_VERSION=$(grep -oP '(?<=#define NGHTTP3_VERSION ).*\"' node-v${version}/deps/ngtcp2/nghttp3/lib/includes/nghttp3/version.h |sed -e 's/^"//' -e 's/"$//') echo $NGHTTP3_VERSION echo echo "ngtcp2" echo "=========================" NGTCP2_VERSION=$(grep -oP '(?<=#define NGTCP2_VERSION ).*\"' node-v${version}/deps/ngtcp2/ngtcp2/lib/includes/ngtcp2/version.h |sed -e 's/^"//' -e 's/"$//') echo $NGTCP2_VERSION echo echo "ICU" echo "=========================" echo "${ICU_MAJOR}.${ICU_MINOR}" echo echo "simdutf" echo "=========================" SIMDUTF_VERSION=$(grep -oP '(?<=#define SIMDUTF_VERSION ).*\"' node-v${version}/deps/simdutf/simdutf.h |sed -e 's/^"//' -e 's/"$//') echo $SIMDUTF_VERSION echo echo "punycode" echo "=========================" PUNYCODE_VERSION=$(/usr/bin/node -e "console.log(require('punycode').version)") echo $PUNYCODE_VERSION echo echo "uvwasi" echo "=========================" UVWASI_MAJOR=$(grep -oP '(?<=#define UVWASI_VERSION_MAJOR )\d+' node-v${version}/deps/uvwasi/include/uvwasi.h) UVWASI_MINOR=$(grep -oP '(?<=#define UVWASI_VERSION_MINOR )\d+' node-v${version}/deps/uvwasi/include/uvwasi.h) UVWASI_PATCH=$(grep -oP '(?<=#define UVWASI_VERSION_PATCH )\d+' node-v${version}/deps/uvwasi/include/uvwasi.h) UVWASI_VERSION="${UVWASI_MAJOR}.${UVWASI_MINOR}.${UVWASI_PATCH}" echo $UVWASI_VERSION echo echo "npm" echo "=========================" NPM_VERSION=$(jq -r .version ./node-v${version}/deps/npm/package.json) echo $NPM_VERSION echo echo "zlib" echo "=========================" ZLIB_VERSION=$(grep -oP '(?<=#define ZLIB_VERSION ).*\"' node-v${version}/deps/zlib/zlib.h |sed -e 's/^"//' -e 's/"$//') echo $ZLIB_VERSION echo echo "cjs-module-lexer" echo "=========================" echo "${LEXER_VERSION}" echo echo "undici" echo "=========================" echo "${UNDICI_VERSION}" echo echo "ada" echo "=========================" ADA_VERSION=$(grep -osP '(?<=#define ADA_VERSION ).*\"' node-v${version}/deps/ada/ada.h |sed -e 's/^"//' -e 's/"$//') ADA_VERSION=${ADA_VERSION:-0} echo "${ADA_VERSION}" echo echo "Applying versions to spec template" # Get the list of patches we need to add to the specfile readarray -t patchlist < <(git ls-files |grep '^[0-9]\{4\}-.*\.patch') json_patchlist=$(jq --compact-output --null-input '$ARGS.positional' --args -- "${patchlist[@]}") IFS='' read -r -d '' template_json < ${SCRIPT_DIR}/nodejs${NODE_PKG_MAJOR}.spec if [ $_arg_push = 'on' ]; then fedpkg new-sources node-v${version}-stripped.tar.gz \ icu4c-${ICU_MAJOR}_${ICU_MINOR}-data-bin-*.zip fi rm -rf node-v${version} # ] <-- needed because of Argbash