From 6a79fb8d842b2f4a7d92c46912a47c18c9dec936 Mon Sep 17 00:00:00 2001 From: Troy Dawson Date: Jan 05 2021 20:48:34 +0000 Subject: [PATCH 1/3] How to bundle nodejs libraries in Fedora in README.md --- diff --git a/README.md b/README.md index 9c45063..936aa6f 100644 --- a/README.md +++ b/README.md @@ -135,3 +135,134 @@ popd ## Submit built packages to Bodhi Follow the usual processes for stable/branched releases to submit builds for testing. + +# How to bundle nodejs libraries in Fedora +The upstream Node.js stance on [global library packages](https://nodejs.org/en/blog/npm/npm-1-0-global-vs-local-installation/) is that they are ".. best avoided if not needed." In Fedora, we take the same stance with our nodejs packages. You can provide a package that uses nodejs, but you should bundle all the nodejs libraries that are needed. + +We are providing a sample spec file and bundling script here. For more detailed packaging information go to the [Fedora Node.js Packaging Guildelines](https://docs.fedoraproject.org/en-US/packaging-guidelines/Node.js/) + +## Sample Spec File + +``` +%global npm_name my_nodejs_application +... +License: and and +... +Source0: http://registry.npmjs.org/%{npm_name}/-/%{npm_name}-%{version}.tgz +Source1: %{npm_name}-%{version}-nm-prod.tgz +Source2: %{npm_name}-%{version}-nm-dev.tgz +... +BuildRequires: nodejs-devel +... +%prep +%setup -q -n package +... +%build +# Setup bundled node modules +tar xfz %{SOURCE1} +mkdir -p node_modules +pushd node_modules +ln -s ../node_modules_prod/* . +ln -s ../node_modules_prod/.bin . +popd +... +%install +mkdir -p %{buildroot}%{nodejs_sitelib}/%{npm_name} +cp -pr index.js lib package.json %{buildroot}%{nodejs_sitelib}/%{npm_name} +# Copy over bundled nodejs modules +cp -pr node_modules node_modules_prod %{buildroot}%{nodejs_sitelib}/%{npm_name} +... +%check +%nodejs_symlink_deps --check +# Setup bundled dev node_modules for testing +tar xfz %{SOURCE2} +pushd node_modules +ln -s ../node_modules_dev/* . +popd +pushd node_modules/.bin +ln -s ../../node_modules_dev/.bin/* . +popd +# Example test run using the binary in ./node_modules/.bin/ +./node_modules/.bin/vows --spec --isolate +... +%files +%doc HISTORY.md +%license LICENSE.md +%{nodejs_sitelib}/%{npm_name} +``` + +## Sample Bundling Script +The following sample bundling script is ran `+./npm-bundler.sh [version]+` If a version is not supplied, it gets the latest version available. + +``` +#!/bin/bash +OUTPUT_DIR="${HOME}/rpmbuild/SOURCES" + +usage() { + echo "Usage `basename $0` [version] " >&2 + echo >&2 + echo " Given a npm module name, and optionally a version," >&2 + echo " download the npm, the prod and dev dependencies," >&2 + echo " each in their own tarball." >&2 + echo " Also finds licenses prod dependencies." >&2 + echo " All three tarballs and license list are copied to ${OUTPUT_DIR}" >&2 + echo >&2 + exit 1 +} + +if [ $# -lt 1 ]; then + usage +else + case $1 in + -h | --help ) + usage + ;; + * ) + PACKAGE="$1" + ;; + esac +fi + +if [ $# -ge 2 ]; then + VERSION="$2" +else + VERSION="$(npm view ${PACKAGE} version)" +fi + +TMP_DIR=$(mktemp -d -t ci-XXXXXXXXXX) +mkdir -p ${OUTPUT_DIR} +mkdir -p ${TMP_DIR} +pushd ${TMP_DIR} +npm pack ${PACKAGE} +tar xfz *.tgz +cd package +echo " Downloading prod dependencies" +npm install --no-optional --only=prod +if [ $? -ge 1 ] ; then + echo " ERROR WILL ROBINSON" + rm -rf node_modules +else + echo " Successful prod dependences download" + mv node_modules/ node_modules_prod +fi +echo "LICENSES IN BUNDLE:" +find . -name "package.json" -exec jq .license {} \; | sort -u -o ${TMP_DIR}/${PACKAGE}-${VERSION}-bundled-licenses.txt +echo " Downloading dev dependencies" +npm install --no-optional --only=dev +if [ $? -ge 1 ] ; then + echo " ERROR WILL ROBINSON" +else + echo " Successful dev dependences download" + mv node_modules/ node_modules_dev +fi +if [ -d node_modules_prod ] ; then + tar cfz ../${PACKAGE}-${VERSION}-nm-prod.tgz node_modules_prod +fi +if [ -d node_modules_dev ] ; then + tar cfz ../${PACKAGE}-${VERSION}-nm-dev.tgz node_modules_dev +fi +cd .. +cp -v ${PACKAGE}-${VERSION}* $HOME/rpmbuild/SOURCES +popd > /dev/null +rm -rf ${TMP_DIR} +``` From f3a7a05029100136a31e775b2c12c40b2927b5ec Mon Sep 17 00:00:00 2001 From: Troy Dawson Date: Jan 05 2021 22:46:28 +0000 Subject: [PATCH 2/3] add nodejs-bundler script --- diff --git a/README.md b/README.md index 936aa6f..b97bd96 100644 --- a/README.md +++ b/README.md @@ -136,11 +136,26 @@ popd Follow the usual processes for stable/branched releases to submit builds for testing. + # How to bundle nodejs libraries in Fedora + The upstream Node.js stance on [global library packages](https://nodejs.org/en/blog/npm/npm-1-0-global-vs-local-installation/) is that they are ".. best avoided if not needed." In Fedora, we take the same stance with our nodejs packages. You can provide a package that uses nodejs, but you should bundle all the nodejs libraries that are needed. We are providing a sample spec file and bundling script here. For more detailed packaging information go to the [Fedora Node.js Packaging Guildelines](https://docs.fedoraproject.org/en-US/packaging-guidelines/Node.js/) +## Bundling Script + +``` +nodejs-bundler [version] +``` + +nodejs-bundler is part of the nodejs-packaging rpm. nodejs-bundler gets the latest npm version available, if no version is given. It produces four files and puts them in ${HOME}/rpmbuild/SOURCES + + * -.tgz - This is the tarball from npm.org + * --nm-prod.tgz - This is the tarball that contains all the bundled nodejs modules needs to run + * --nm-dev.tgz - This is the tarball that contains all the bundled nodejs modules needs to test + * --bundled-licenses.txt - This lists the bundled licenses in --nm-prod.tgz + ## Sample Spec File ``` @@ -191,78 +206,3 @@ popd %{nodejs_sitelib}/%{npm_name} ``` -## Sample Bundling Script -The following sample bundling script is ran `+./npm-bundler.sh [version]+` If a version is not supplied, it gets the latest version available. - -``` -#!/bin/bash -OUTPUT_DIR="${HOME}/rpmbuild/SOURCES" - -usage() { - echo "Usage `basename $0` [version] " >&2 - echo >&2 - echo " Given a npm module name, and optionally a version," >&2 - echo " download the npm, the prod and dev dependencies," >&2 - echo " each in their own tarball." >&2 - echo " Also finds licenses prod dependencies." >&2 - echo " All three tarballs and license list are copied to ${OUTPUT_DIR}" >&2 - echo >&2 - exit 1 -} - -if [ $# -lt 1 ]; then - usage -else - case $1 in - -h | --help ) - usage - ;; - * ) - PACKAGE="$1" - ;; - esac -fi - -if [ $# -ge 2 ]; then - VERSION="$2" -else - VERSION="$(npm view ${PACKAGE} version)" -fi - -TMP_DIR=$(mktemp -d -t ci-XXXXXXXXXX) -mkdir -p ${OUTPUT_DIR} -mkdir -p ${TMP_DIR} -pushd ${TMP_DIR} -npm pack ${PACKAGE} -tar xfz *.tgz -cd package -echo " Downloading prod dependencies" -npm install --no-optional --only=prod -if [ $? -ge 1 ] ; then - echo " ERROR WILL ROBINSON" - rm -rf node_modules -else - echo " Successful prod dependences download" - mv node_modules/ node_modules_prod -fi -echo "LICENSES IN BUNDLE:" -find . -name "package.json" -exec jq .license {} \; | sort -u -o ${TMP_DIR}/${PACKAGE}-${VERSION}-bundled-licenses.txt -echo " Downloading dev dependencies" -npm install --no-optional --only=dev -if [ $? -ge 1 ] ; then - echo " ERROR WILL ROBINSON" -else - echo " Successful dev dependences download" - mv node_modules/ node_modules_dev -fi -if [ -d node_modules_prod ] ; then - tar cfz ../${PACKAGE}-${VERSION}-nm-prod.tgz node_modules_prod -fi -if [ -d node_modules_dev ] ; then - tar cfz ../${PACKAGE}-${VERSION}-nm-dev.tgz node_modules_dev -fi -cd .. -cp -v ${PACKAGE}-${VERSION}* $HOME/rpmbuild/SOURCES -popd > /dev/null -rm -rf ${TMP_DIR} -``` diff --git a/nodejs-bundler b/nodejs-bundler new file mode 100755 index 0000000..c8573c5 --- /dev/null +++ b/nodejs-bundler @@ -0,0 +1,80 @@ +#!/bin/bash +OUTPUT_DIR="${HOME}/rpmbuild/SOURCES" + +usage() { + echo "Usage `basename $0` [version] " >&2 + echo >&2 + echo " Given a npm module name, and optionally a version," >&2 + echo " download the npm, the prod and dev dependencies," >&2 + echo " each in their own tarball." >&2 + echo " Also finds licenses prod dependencies." >&2 + echo " All three tarballs and license list are copied to ${OUTPUT_DIR}" >&2 + echo >&2 + exit 1 +} + +if ! [ -f /usr/bin/npm ]; then + echo >&2 + echo "`basename $0` requires npm to run" >&2 + echo >&2 + echo "Run the following to fix this" >&2 + echo " sudo dnf install npm" >&2 + echo >&2 + exit 2 +fi + +if [ $# -lt 1 ]; then + usage +else + case $1 in + -h | --help ) + usage + ;; + * ) + PACKAGE="$1" + ;; + esac +fi + +if [ $# -ge 2 ]; then + VERSION="$2" +else + VERSION="$(npm view ${PACKAGE} version)" +fi + +TMP_DIR=$(mktemp -d -t ci-XXXXXXXXXX) +mkdir -p ${OUTPUT_DIR} +mkdir -p ${TMP_DIR} +pushd ${TMP_DIR} +npm pack ${PACKAGE} +tar xfz *.tgz +cd package +echo " Downloading prod dependencies" +npm install --no-optional --only=prod +if [ $? -ge 1 ] ; then + echo " ERROR WILL ROBINSON" + rm -rf node_modules +else + echo " Successful prod dependences download" + mv node_modules/ node_modules_prod +fi +echo "LICENSES IN BUNDLE:" +find . -name "package.json" -exec jq .license {} \; | sort -u -o ${TMP_DIR}/${PACKAGE}-${VERSION}-bundled-licenses.txt +echo " Downloading dev dependencies" +npm install --no-optional --only=dev +if [ $? -ge 1 ] ; then + echo " ERROR WILL ROBINSON" +else + echo " Successful dev dependences download" + mv node_modules/ node_modules_dev +fi +if [ -d node_modules_prod ] ; then + tar cfz ../${PACKAGE}-${VERSION}-nm-prod.tgz node_modules_prod +fi +if [ -d node_modules_dev ] ; then + tar cfz ../${PACKAGE}-${VERSION}-nm-dev.tgz node_modules_dev +fi +cd .. +cp -v ${PACKAGE}-${VERSION}* $HOME/rpmbuild/SOURCES +popd > /dev/null +rm -rf ${TMP_DIR} From 2444893206b5f9f93a9c24b1222643bc2b4ccbb8 Mon Sep 17 00:00:00 2001 From: Troy Dawson Date: Jan 06 2021 14:37:04 +0000 Subject: [PATCH 3/3] Add bundled licenses file to %license --- diff --git a/README.md b/README.md index b97bd96..fb14edc 100644 --- a/README.md +++ b/README.md @@ -166,11 +166,13 @@ License: and and Source0: http://registry.npmjs.org/%{npm_name}/-/%{npm_name}-%{version}.tgz Source1: %{npm_name}-%{version}-nm-prod.tgz Source2: %{npm_name}-%{version}-nm-dev.tgz +Source3: %{npm_name}-%{version}-bundled-licenses.txt ... BuildRequires: nodejs-devel ... %prep %setup -q -n package +cp %{SOURCE3} . ... %build # Setup bundled node modules @@ -202,7 +204,7 @@ popd ... %files %doc HISTORY.md -%license LICENSE.md +%license LICENSE.md %{npm_name}-%{version}-bundled-licenses.txt %{nodejs_sitelib}/%{npm_name} ```