From 5c31324e1192640040ddd73c0360a6490d577b8d Mon Sep 17 00:00:00 2001 From: Honza Horak Date: Tue, 16 May 2023 21:19:40 +0200 Subject: [PATCH] Replace whole repo with latest content from branch stream-14-rhel-8.8.0 Content corresponds with RHEL dist-git commit b2f72a7 --- .gitignore | 16 +- LICENSE | 19 - README.md | 218 ------ macros.nodejs | 37 - multiver_modules | 3 - nodejs-fixdep | 117 --- nodejs-packaging-bundler | 95 --- nodejs-setversion | 43 -- nodejs-symlink-deps | 141 ---- nodejs.attr | 4 - nodejs.prov | 121 --- nodejs.req | 707 ------------------ sources | 2 +- .../bundled/node_modules/test100/package.json | 4 - .../bundled/node_modules/test101/package.json | 4 - test/bundled/nodejs.prov.err.exp | 0 test/bundled/nodejs.prov.out.exp | 3 - test/bundled/nodejs.req.err.exp | 0 test/bundled/nodejs.req.out.exp | 1 - test/bundled/package.json.in | 11 - .../node_modules/@nmcli/test201/package.json | 4 - .../node_modules/test200/package.json | 4 - test/bundled_namespace/nodejs.prov.err.exp | 0 test/bundled_namespace/nodejs.prov.out.exp | 3 - test/bundled_namespace/nodejs.req.err.exp | 0 test/bundled_namespace/nodejs.req.out.exp | 1 - test/bundled_namespace/package.json.in | 11 - test/run | 18 - test/unbundled/nodejs.prov.err.exp | 0 test/unbundled/nodejs.prov.out.exp | 1 - test/unbundled/nodejs.req.err.exp | 2 - test/unbundled/nodejs.req.out.exp | 74 -- test/unbundled/package.json.in | 108 --- 33 files changed, 16 insertions(+), 1756 deletions(-) delete mode 100644 LICENSE delete mode 100644 README.md delete mode 100644 macros.nodejs delete mode 100644 multiver_modules delete mode 100755 nodejs-fixdep delete mode 100755 nodejs-packaging-bundler delete mode 100755 nodejs-setversion delete mode 100755 nodejs-symlink-deps delete mode 100644 nodejs.attr delete mode 100755 nodejs.prov delete mode 100755 nodejs.req delete mode 100644 test/bundled/node_modules/test100/package.json delete mode 100644 test/bundled/node_modules/test101/package.json delete mode 100644 test/bundled/nodejs.prov.err.exp delete mode 100644 test/bundled/nodejs.prov.out.exp delete mode 100644 test/bundled/nodejs.req.err.exp delete mode 100644 test/bundled/nodejs.req.out.exp delete mode 100644 test/bundled/package.json.in delete mode 100644 test/bundled_namespace/node_modules/@nmcli/test201/package.json delete mode 100644 test/bundled_namespace/node_modules/test200/package.json delete mode 100644 test/bundled_namespace/nodejs.prov.err.exp delete mode 100644 test/bundled_namespace/nodejs.prov.out.exp delete mode 100644 test/bundled_namespace/nodejs.req.err.exp delete mode 100644 test/bundled_namespace/nodejs.req.out.exp delete mode 100644 test/bundled_namespace/package.json.in delete mode 100755 test/run delete mode 100644 test/unbundled/nodejs.prov.err.exp delete mode 100644 test/unbundled/nodejs.prov.out.exp delete mode 100644 test/unbundled/nodejs.req.err.exp delete mode 100644 test/unbundled/nodejs.req.out.exp delete mode 100644 test/unbundled/package.json.in diff --git a/.gitignore b/.gitignore index 277649e..42aaec9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,16 @@ -SOURCES/nodejs-packaging-fedora-23.tar.xz +/nodejs-packaging-fedora-2.tar.xz +/nodejs-packaging-fedora-3.tar.xz +/nodejs-packaging-fedora-4.tar.xz +/nodejs-packaging-fedora-6.tar.xz +/nodejs-packaging-fedora-7.tar.xz +/nodejs-packaging-fedora-8.tar.xz +/nodejs-packaging-fedora-9.tar.xz +/nodejs-packaging-fedora-10.tar.xz +/nodejs-packaging-fedora-11.tar.xz +/nodejs-packaging-fedora-12.tar.xz +/nodejs-packaging-fedora-13.tar.xz +/nodejs-packaging-fedora-14.tar.xz +/nodejs-packaging-fedora-15.tar.xz +/nodejs-packaging-fedora-16.tar.xz +/nodejs-packaging-fedora-17.tar.xz /nodejs-packaging-fedora-23.tar.xz diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 3792306..0000000 --- a/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright 2012, 2013 T.C. Hollingsworth - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100644 index cbad903..0000000 --- a/README.md +++ /dev/null @@ -1,218 +0,0 @@ -# How to update Node.js in Fedora - -## Determine the Node.js version -Monitor the [Node.js Blog](https://nodejs.org/en/blog/) to be notified of -available updates. - -For simplicity and copy-and-paste of instructions below, set some variables -here: - -``` -NODEJS_MAJOR=12 -NODEJS_VERSION=12.9.0 -``` - -## Clone the Fedora package repository -These steps assume that you are a comaintainer of Node.js or a provenpackager -in Fedora. - -``` -fedpkg clone nodejs nodejs-fedora -``` - -Next, switch to the major version branch you are going to update. We'll use -Node.js 12.9.0 in this document. Adjust the versions appropriately for the -version you are working on. - -``` -pushd nodejs-fedora -fedpkg switch-branch $NODEJS_MAJOR -popd -``` - - -## Clone the Fedora Module repository - -``` -fedpkg clone modules/nodejs nodejs-fedora-module -``` - - -## Clone the upstream Node.js repository -``` -git clone -o upstream git://github.com/nodejs/node.git nodejs-upstream -``` - - -## Rebase the Fedora patches atop the latest release - -``` -pushd nodejs-upstream -git checkout -b fedora-v$NODEJS_VERSION v$NODEJS_VERSION -git am -3 ../nodejs-fedora/*.patch -``` - -If the patches do not apply cleanly, resolve the merges appropriately. Once -they have all been applied, output them again: - -``` -git format-patch -M --patience --full-index -o ../nodejs-fedora v$NODEJS_VERSION..HEAD -popd -``` - - -## Update the Node.js tarball and specfile - -``` -pushd nodejs-fedora -./nodejs-tarball.sh $NODEJS_VERSION -``` - -Note that this command will also output all of the versions for the software -bundled with Node.js. You will need to edit `nodejs.spec` and update the -%global values near the top of that file to include the appropriate values -matching the dependencies. Make sure to also update the Node.js versions too! - -Note that if libuv is updated, you need to ensure that the libuv in each -buildroot is of a sufficient version. If not, you may need to update that -package first and submit a buildroot override. - -Update the RPM spec %changelog appropriately. - - -## (Preferred) Perform a scratch-build on at least one architecture - -``` -fedpkg scratch-build [--arch x86_64] --srpm -``` - -Verify that it built successfully. - - -## Push the changes up to Fedora -``` -fedpkg commit -cs -fedpkg push -popd -``` - - -## (Optional) Build for Fedora releases - -If this major version is the default for one or more Fedora releases, build it -for them. (Note: this step will go away in the future, once module default -streams are available in the non-modular buildroot.) - -In the case of Node.js 12.x, this is the default version for Fedora 31 and 32. - -``` -pushd nodejs-fedora -fedpkg switch-branch [master|31] -git merge $NODEJS_MAJOR -fedpkg push -fedpkg build -popd -``` - -## Build module stream - -``` -pushd nodejs-fedora-module -fedpkg switch-branch $NODEJS_MAJOR -``` - -If the module has changed any package dependencies (such as added a dep on a -new shared library), you may need to modify nodejs.yaml here. If not, you can -simply run: - -``` -git commit --allow-empty -sm "Update to $NODEJS_VERSION" -fedpkg push -fedpkg module-build -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/) - -## Bundling Script - -``` -nodejs-packaging-bundler [version] -``` - -nodejs-packaging-bundler is it's own package, nodejs-packaging-bundler and must be installed before use. -nodejs-packaging-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 - -``` -%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 -Source3: %{npm_name}-%{version}-bundled-licenses.txt -... -BuildRequires: nodejs-devel -... -%prep -%setup -q -n package -cp %{SOURCE3} . -... -%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 %{npm_name}-%{version}-bundled-licenses.txt -%{nodejs_sitelib}/%{npm_name} -``` - diff --git a/macros.nodejs b/macros.nodejs deleted file mode 100644 index f86891c..0000000 --- a/macros.nodejs +++ /dev/null @@ -1,37 +0,0 @@ -# nodejs binary -%__nodejs %{_bindir}/node - -# nodejs library directory -%nodejs_sitelib %{_prefix}/lib/node_modules - -#arch specific library directory -#for future-proofing only; we don't do multilib -%nodejs_sitearch %{nodejs_sitelib} - -# currently installed nodejs version -%nodejs_version %(%{__nodejs} -v | sed s/v//) - -# symlink dependencies so `npm link` works -# this should be run in every module's %%install section -# pass --check to work in the current directory instead of the buildroot -# pass --no-devdeps to ignore devDependencies when --check is used -%nodejs_symlink_deps %{_rpmconfigdir}/nodejs-symlink-deps %{nodejs_sitelib} - -# patch package.json to fix a dependency -# see `man npm-json` for details on writing dependencies for package.json files -# e.g. `%%nodejs_fixdep frobber` makes any version of frobber do -# `%%nodejs_fixdep frobber '>1.0'` requires frobber > 1.0 -# `%%nodejs_fixdep -r frobber removes the frobber dep -%nodejs_fixdep %{_rpmconfigdir}/nodejs-fixdep - -# patch package.json to set the package version -# e.g. `%%nodejs_setversion 1.2.3` -%nodejs_setversion %{_rpmconfigdir}/nodejs-setversion - -# macro to filter unwanted provides from Node.js binary native modules -%nodejs_default_filter %{expand: \ -%global __provides_exclude_from ^%{nodejs_sitearch}/.*\\.node$ -} - -# no-op macro to allow spec compatibility with EPEL -%nodejs_find_provides_and_requires %{nil} diff --git a/multiver_modules b/multiver_modules deleted file mode 100644 index 2dc44eb..0000000 --- a/multiver_modules +++ /dev/null @@ -1,3 +0,0 @@ -uglify-js -inherits -nan \ No newline at end of file diff --git a/nodejs-fixdep b/nodejs-fixdep deleted file mode 100755 index 2569266..0000000 --- a/nodejs-fixdep +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/python3 - -"""Modify a dependency listed in a package.json file""" - -# Copyright 2013 T.C. Hollingsworth -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -import json -import optparse -import os -import re -import shutil -import sys - -RE_VERSION = re.compile(r'\s*v?([<>=~^]{0,2})\s*([0-9][0-9\.\-]*)\s*') - -p = optparse.OptionParser( - description='Modifies dependency entries in package.json files') - -p.add_option('-r', '--remove', action='store_true') -p.add_option('-m', '--move', action='store_true') -p.add_option('--dev', action='store_const', const='devDependencies', - dest='deptype', help='affect devDependencies') -p.add_option('--optional', action='store_const', const='optionalDependencies', - dest='deptype', help='affect optionalDependencies') -p.add_option('--caret', action='store_true', - help='convert all or specified dependencies to use the caret operator') - -options, args = p.parse_args() - -if not os.path.exists('package.json~'): - shutil.copy2('package.json', 'package.json~') - -md = json.load(open('package.json')) - -deptype = options.deptype if options.deptype is not None else 'dependencies' - -if deptype not in md: - md[deptype] = {} - -# convert alternate JSON dependency representations to a dictionary -if not options.caret and not isinstance(md[deptype], dict): - if isinstance(md[deptype], list): - deps = md[deptype] - md[deptype] = {} - for dep in deps: - md[deptype][dep] = '*' - elif isinstance(md[deptype], str): - md[deptype] = { md[deptype] : '*' } - -if options.remove: - dep = args[0] - del md[deptype][dep] -elif options.move: - dep = args[0] - ver = None - for fromtype in ['dependencies', 'optionalDependencies', 'devDependencies']: - if fromtype in md: - if isinstance(md[fromtype], dict) and dep in md[fromtype]: - ver = md[fromtype][dep] - del md[fromtype][dep] - elif isinstance(md[fromtype], list) and md[fromtype].count(dep) > 0: - ver = '*' - md[fromtype].remove(dep) - elif isinstance(md[fromtype], str) and md[fromtype] == dep: - ver = '*' - del md[fromtype] - if ver != None: - md[deptype][dep] = ver -elif options.caret: - if not isinstance(md[deptype], dict): - sys.stderr.write('All dependencies are unversioned. Unable to apply ' + - 'caret operator.\n') - sys.exit(2) - - deps = args if len(args) > 0 else md[deptype].keys() - for dep in deps: - if md[deptype][dep][0] == '^': - continue - elif md[deptype][dep][0] in ('~','0','1','2','3','4','5','6','7','8','9'): - ver = re.match(RE_VERSION, md[deptype][dep]).group(2) - md[deptype][dep] = '^' + ver - else: - sys.stderr.write('Attempted to convert non-numeric or tilde ' + - 'dependency to caret. This is not permitted.\n') - sys.exit(1) -else: - dep = args[0] - - if len(args) > 1: - ver = args[1] - else: - ver = '*' - - md[deptype][dep] = ver - -fh = open('package.json', 'w') -data = json.JSONEncoder(indent=4).encode(md) -fh.write(data) -fh.close() diff --git a/nodejs-packaging-bundler b/nodejs-packaging-bundler deleted file mode 100755 index 5be05e1..0000000 --- a/nodejs-packaging-bundler +++ /dev/null @@ -1,95 +0,0 @@ -#!/bin/bash -OUTPUT_DIR="$(rpm -E '%{_sourcedir}')" - -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 the 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 -# the package name might contain invalid characters, sanitize first -PACKAGE_SAFE=$(echo $PACKAGE | sed -e 's|/|-|g') -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 dependencies download" - mv node_modules/ node_modules_prod -fi -echo "LICENSES IN BUNDLE:" -find . -name "package.json" -exec jq '.license | strings' {} \; >> ${TMP_DIR}/${PACKAGE_SAFE}-${VERSION}-bundled-licenses.txt -find . -name "package.json" -exec jq '.license | objects | .type' {} \; >> ${TMP_DIR}/${PACKAGE_SAFE}-${VERSION}-bundled-licenses.txt 2>/dev/null -find . -name "package.json" -exec jq '.licenses[] .type' {} \; >> ${TMP_DIR}/${PACKAGE_SAFE}-${VERSION}-bundled-licenses.txt 2>/dev/null -sort -u -o ${TMP_DIR}/${PACKAGE_SAFE}-${VERSION}-bundled-licenses.txt ${TMP_DIR}/${PACKAGE_SAFE}-${VERSION}-bundled-licenses.txt - -# Locate any dependencies without a provided license -find . -type f -name package.json -execdir jq 'if .license==null and .licenses==null then .name else null end' '{}' '+' | grep -vE '^null$' | sort -u > ${TMP_DIR}/nolicense.txt - -if [ -s ${TMP_DIR}/nolicense.txt ]; then - echo -e "\e[5m\e[41mSome dependencies do not list a license. Manual verification required!\e[0m" - cat ${TMP_DIR}/nolicense.txt - echo -e "\e[5m\e[41m======================================================================\e[0m" -fi - - -echo " Downloading dev dependencies" -npm install --no-optional --only=dev -if [ $? -ge 1 ] ; then - echo " ERROR WILL ROBINSON" -else - echo " Successful dev dependencies download" - mv node_modules/ node_modules_dev -fi -if [ -d node_modules_prod ] ; then - tar cfz ../${PACKAGE_SAFE}-${VERSION}-nm-prod.tgz node_modules_prod -fi -if [ -d node_modules_dev ] ; then - tar cfz ../${PACKAGE_SAFE}-${VERSION}-nm-dev.tgz node_modules_dev -fi -cd .. -cp -v ${PACKAGE_SAFE}-${VERSION}* "${OUTPUT_DIR}" -popd > /dev/null -rm -rf ${TMP_DIR} diff --git a/nodejs-setversion b/nodejs-setversion deleted file mode 100755 index 49bbe1e..0000000 --- a/nodejs-setversion +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/python3 - -"""Set a package version in a package.json file""" - -# Copyright 2018 Tom Hughes -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -import json -import os -import shutil -import sys - -if not os.path.exists('package.json~'): - shutil.copy2('package.json', 'package.json~') - -md = json.load(open('package.json')) - -if 'version' in md and sys.argv[1] != md['version']: - raise RuntimeError('Version is already set to {0}'.format(md['version'])) -else: - md['version'] = sys.argv[1] - -fh = open('package.json', 'w') -data = json.JSONEncoder(indent=4).encode(md) -fh.write(data) -fh.close() diff --git a/nodejs-symlink-deps b/nodejs-symlink-deps deleted file mode 100755 index b5e44b3..0000000 --- a/nodejs-symlink-deps +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/python3 - -"""Symlink a node module's dependencies into the node_modules directory so users -can `npm link` RPM-installed modules into their personal projects.""" - -# Copyright 2012, 2013 T.C. Hollingsworth -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -import json -import os -import re -import shutil -import sys - -def symlink(source, dest): - try: - os.symlink(source, dest) - except OSError: - if os.path.islink(dest) and os.path.realpath(dest) == os.path.normpath(source): - sys.stderr.write(""" -WARNING: the symlink for dependency "{0}" already exists - -This could mean that the dependency exists in both devDependencies and -dependencies, which may cause trouble for people using this module with npm. - -Please report this to upstream. For more information, see: - -""".format(dest)) - - elif '--force' in sys.argv: - if os.path.isdir(dest): - shutil.rmtree(dest) - else: - os.unlink(dest) - - os.symlink(source, dest) - - else: - sys.stderr.write(""" -ERROR: the path for dependency "{0}" already exists - -This could mean that bundled modules are being installed. Bundled libraries are -forbidden in Fedora. For more information, see: - - -It is generally reccomended to remove the entire "node_modules" directory in -%prep when it exists. For more information, see: - - -If you have obtained permission from the Fedora Packaging Committee to bundle -libraries, please use `%nodejs_fixdep -r` in %prep to remove the dependency on -the bundled module. This will prevent an unnecessary dependency on the system -version of the module and eliminate this error. -""".format(dest)) - sys.exit(1) - - -def symlink_deps(deps, check): - if isinstance(deps, dict): - #read in the list of mutiple-versioned packages - mvpkgs = open('/usr/share/node/multiver_modules').read().split('\n') - - for dep, ver in deps.items(): - if dep in mvpkgs and ver != '' and ver != '*' and ver != 'latest': - depver = re.sub('^ *(~|\^|=|>=|<=) *', '', ver).split('.')[0] - target = os.path.join(sitelib, '{0}@{1}'.format(dep, depver)) - else: - target = os.path.join(sitelib, dep) - - if not check or os.path.exists(target): - symlink(target, dep) - - elif isinstance(deps, list): - for dep in deps: - target = os.path.join(sitelib, dep) - if not check or os.path.exists(target): - symlink(target, dep) - - elif isinstance(deps, str): - target = os.path.join(sitelib, deps) - if not check or os.path.exists(target): - symlink(target, deps) - - else: - raise TypeError("Invalid package.json: dependencies weren't a recognized type") - - -#the %nodejs_symlink_deps macro passes %nodejs_sitelib as the first argument -sitelib = sys.argv[1] - -if '--check' in sys.argv or '--build' in sys.argv: - check = True - modules = [os.getcwd()] -else: - check = False - br_sitelib = os.path.join(os.environ['RPM_BUILD_ROOT'], sitelib.lstrip('/')) - modules = [os.path.join(br_sitelib, module) for module in os.listdir(br_sitelib)] - -if '--optional' in sys.argv: - optional = True -else: - optional = False - -for path in modules: - os.chdir(path) - md = json.load(open('package.json')) - - if 'dependencies' in md or (check and 'devDependencies' in md) or (optional and 'optionalDependencies' in md): - try: - os.mkdir('node_modules') - except OSError: - sys.stderr.write('WARNING: node_modules already exists. Make sure you have ' + - 'no bundled dependencies.\n') - - os.chdir('node_modules') - - if 'dependencies' in md: - symlink_deps(md['dependencies'], check) - - if check and '--no-devdeps' not in sys.argv and 'devDependencies' in md: - symlink_deps(md['devDependencies'], check) - - if optional and 'optionalDependencies' in md: - symlink_deps(md['optionalDependencies'], check) diff --git a/nodejs.attr b/nodejs.attr deleted file mode 100644 index 1066499..0000000 --- a/nodejs.attr +++ /dev/null @@ -1,4 +0,0 @@ -%__nodejs_provides %{_rpmconfigdir}/nodejs.prov -%__nodejs_requires %{_rpmconfigdir}/nodejs.req -%__nodejs_suggests %{_rpmconfigdir}/nodejs.req --optional -%__nodejs_path ^/usr/lib(64)?/node_modules/[^/]+/package\\.json$ diff --git a/nodejs.prov b/nodejs.prov deleted file mode 100755 index 56a9bf1..0000000 --- a/nodejs.prov +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: utf-8 -*- -# Copyright 2012 T.C. Hollingsworth -# Copyright 2017 Tomas Tomecek -# Copyright 2019 Jan Staněk -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -"""Automatic provides generator for Node.js libraries. - -Metadata taken from package.json. See `man npm-json` for details. -""" - -from __future__ import print_function, with_statement - -import json -import os -import sys -from itertools import chain, groupby - -DEPENDENCY_TEMPLATE = "npm(%(name)s) = %(version)s" -BUNDLED_TEMPLATE = "bundled(nodejs-%(name)s) = %(version)s" -NODE_MODULES = {"node_modules", "node_modules_prod"} - - -class PrivatePackage(RuntimeError): - """Private package metadata that should not be listed.""" - - -#: Something is wrong with the ``package.json`` file -_INVALID_METADATA_FILE = (IOError, PrivatePackage, KeyError) - - -def format_metadata(metadata, bundled=False): - """Format ``package.json``-like metadata into RPM dependency. - - Arguments: - metadata (dict): Package metadata, presumably read from ``package.json``. - bundled (bool): Should the bundled dependency format be used? - - Returns: - str: RPM dependency (i.e. ``npm(example) = 1.0.0``) - - Raises: - KeyError: Expected key (i.e. ``name``, ``version``) missing in metadata. - PrivatePackage: The metadata indicate private (unlisted) package. - """ - - # Skip private packages - if metadata.get("private", False): - raise PrivatePackage(metadata) - - template = BUNDLED_TEMPLATE if bundled else DEPENDENCY_TEMPLATE - return template % metadata - - -def generate_dependencies(module_path, module_dir_set=NODE_MODULES): - """Generate RPM dependency for a module and all it's dependencies. - - Arguments: - module_path (str): Path to a module directory or it's ``package.json`` - module_dir_set (set): Base names of directories to look into - for bundled dependencies. - - Yields: - str: RPM dependency for the module and each of it's (public) bundled dependencies. - - Raises: - ValueError: module_path is not valid module or ``package.json`` file - """ - - # Determine paths to root module directory and package.json - if os.path.isdir(module_path): - root_dir = module_path - elif os.path.basename(module_path) == "package.json": - root_dir = os.path.dirname(module_path) - else: # Invalid metadata path - raise ValueError("Invalid module path '%s'" % module_path) - - for dir_path, subdir_list, file_list in os.walk(root_dir): - # We are only interested in directories that contain package.json - if "package.json" not in file_list: - continue - - # Read and format metadata - metadata_path = os.path.join(dir_path, "package.json") - bundled = dir_path != root_dir - try: - with open(metadata_path, mode="r") as metadata_file: - metadata = json.load(metadata_file) - yield format_metadata(metadata, bundled=bundled) - except _INVALID_METADATA_FILE: - pass # Ignore - - # Only visit subdirectories in module_dir_set - subdir_list[:] = list(module_dir_set & set(subdir_list)) - - -if __name__ == "__main__": - module_paths = (path.strip() for path in sys.stdin) - provides = chain.from_iterable(generate_dependencies(m) for m in module_paths) - - # sort|uniq - for provide, __ in groupby(sorted(provides)): - print(provide) diff --git a/nodejs.req b/nodejs.req deleted file mode 100755 index 129606b..0000000 --- a/nodejs.req +++ /dev/null @@ -1,707 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: utf-8 -*- -# Copyright 2012, 2013 T.C. Hollingsworth -# Copyright 2019 Jan Staněk -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -""" Automatic dependency generator for Node.js libraries. - -Metadata parsed from package.json. See `man npm-json` for details. -""" - -from __future__ import print_function, with_statement - -import json -import operator -import os -import re -import sys -from collections import namedtuple -from itertools import chain -from itertools import takewhile - -# Python version detection -_PY2 = sys.version_info[0] <= 2 -_PY3 = sys.version_info[0] >= 3 - -if _PY2: - from future_builtins import map, filter - - -#: Name format of the requirements -REQUIREMENT_NAME_TEMPLATE = "npm({name})" - -#: ``simple`` product of the NPM semver grammar. -RANGE_SPECIFIER_SIMPLE = re.compile( - r""" - (?P - <= | >= | < | > | = # primitive - | ~ | \^ # tilde/caret operators - )? - \s*(?P\S+)\s* # version specifier - """, - flags=re.VERBOSE, -) - - -class UnsupportedVersionToken(ValueError): - """Version specifier contains token unsupported by the parser.""" - - -class Version(tuple): - """Normalized RPM/NPM version. - - The version has up to 3 components – major, minor, patch. - Any part set to None is treated as unspecified. - - :: - - 1.2.3 == Version(1, 2, 3) - 1.2 == Version(1, 2) - 1 == Version(1) - * == Version() - """ - - __slots__ = () - - #: Version part meaning 'Any' - #: ``xr`` in https://docs.npmjs.com/misc/semver#range-grammar - _PART_ANY = re.compile(r"^[xX*]$") - #: Numeric version part - #: ``nr`` in https://docs.npmjs.com/misc/semver#range-grammar - _PART_NUMERIC = re.compile(r"0|[1-9]\d*") - - def __new__(cls, *args): - """Create new version. - - Arguments: - Version components in the order of "major", "minor", "patch". - All parts are optional:: - - >>> Version(1, 2, 3) - Version(1, 2, 3) - >>> Version(1) - Version(1) - >>> Version() - Version() - - Returns: - New Version. - """ - - if len(args) > 3: - raise ValueError("Version has maximum of 3 components") - return super(Version, cls).__new__(cls, map(int, args)) - - def __repr__(self): - """Pretty debugging format.""" - - return "{0}({1})".format(self.__class__.__name__, ", ".join(map(str, self))) - - def __str__(self): - """RPM version format.""" - - return ".".join(format(part, "d") for part in self) - - @property - def major(self): - """Major version number, if any.""" - return self[0] if len(self) > 0 else None - - @property - def minor(self): - """Major version number, if any.""" - return self[1] if len(self) > 1 else None - - @property - def patch(self): - """Major version number, if any.""" - return self[2] if len(self) > 2 else None - - @property - def empty(self): - """True if the version contains nothing but zeroes.""" - return not any(self) - - @classmethod - def parse(cls, version_string): - """Parse individual version string (like ``1.2.3``) into Version. - - This is the ``partial`` production in the grammar: - https://docs.npmjs.com/misc/semver#range-grammar - - Examples:: - - >>> Version.parse("1.2.3") - Version(1, 2, 3) - >>> Version.parse("v2.x") - Version(2) - >>> Version.parse("") - Version() - - Arguments: - version_string (str): The version_string to parse. - - Returns: - Version: Parsed result. - """ - - # Ignore leading ``v``, if any - version_string = version_string.lstrip("v") - - part_list = version_string.split(".", 2) - # Use only parts up to first "Any" indicator - part_list = list(takewhile(lambda p: not cls._PART_ANY.match(p), part_list)) - - if not part_list: - return cls() - - # Strip off and discard any pre-release or build qualifiers at the end. - # We can get away with this, because there is no sane way to represent - # these kinds of version requirements in RPM, and we generally expect - # the distro will only carry proper releases anyway. - try: - part_list[-1] = cls._PART_NUMERIC.match(part_list[-1]).group() - except AttributeError: # no match - part_list.pop() - - # Extend with ``None``s at the end, if necessary - return cls(*part_list) - - def incremented(self): - """Increment the least significant part of the version:: - - >>> Version(1, 2, 3).incremented() - Version(1, 2, 4) - >>> Version(1, 2).incremented() - Version(1, 3) - >>> Version(1).incremented() - Version(2) - >>> Version().incremented() - Version() - - Returns: - Version: New incremented Version. - """ - - if len(self) == 0: - return self.__class__() - else: - args = self[:-1] + (self[-1] + 1,) - return self.__class__(*args) - - -class VersionBoundary(namedtuple("VersionBoundary", ("version", "operator"))): - """Normalized version range boundary.""" - - __slots__ = () - - #: Ordering of primitive operators. - #: Operators not listed here are handled specially; see __compare below. - #: Convention: Lower boundary < 0, Upper boundary > 0 - _OPERATOR_ORDER = {"<": 2, "<=": 1, ">=": -1, ">": -2} - - def __str__(self): - """Pretty-print the boundary""" - - return "{0.operator}{0.version}".format(self) - - def __compare(self, other, operator): - """Compare two boundaries with provided operator. - - Boundaries compare same as (version, operator_order) tuple. - In case the boundary operator is not listed in _OPERATOR_ORDER, - it's order is treated as 0. - - Arguments: - other (VersionBoundary): The other boundary to compare with. - operator (Callable[[VersionBoundary, VersionBoundary], bool]): - Comparison operator to delegate to. - - Returns: - bool: The result of the operator's comparison. - """ - - ORDER = self._OPERATOR_ORDER - - lhs = self.version, ORDER.get(self.operator, 0) - rhs = other.version, ORDER.get(other.operator, 0) - return operator(lhs, rhs) - - def __eq__(self, other): - return self.__compare(other, operator.eq) - - def __lt__(self, other): - return self.__compare(other, operator.lt) - - def __le__(self, other): - return self.__compare(other, operator.le) - - def __gt__(self, other): - return self.__compare(other, operator.gt) - - def __ge__(self, other): - return self.__compare(other, operator.ge) - - @property - def upper(self): - """True if self is upper boundary.""" - return self._OPERATOR_ORDER.get(self.operator, 0) > 0 - - @property - def lower(self): - """True if self is lower boundary.""" - return self._OPERATOR_ORDER.get(self.operator, 0) < 0 - - @classmethod - def equal(cls, version): - """Normalize single samp:`={version}` into equivalent x-range:: - - >>> empty = VersionBoundary.equal(Version()); tuple(map(str, empty)) - () - >>> patch = VersionBoundary.equal(Version(1, 2, 3)); tuple(map(str, patch)) - ('>=1.2.3', '<1.2.4') - >>> minor = VersionBoundary.equal(Version(1, 2)); tuple(map(str, minor)) - ('>=1.2', '<1.3') - >>> major = VersionBoundary.equal(Version(1)); tuple(map(str, major)) - ('>=1', '<2') - - See `X-Ranges `_ - for details. - - Arguments: - version (Version): The version the x-range should be equal to. - - Returns: - (VersionBoundary, VersionBoundary): - Lower and upper bound of the x-range. - (): Empty tuple in case version is empty (any version matches). - """ - - if version: - return ( - cls(version=version, operator=">="), - cls(version=version.incremented(), operator="<"), - ) - else: - return () - - @classmethod - def tilde(cls, version): - """Normalize :samp:`~{version}` into equivalent range. - - Tilde allows patch-level changes if a minor version is specified. - Allows minor-level changes if not:: - - >>> with_minor = VersionBoundary.tilde(Version(1, 2, 3)); tuple(map(str, with_minor)) - ('>=1.2.3', '<1.3') - >>> no_minor = VersionBoundary.tilde(Version(1)); tuple(map(str, no_minor)) - ('>=1', '<2') - - Arguments: - version (Version): The version to tilde-expand. - - Returns: - (VersionBoundary, VersionBoundary): - The lower and upper boundary of the tilde range. - """ - - # Fail on ``~*`` or similar nonsense specifier - assert version.major is not None, "Nonsense '~*' specifier" - - lower_boundary = cls(version=version, operator=">=") - - if version.minor is None: - upper_boundary = cls(version=Version(version.major + 1), operator="<") - else: - upper_boundary = cls( - version=Version(version.major, version.minor + 1), operator="<" - ) - - return lower_boundary, upper_boundary - - @classmethod - def caret(cls, version): - """Normalize :samp:`^{version}` into equivalent range. - - Caret allows changes that do not modify the left-most non-zero digit - in the ``(major, minor, patch)`` tuple. - In other words, this allows - patch and minor updates for versions 1.0.0 and above, - patch updates for versions 0.X >=0.1.0, - and no updates for versions 0.0.X:: - - >>> major = VersionBoundary.caret(Version(1, 2, 3)); tuple(map(str, major)) - ('>=1.2.3', '<2') - >>> minor = VersionBoundary.caret(Version(0, 2, 3)); tuple(map(str, minor)) - ('>=0.2.3', '<0.3') - >>> patch = VersionBoundary.caret(Version(0, 0, 3)); tuple(map(str, patch)) - ('>=0.0.3', '<0.0.4') - - When parsing caret ranges, a missing patch value desugars to the number 0, - but will allow flexibility within that value, - even if the major and minor versions are both 0:: - - >>> rel = VersionBoundary.caret(Version(1, 2)); tuple(map(str, rel)) - ('>=1.2', '<2') - >>> pre = VersionBoundary.caret(Version(0, 0)); tuple(map(str, pre)) - ('>=0.0', '<0.1') - - A missing minor and patch values will desugar to zero, - but also allow flexibility within those values, - even if the major version is zero:: - - >>> rel = VersionBoundary.caret(Version(1)); tuple(map(str, rel)) - ('>=1', '<2') - >>> pre = VersionBoundary.caret(Version(0)); tuple(map(str, pre)) - ('>=0', '<1') - - Arguments: - version (Version): The version to range-expand. - - Returns: - (VersionBoundary, VersionBoundary): - The lower and upper boundary of caret-range. - """ - - # Fail on ^* or similar nonsense specifier - assert len(version) != 0, "Nonsense '^*' specifier" - - lower_boundary = cls(version=version, operator=">=") - - # Increment left-most non-zero part - for idx, part in enumerate(version): - if part != 0: - upper_version = Version(*(version[:idx] + (part + 1,))) - break - else: # No non-zero found; increment last specified part - upper_version = version.incremented() - - upper_boundary = cls(version=upper_version, operator="<") - - return lower_boundary, upper_boundary - - @classmethod - def hyphen(cls, lower_version, upper_version): - """Construct hyphen range (inclusive set):: - - >>> full = VersionBoundary.hyphen(Version(1, 2, 3), Version(2, 3, 4)); tuple(map(str, full)) - ('>=1.2.3', '<=2.3.4') - - If a partial version is provided as the first version in the inclusive range, - then the missing pieces are treated as zeroes:: - - >>> part = VersionBoundary.hyphen(Version(1, 2), Version(2, 3, 4)); tuple(map(str, part)) - ('>=1.2', '<=2.3.4') - - If a partial version is provided as the second version in the inclusive range, - then all versions that start with the supplied parts of the tuple are accepted, - but nothing that would be greater than the provided tuple parts:: - - >>> part = VersionBoundary.hyphen(Version(1, 2, 3), Version(2, 3)); tuple(map(str, part)) - ('>=1.2.3', '<2.4') - >>> part = VersionBoundary.hyphen(Version(1, 2, 3), Version(2)); tuple(map(str, part)) - ('>=1.2.3', '<3') - - Arguments: - lower_version (Version): Version on the lower range boundary. - upper_version (Version): Version on the upper range boundary. - - Returns: - (VersionBoundary, VersionBoundary): - Lower and upper boundaries of the hyphen range. - """ - - lower_boundary = cls(version=lower_version, operator=">=") - - if len(upper_version) < 3: - upper_boundary = cls(version=upper_version.incremented(), operator="<") - else: - upper_boundary = cls(version=upper_version, operator="<=") - - return lower_boundary, upper_boundary - - -def parse_simple_seq(specifier_string): - """Parse all specifiers from a space-separated string:: - - >>> single = parse_simple_seq(">=1.2.3"); list(map(str, single)) - ['>=1.2.3'] - >>> multi = parse_simple_seq("~1.2.0 <1.2.5"); list(map(str, multi)) - ['>=1.2.0', '<1.3', '<1.2.5'] - - This method implements the ``simple (' ' simple)*`` part of the grammar: - https://docs.npmjs.com/misc/semver#range-grammar. - - Arguments: - specifier_string (str): Space-separated string of simple version specifiers. - - Yields: - VersionBoundary: Parsed boundaries. - """ - - # Per-operator dispatch table - # API: Callable[[Version], Iterable[VersionBoundary]] - handler = { - ">": lambda v: [VersionBoundary(version=v, operator=">")], - ">=": lambda v: [VersionBoundary(version=v, operator=">=")], - "<=": lambda v: [VersionBoundary(version=v, operator="<=")], - "<": lambda v: [VersionBoundary(version=v, operator="<")], - "=": VersionBoundary.equal, - "~": VersionBoundary.tilde, - "^": VersionBoundary.caret, - None: VersionBoundary.equal, - } - - for match in RANGE_SPECIFIER_SIMPLE.finditer(specifier_string): - operator, version_string = match.group("operator", "version") - - for boundary in handler[operator](Version.parse(version_string)): - yield boundary - - -def parse_range(range_string): - """Parse full NPM version range specification:: - - >>> empty = parse_range(""); list(map(str, empty)) - [] - >>> simple = parse_range("^1.0"); list(map(str, simple)) - ['>=1.0', '<2'] - >>> hyphen = parse_range("1.0 - 2.0"); list(map(str, hyphen)) - ['>=1.0', '<2.1'] - - This method implements the ``range`` part of the grammar: - https://docs.npmjs.com/misc/semver#range-grammar. - - Arguments: - range_string (str): The range specification to parse. - - Returns: - Iterable[VersionBoundary]: Parsed boundaries. - - Raises: - UnsupportedVersionToken: ``||`` is present in range_string. - """ - - HYPHEN = " - " - - # FIXME: rpm should be able to process OR in dependencies - # This error reporting kept for backward compatibility - if "||" in range_string: - raise UnsupportedVersionToken(range_string) - - if HYPHEN in range_string: - version_pair = map(Version.parse, range_string.split(HYPHEN, 2)) - return VersionBoundary.hyphen(*version_pair) - - elif range_string != "": - return parse_simple_seq(range_string) - - else: - return [] - - -def unify_range(boundary_iter): - """Calculate largest allowed continuous version range from a set of boundaries:: - - >>> unify_range([]) - () - >>> _ = unify_range(parse_range("=1.2.3 <2")); tuple(map(str, _)) - ('>=1.2.3', '<1.2.4') - >>> _ = unify_range(parse_range("~1.2 <1.2.5")); tuple(map(str, _)) - ('>=1.2', '<1.2.5') - - Arguments: - boundary_iter (Iterable[VersionBoundary]): The version boundaries to unify. - - Returns: - (VersionBoundary, VersionBoundary): - Lower and upper boundary of the unified range. - """ - - # Drop boundaries with empty version - boundary_iter = ( - boundary for boundary in boundary_iter if not boundary.version.empty - ) - - # Split input sequence into upper/lower boundaries - lower_list, upper_list = [], [] - for boundary in boundary_iter: - if boundary.lower: - lower_list.append(boundary) - elif boundary.upper: - upper_list.append(boundary) - else: - msg = "Unsupported boundary for unify_range: {0}".format(boundary) - raise ValueError(msg) - - # Select maximum from lower boundaries and minimum from upper boundaries - intermediate = ( - max(lower_list) if lower_list else None, - min(upper_list) if upper_list else None, - ) - - return tuple(filter(None, intermediate)) - - -def rpm_format(requirement, version_spec="*"): - """Format requirement as RPM boolean dependency:: - - >>> rpm_format("nodejs(engine)") - 'nodejs(engine)' - >>> rpm_format("npm(foo)", ">=1.0.0") - 'npm(foo) >= 1.0.0' - >>> rpm_format("npm(bar)", "~1.2") - '(npm(bar) >= 1.2 with npm(bar) < 1.3)' - - Arguments: - requirement (str): The name of the requirement. - version_spec (str): The NPM version specification for the requirement. - - Returns: - str: Formatted requirement. - """ - - TEMPLATE = "{name} {boundary.operator} {boundary.version!s}" - - try: - boundary_tuple = unify_range(parse_range(version_spec)) - - except UnsupportedVersionToken: - # FIXME: Typos and print behavior kept for backward compatibility - warning_lines = [ - "WARNING: The {requirement} dependency contains an OR (||) dependency: '{version_spec}.", - "Please manually include a versioned dependency in your spec file if necessary", - ] - warning = "\n".join(warning_lines).format( - requirement=requirement, version_spec=version_spec - ) - print(warning, end="", file=sys.stderr) - - return requirement - - formatted = [ - TEMPLATE.format(name=requirement, boundary=boundary) - for boundary in boundary_tuple - ] - - if len(formatted) > 1: - return "({0})".format(" with ".join(formatted)) - elif len(formatted) == 1: - return formatted[0] - else: - return requirement - - -def has_only_bundled_dependencies(module_dir_path): - """Determines if the module contains only bundled dependencies. - - Dependencies are considered un-bundled when they are symlinks - pointing outside the root module's tree. - - Arguments: - module_dir_path (str): - Path to the module directory (directory with ``package.json``). - - Returns: - bool: True if all dependencies are bundled, False otherwise. - """ - - module_root_path = os.path.abspath(module_dir_path) - dependency_root_path = os.path.join(module_root_path, "node_modules") - - try: - dependency_path_iter = ( - os.path.join(dependency_root_path, basename) - for basename in os.listdir(dependency_root_path) - ) - bundled_dependency_iter = ( - os.path.realpath(path) - for path in dependency_path_iter - if not os.path.islink(path) or path.startswith(module_root_path) - ) - - return any(bundled_dependency_iter) - except OSError: # node_modules does not exist - return False - - -def extract_dependencies(metadata_path, optional=False): - """Extract all dependencies in RPM format from package metadata. - - Arguments: - metadata_path (str): Path to package metadata (``package.json``). - optional (bool): - If True, extract ``optionalDependencies`` - instead of ``dependencies``. - - Yields: - RPM-formatted dependencies. - - Raises: - TypeError: Invalid dependency data type. - """ - - if has_only_bundled_dependencies(os.path.dirname(metadata_path)): - return # skip - - # Read metadata - try: - with open(metadata_path, mode="r") as metadata_file: - metadata = json.load(metadata_file) - except OSError: # Invalid metadata file - return # skip - - # Report required NodeJS version with required dependencies - if not optional: - try: - yield rpm_format("nodejs(engine)", metadata["engines"]["node"]) - except KeyError: # NodeJS engine version unspecified - yield rpm_format("nodejs(engine)") - - # Report listed dependencies - kind = "optionalDependencies" if optional else "dependencies" - container = metadata.get(kind, {}) - - if isinstance(container, dict): - for name, version_spec in container.items(): - yield rpm_format(REQUIREMENT_NAME_TEMPLATE.format(name=name), version_spec) - - elif isinstance(container, list): - for name in container: - yield rpm_format(REQUIREMENT_NAME_TEMPLATE.format(name=name)) - - elif isinstance(container, str): - yield rpm_format(REQUIREMENT_NAME_TEMPLATE.format(name=name)) - - else: - raise TypeError("invalid package.json: dependencies not a valid type") - - -if __name__ == "__main__": - nested = ( - extract_dependencies(path.strip(), optional="--optional" in sys.argv) - for path in sys.stdin - ) - flat = chain.from_iterable(nested) - # Ignore parentheses around the requirements when sorting - ordered = sorted(flat, key=lambda s: s.strip("()")) - - print(*ordered, sep="\n") diff --git a/sources b/sources index 6fa90fe..bba5945 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (nodejs-packaging-fedora-23.tar.xz) = 9a49c6a4d59a80d757f4e556b6bcdf771d6a3a037a28b00f31eaefc737c85add130cd7e2281ff0f423ee87bcfa0d8cb34a400f0c5678f9af031911c4d80084c4 +f9913b4b9274d00160300825f045d7fd nodejs-packaging-fedora-23.tar.xz diff --git a/test/bundled/node_modules/test100/package.json b/test/bundled/node_modules/test100/package.json deleted file mode 100644 index 5e1a529..0000000 --- a/test/bundled/node_modules/test100/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "test100", - "version": "1.3.5" -} diff --git a/test/bundled/node_modules/test101/package.json b/test/bundled/node_modules/test101/package.json deleted file mode 100644 index f98ae32..0000000 --- a/test/bundled/node_modules/test101/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "test101", - "version": "2.1.4" -} diff --git a/test/bundled/nodejs.prov.err.exp b/test/bundled/nodejs.prov.err.exp deleted file mode 100644 index e69de29..0000000 diff --git a/test/bundled/nodejs.prov.out.exp b/test/bundled/nodejs.prov.out.exp deleted file mode 100644 index ee0f024..0000000 --- a/test/bundled/nodejs.prov.out.exp +++ /dev/null @@ -1,3 +0,0 @@ -bundled(nodejs-test100) = 1.3.5 -bundled(nodejs-test101) = 2.1.4 -npm(test) = 4.5.6 diff --git a/test/bundled/nodejs.req.err.exp b/test/bundled/nodejs.req.err.exp deleted file mode 100644 index e69de29..0000000 diff --git a/test/bundled/nodejs.req.out.exp b/test/bundled/nodejs.req.out.exp deleted file mode 100644 index 8b13789..0000000 --- a/test/bundled/nodejs.req.out.exp +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/bundled/package.json.in b/test/bundled/package.json.in deleted file mode 100644 index e41f38b..0000000 --- a/test/bundled/package.json.in +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "test", - "version": "4.5.6", - "engines": { - "node": ">=6 <10" - }, - "dependencies": { - "test100": "^1.2.3", - "test101": ">=2.1" - } -} diff --git a/test/bundled_namespace/node_modules/@nmcli/test201/package.json b/test/bundled_namespace/node_modules/@nmcli/test201/package.json deleted file mode 100644 index 4618046..0000000 --- a/test/bundled_namespace/node_modules/@nmcli/test201/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "@nmcli/test201", - "version": "2.1.4" -} diff --git a/test/bundled_namespace/node_modules/test200/package.json b/test/bundled_namespace/node_modules/test200/package.json deleted file mode 100644 index 92ab4ba..0000000 --- a/test/bundled_namespace/node_modules/test200/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "test200", - "version": "1.3.5" -} diff --git a/test/bundled_namespace/nodejs.prov.err.exp b/test/bundled_namespace/nodejs.prov.err.exp deleted file mode 100644 index e69de29..0000000 diff --git a/test/bundled_namespace/nodejs.prov.out.exp b/test/bundled_namespace/nodejs.prov.out.exp deleted file mode 100644 index cf9c17f..0000000 --- a/test/bundled_namespace/nodejs.prov.out.exp +++ /dev/null @@ -1,3 +0,0 @@ -bundled(nodejs-@nmcli/test201) = 2.1.4 -bundled(nodejs-test200) = 1.3.5 -npm(test) = 4.5.6 diff --git a/test/bundled_namespace/nodejs.req.err.exp b/test/bundled_namespace/nodejs.req.err.exp deleted file mode 100644 index e69de29..0000000 diff --git a/test/bundled_namespace/nodejs.req.out.exp b/test/bundled_namespace/nodejs.req.out.exp deleted file mode 100644 index 8b13789..0000000 --- a/test/bundled_namespace/nodejs.req.out.exp +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/bundled_namespace/package.json.in b/test/bundled_namespace/package.json.in deleted file mode 100644 index e41f38b..0000000 --- a/test/bundled_namespace/package.json.in +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "test", - "version": "4.5.6", - "engines": { - "node": ">=6 <10" - }, - "dependencies": { - "test100": "^1.2.3", - "test101": ">=2.1" - } -} diff --git a/test/run b/test/run deleted file mode 100755 index 7897b24..0000000 --- a/test/run +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -ln -sf nodejs.req nodejs_req.py -"$(command -v python2 || echo :)" -m doctest nodejs_req.py || exit 1 -"$(command -v python3 || echo :)" -m doctest nodejs_req.py || exit 1 - -for test in unbundled bundled bundled_namespace -do - sed -e "s|//.*$||" < test/$test/package.json.in > test/$test/package.json - - echo test/$test/package.json | ./nodejs.prov test/$test/package.json > test/$test/nodejs.prov.out 2> test/$test/nodejs.prov.err - diff -uw test/$test/nodejs.prov.err.exp test/$test/nodejs.prov.err || exit 1 - diff -uw test/$test/nodejs.prov.out.exp test/$test/nodejs.prov.out || exit 1 - - echo test/$test/package.json | ./nodejs.req test/$test/package.json > test/$test/nodejs.req.out 2> test/$test/nodejs.req.err - diff -uw test/$test/nodejs.req.err.exp test/$test/nodejs.req.err || exit 1 - diff -uw test/$test/nodejs.req.out.exp test/$test/nodejs.req.out || exit 1 -done diff --git a/test/unbundled/nodejs.prov.err.exp b/test/unbundled/nodejs.prov.err.exp deleted file mode 100644 index e69de29..0000000 diff --git a/test/unbundled/nodejs.prov.out.exp b/test/unbundled/nodejs.prov.out.exp deleted file mode 100644 index 2ea2883..0000000 --- a/test/unbundled/nodejs.prov.out.exp +++ /dev/null @@ -1 +0,0 @@ -npm(test) = 4.5.6 diff --git a/test/unbundled/nodejs.req.err.exp b/test/unbundled/nodejs.req.err.exp deleted file mode 100644 index 83bd277..0000000 --- a/test/unbundled/nodejs.req.err.exp +++ /dev/null @@ -1,2 +0,0 @@ -WARNING: The npm(test900) dependency contains an OR (||) dependency: '^1.2 || ^2.2. -Please manually include a versioned dependency in your spec file if necessary diff --git a/test/unbundled/nodejs.req.out.exp b/test/unbundled/nodejs.req.out.exp deleted file mode 100644 index 08aeab1..0000000 --- a/test/unbundled/nodejs.req.out.exp +++ /dev/null @@ -1,74 +0,0 @@ -(nodejs(engine) >= 6 with nodejs(engine) < 10) -(npm(test100) >= 1 with npm(test100) < 2) -(npm(test101) >= 1 with npm(test101) < 2) -(npm(test102) >= 1 with npm(test102) < 2) -(npm(test103) >= 1 with npm(test103) < 2) -(npm(test104) >= 1.2 with npm(test104) < 1.3) -(npm(test105) >= 1.2 with npm(test105) < 1.3) -(npm(test106) >= 1.2 with npm(test106) < 1.3) -(npm(test107) >= 1.2 with npm(test107) < 1.3) -(npm(test108) >= 1.2.3 with npm(test108) < 1.2.4) -(npm(test109) >= 1.2.3 with npm(test109) < 1.2.4) -(npm(test110) >= 1.2.3 with npm(test110) < 1.2.4) -(npm(test111) >= 1.2.3 with npm(test111) < 1.2.4) -npm(test200) > 1 -npm(test201) > 1.2 -npm(test202) > 1.2.3 -npm(test203) >= 1 -npm(test204) >= 1.2 -npm(test205) >= 1.2.3 -npm(test206) < 2 -npm(test207) < 2.3 -npm(test208) < 2.3.4 -npm(test209) <= 2 -npm(test210) <= 2.3 -npm(test211) <= 2.3.4 -(npm(test300) > 1 with npm(test300) < 2) -(npm(test301) > 1.2 with npm(test301) < 2.3) -(npm(test302) > 1.2.3 with npm(test302) < 2.3.4) -(npm(test303) >= 1 with npm(test303) <= 2) -(npm(test304) >= 1.2 with npm(test304) <= 2.3) -(npm(test305) >= 1.2.3 with npm(test305) <= 2.3.4) -(npm(test306) > 1 with npm(test306) < 2) -(npm(test307) > 1.2 with npm(test307) < 2.3) -(npm(test308) > 1.2.3 with npm(test308) < 2.3.4) -(npm(test309) >= 1 with npm(test309) <= 2) -(npm(test310) >= 1.2 with npm(test310) <= 2.3) -(npm(test311) >= 1.2.3 with npm(test311) <= 2.3.4) -(npm(test400) >= 1.2.3 with npm(test400) <= 2.3.4) -(npm(test401) >= 1.2.3 with npm(test401) < 2.4) -(npm(test402) >= 1.2.3 with npm(test402) < 3) -(npm(test403) >= 1.2 with npm(test403) <= 2.3.4) -(npm(test404) >= 1 with npm(test404) <= 2.3.4) -(npm(test405) >= 1.2 with npm(test405) < 2.4) -(npm(test406) >= 1.2 with npm(test406) < 3) -(npm(test407) >= 1 with npm(test407) < 2.4) -(npm(test408) >= 1 with npm(test408) < 3) -(npm(test500) >= 1.2 with npm(test500) < 1.3) -(npm(test501) >= 1.2 with npm(test501) < 1.3) -(npm(test502) >= 1 with npm(test502) < 2) -(npm(test503) >= 1 with npm(test503) < 2) -npm(test504) -npm(test505) -(npm(test600) >= 1.2.3 with npm(test600) < 1.3) -(npm(test601) >= 1.2 with npm(test601) < 1.3) -(npm(test602) >= 1.2 with npm(test602) < 1.3) -(npm(test603) >= 1 with npm(test603) < 2) -(npm(test604) >= 1 with npm(test604) < 2) -(npm(test700) >= 1.2.3 with npm(test700) < 2) -(npm(test701) >= 0.2.3 with npm(test701) < 0.3) -(npm(test702) >= 0.0.3 with npm(test702) < 0.0.4) -(npm(test703) >= 1.2 with npm(test703) < 2) -(npm(test704) >= 1.2 with npm(test704) < 2) -(npm(test705) >= 0.1 with npm(test705) < 0.2) -(npm(test706) >= 0.1 with npm(test706) < 0.2) -(npm(test707) >= 1 with npm(test707) < 2) -(npm(test708) >= 1 with npm(test708) < 2) -npm(test709) < 0.1 -npm(test710) < 0.1 -npm(test711) < 1 -npm(test712) < 1 -npm(test750) >= 0.10 -(npm(test751) >= 0.10 with npm(test751) <= 6) -(npm(test800) > 1.2 with npm(test800) < 1.9) -npm(test900) diff --git a/test/unbundled/package.json.in b/test/unbundled/package.json.in deleted file mode 100644 index 4d9624e..0000000 --- a/test/unbundled/package.json.in +++ /dev/null @@ -1,108 +0,0 @@ -{ - "name": "test", - "version": "4.5.6", - "engines": { - "node": ">=6 <10" - }, - "dependencies": { - // Single version - "test100": "1", - "test101": "=1", - "test102": "v1", - "test103": "=v1", - "test104": "1.2", - "test105": "=1.2", - "test106": "v1.2", - "test107": "=v1.2", - "test108": "1.2.3", - "test109": "=1.2.3", - "test110": "v1.2.3", - "test111": "=v1.2.3", - - // Ranges with one comparator - "test200": ">1", - "test201": ">1.2", - "test202": ">1.2.3", - "test203": ">=1", - "test204": ">=1.2", - "test205": ">=1.2.3", - "test206": "<2", - "test207": "<2.3", - "test208": "<2.3.4", - "test209": "<=2", - "test210": "<=2.3", - "test211": "<=2.3.4", - - // Ranges with two comparators - "test300": ">1 <2", - "test301": ">1.2 <2.3", - "test302": ">1.2.3 <2.3.4", - "test303": ">=1 <=2", - "test304": ">=1.2 <=2.3", - "test305": ">=1.2.3 <=2.3.4", - "test306": "<2 >1", - "test307": "<2.3 >1.2", - "test308": "<2.3.4 >1.2.3", - "test309": "<=2 >=1", - "test310": "<=2.3 >=1.2", - "test311": "<=2.3.4 >=1.2.3", - - // Hyphen ranges - "test400": "1.2.3 - 2.3.4", - "test401": "1.2.3 - 2.3", - "test402": "1.2.3 - 2", - "test403": "1.2 - 2.3.4", - "test404": "1 - 2.3.4", - "test405": "1.2 - 2.3", - "test406": "1.2 - 2", - "test407": "1 - 2.3", - "test408": "1 - 2", - - // X-Ranges - "test500": "1.2.x", - "test501": "1.2.*", - "test502": "1.x", - "test503": "1.*", - "test504": "*", - "test505": "", - - // Tilde ranges - "test600": "~1.2.3", - "test601": "~1.2.x", - "test602": "~1.2", - "test603": "~1.x", - "test604": "~1", - - // Caret ranges - "test700": "^1.2.3", - "test701": "^0.2.3", - "test702": "^0.0.3", - "test703": "^1.2.x", - "test704": "^1.2", - "test705": "^0.1.x", - "test706": "^0.1", - "test707": "^1.x", - "test708": "^1", - "test709": "^0.0.x", - "test710": "^0.0", - "test711": "^0.x", - "test712": "^0", - - // Space after the operator - // (the grammar does not permit this, but it is accepted in practice) - "test750": ">= 0.10", - "test751": ">= 0.10 <= 6", - - // More than two comparators in a set - // (no reason for this to ever appear, but it is permitted) - "test800": ">1.2 <2.0 <1.9", - - // The following cases are not implemented currently... - - // Multiple comparator sets separated by || - "test900": "^1.2 || ^2.2" - - // The whole pre-release stuff: https://docs.npmjs.com/misc/semver//prerelease-tags - // which is not even enumerated here because it is so complex. - } -}