From fb565e93cc5cf3952be527ede4ef0a09b3024a07 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 13 2018 08:02:52 +0000 Subject: import rh-nodejs10-3.2-2.el7 --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/.gitignore diff --git a/.rh-nodejs10.metadata b/.rh-nodejs10.metadata new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/.rh-nodejs10.metadata diff --git a/README.md b/README.md deleted file mode 100644 index 98f42b4..0000000 --- a/README.md +++ /dev/null @@ -1,4 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/LICENSE b/SOURCES/LICENSE new file mode 100644 index 0000000..d27a669 --- /dev/null +++ b/SOURCES/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013-2018 by Red Hat inc. + +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/SOURCES/README b/SOURCES/README new file mode 100644 index 0000000..746aae9 --- /dev/null +++ b/SOURCES/README @@ -0,0 +1,38 @@ +Package %{scl_name} provides Node.js platform delivered as a Software +Collection. For more information about Software Collections, +see the scl(1) man page. By installing the %{scl_name} collection, +you will get the minimum working set of packages to have a working Node.js platform. + +Usage: scl enable %{scl} 'node' + +Software Collections allow you to build and execute applications +which are not located in the filesystem root hierarchy, +but are stored in an alternative location, which is %{_scl_root} +in case of the %{scl_name} collection. + +Node.js is a platform built on Chrome's JavaScript runtime +for easily building fast, scalable network applications. +Node.js uses an event-driven, non-blocking I/O model that +makes it lightweight and efficient, perfect for data-intensive +real-time applications that run across distributed devices. + +When you want to work with the %{scl_name} collection, use the scl +utility (see the scl(1) man page for usage) to enable the scl +environment. + +Examples: +scl enable %{scl_name} 'command --arg' + Run a specific command with the argument --arg within the %{scl_name} + software collections environment. + +scl enable %{scl_name} 'node' + Run node from the %{scl_name} software collection. + +scl enable %{scl_name} bash + Run an interactive shell with the %{scl_name} software collection enabled. + +scl enable %{scl_name} 'man node' + Show man pages for the node command, which is a part of the + %{scl_name} software collection. + +Report bugs to . diff --git a/SOURCES/macros.nodejs b/SOURCES/macros.nodejs new file mode 100644 index 0000000..bf29c5d --- /dev/null +++ b/SOURCES/macros.nodejs @@ -0,0 +1,38 @@ +# 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}/rh-nodejs10-fixdep + +# patch package.json to set the package version +# e.g. `%%nodejs_setversion 1.2.3` +# %nodejs_setversion %{_rpmconfigdir}/rh-nodejs10-setversion +%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/SOURCES/multiver_modules b/SOURCES/multiver_modules new file mode 100644 index 0000000..2dc44eb --- /dev/null +++ b/SOURCES/multiver_modules @@ -0,0 +1,3 @@ +uglify-js +inherits +nan \ No newline at end of file diff --git a/SOURCES/nodejs-fixdep b/SOURCES/nodejs-fixdep new file mode 100755 index 0000000..b425435 --- /dev/null +++ b/SOURCES/nodejs-fixdep @@ -0,0 +1,117 @@ +#!/usr/bin/python + +"""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/SOURCES/nodejs-setversion b/SOURCES/nodejs-setversion new file mode 100755 index 0000000..b266603 --- /dev/null +++ b/SOURCES/nodejs-setversion @@ -0,0 +1,43 @@ +#!/usr/bin/python + +"""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/SOURCES/nodejs-symlink-deps b/SOURCES/nodejs-symlink-deps new file mode 100755 index 0000000..664e405 --- /dev/null +++ b/SOURCES/nodejs-symlink-deps @@ -0,0 +1,140 @@ +#!/usr/bin/python + +"""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 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('/opt/rh/rh-nodejs10/root/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 = ver.lstrip('~^').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/SOURCES/nodejs.attr b/SOURCES/nodejs.attr new file mode 100644 index 0000000..a04c30e --- /dev/null +++ b/SOURCES/nodejs.attr @@ -0,0 +1,3 @@ +%__nodejs10_provides %{_rpmconfigdir}/nodejs10.prov +%__nodejs10_requires %{_rpmconfigdir}/nodejs10.req +%__nodejs10_path ^/usr/lib(64)?/node_modules/[^/]+/package\\.json$ diff --git a/SOURCES/nodejs.prov b/SOURCES/nodejs.prov new file mode 100755 index 0000000..5fe4498 --- /dev/null +++ b/SOURCES/nodejs.prov @@ -0,0 +1,98 @@ +#!/usr/bin/python + +""" +Automatic provides generator for Node.js libraries. + +Taken from package.json. See `man npm-json` for details. +""" +# Copyright 2012 T.C. Hollingsworth +# Copyright 2017 Tomas Tomecek +# +# 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. + +from __future__ import print_function + +import os +import sys +import json + +provides = set() + +def handle_package_json(path, bundled=False): + """ + process package.json file available on path, print RPM dependency based on name and version + """ + if not path.endswith('package.json') or not os.path.isfile(path): + return + fh = open(path) + metadata = json.load(fh) + fh.close() + + try: + if metadata['private']: + return + except KeyError: + pass + + try: + name = metadata["name"] + except KeyError: + return + try: + version = metadata["version"] + except KeyError: + return + + if bundled: + value = "bundled(nodejs-%s) = %s" % (name, version) + else: + value = "rh-nodejs10-npm(%s) = %s" % (name, version) + provides.add(value) + + +def handle_module(path, bundled): + """ + process npm module and all its bundled dependencies + """ + handle_package_json(path, bundled=bundled) + if not os.path.isdir(path): + path = os.path.dirname(path) + node_modules_dir_candidate = os.path.join(path, "node_modules") + if os.path.isdir(node_modules_dir_candidate): + for module_path in os.listdir(node_modules_dir_candidate): + module_abs_path = os.path.join(node_modules_dir_candidate, module_path) + # skip modules which are linked against system module + if not os.path.islink(module_abs_path): + p_json_file = os.path.join(module_abs_path, "package.json") + handle_module(p_json_file, bundled=True) + + +def main(): + """ read list of package.json paths from stdin """ + paths = [path.rstrip() for path in sys.stdin.readlines()] + + for path in paths: + handle_module(path, bundled=False) + + for provide in sorted(provides): + print(provide) + + +if __name__ == '__main__': + main() diff --git a/SOURCES/nodejs.req b/SOURCES/nodejs.req new file mode 100755 index 0000000..acd96d8 --- /dev/null +++ b/SOURCES/nodejs.req @@ -0,0 +1,295 @@ +#!/usr/bin/python + +""" +Automatic dependency generator for Node.js libraries. + +Parsed from package.json. See `man npm-json` for details. +""" + +# 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. + +from __future__ import unicode_literals, print_function +import json +import os +import re +import sys + +def has_all_bundled(path): + # remove 'package.json' + path = os.path.dirname(path) + node_modules_dir_candidate = os.path.join(path, "node_modules") + if os.path.isdir(node_modules_dir_candidate): + modules_abs_path = map(lambda x: os.path.join(node_modules_dir_candidate, x), + os.listdir(node_modules_dir_candidate)) + any_link = any([os.path.islink(x) for x in modules_abs_path]) + return not any_link + + +def main(): + #npm2rpm uses functions here to write BuildRequires so don't print anything + #until the very end + deps = [] + + #it's highly unlikely that we'll ever get more than one file but we handle + #this like all RPM automatic dependency generation scripts anyway + paths = [path.rstrip() for path in sys.stdin.readlines()] + + for path in paths: + if not path.endswith('package.json'): + continue + + if has_all_bundled(path): + continue + + fh = open(path) + metadata = json.load(fh) + fh.close() + + if '--optional' in sys.argv: + deptype = 'optionalDependencies' + else: + deptype = 'dependencies' + + if deptype == 'dependencies': + #write out the node.js interpreter dependency + req = 'rh-nodejs10-nodejs(engine)' + + if 'engines' in metadata and isinstance(metadata['engines'], dict) \ + and 'node' in metadata['engines']: + deps.append(process_dep(req, metadata['engines']['node'])) + else: + deps.append(req) + + if deptype in metadata: + if isinstance(metadata[deptype], dict): + for name, version in metadata[deptype].items(): + req = 'rh-nodejs10-npm(' + name + ')' + deps.append(process_dep(req, version)) + elif isinstance(metadata[deptype], list): + for name in metadata[deptype]: + req = 'rh-nodejs10-npm(' + name + ')' + deps.append(req) + elif isinstance(metadata[deptype], str): + req = 'rh-nodejs10-npm(' + metadata[deptype] + ')' + deps.append(req) + else: + raise TypeError('invalid package.json: dependencies not a valid type') + + print('\n'.join(deps)) + +def process_dep(req, version): + """Converts an individual npm dependency into RPM dependencies""" + + #there's no way RPM can do anything like an OR dependency + if '||' in version: + sys.stderr.write("WARNING: The {0} dependency contains an ".format(req) + + "OR (||) dependency: '{0}.\nPlease manually include ".format(version) + + "a versioned dependency in your spec file if necessary") + return req + + if ' - ' in version: + version = expand_hyphen_range(version) + + deps = convert_dep(req, version) + + if len(deps) > 1: + dep = "(" + " with ".join(deps) + ")" + else: + dep = deps[0] + + return dep + +def parse_version(v): + """ + Parse an individual version number like 1.2.3 into a tuple. + '1.2.3' -> (1, 2, 3) + '1.2' -> (1, 2) + '1' -> (1,) + '*' -> () + This is the "partial" production in the grammar: + https://docs.npmjs.com/misc/semver#range-grammar + """ + # Ignore leading 'v' + v = v.lstrip('v') + parts = v.split('.', 3) + if parts[0] in ['', 'x', 'X', '*']: + return () + if len(parts) < 2 or parts[1] in ['', 'x', 'X', '*']: + return (int(parts[0]),) + if len(parts) < 3 or parts[2] in ['', 'x', 'X', '*']: + return (int(parts[0]), int(parts[1])) + # 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. + return (int(parts[0]), + int(parts[1]), + int(''.join(c for c in parts[2] if c.isdigit()))) + +def incremented(v): + """ + Returns the given version tuple with the last part incremented. + (1, 2, 3) -> (1, 2, 4) + (1, 2) -> (1, 3) + (1,) -> (2,) + () -> () + """ + if len(v) == 3: + return (v[0], v[1], v[2] + 1) + if len(v) == 2: + return (v[0], v[1] + 1) + if len(v) == 1: + return (v[0] + 1,) + if len(v) == 0: + return () + +def expand_hyphen_range(version): + """ + Converts a hyphen range into its equivalent comparator set. + '1.2.3 - 2.3.4' -> '>=1.2.3 <=2.3.4' + + https://docs.npmjs.com/misc/semver#hyphen-ranges-xyz---abc + """ + lower, upper = version.split(' - ', 1) + upper_parts = parse_version(upper) + if len(upper_parts) == 3: + return '>={} <={}'.format(lower, upper) + # Special behaviour if the upper bound is partial: + if len(upper_parts) == 2: + return '>={} <{}.{}'.format(lower, upper_parts[0], upper_parts[1] + 1) + if len(upper_parts) == 1: + return '>={} <{}'.format(lower, upper_parts[0] + 1) + if len(upper_parts) == 0: + return '>={}'.format(lower) + +def convert_dep(req, version): + """ + Converts an NPM requirement to an equivalent list of RPM requirements. + """ + # The version is a space-separated set of one or more comparators. + # There can be any number of comparators (even more than two) using all the + # various shortcut operators, but ultimately the comparator set is + # equivalent to a continuous range of version numbers, with an upper and + # lower bound (possibly inclusive or exclusive at each end). + + # Start by defining the range as infinite. + lower_bound = () + lower_bound_inclusive = True + upper_bound = () + upper_bound_inclusive = False + + # Helper function to narrow the lower bound to the given version, if it's + # *higher* than what we have now. + def narrow_lower(parts, inclusive): + nonlocal lower_bound, lower_bound_inclusive + if parts > lower_bound: + lower_bound = parts + lower_bound_inclusive = inclusive + elif parts == lower_bound: + if not inclusive and lower_bound_inclusive: + lower_bound_inclusive = False + # Same for the upper bound. + def narrow_upper(parts, inclusive): + nonlocal upper_bound, upper_bound_inclusive + if parts == (): + return + if upper_bound == () or parts < upper_bound: + upper_bound = parts + upper_bound_inclusive = inclusive + elif parts == upper_bound: + if not inclusive and upper_bound_inclusive: + upper_bound_inclusive = False + + # For each comparator in the set, narrow the range to match it, + # using the two helper functions. + for operator, v in re.findall(r'(<=|>=|<|>|=|\^|~)?\s*(\S+)\s*', version): + if not operator: + operator = '=' + parts = parse_version(v) + + if operator == '>': + narrow_lower(parts, False) + + elif operator == '>=': + narrow_lower(parts, True) + + elif operator == '<': + narrow_upper(parts, False) + + elif operator == '<=': + narrow_upper(parts, True) + + elif operator == '=': + narrow_lower(parts, True) + narrow_upper(incremented(parts), False) + + elif operator == '~': + narrow_lower(parts, True) + if len(parts) == 0: + pass + elif len(parts) == 1: + narrow_upper((parts[0] + 1,), False) + else: + narrow_upper((parts[0], parts[1] + 1), False) + + elif operator == '^': + narrow_lower(parts, True) + if len(parts) == 0: + pass + elif len(parts) == 1: + narrow_upper((parts[0] + 1,), False) + elif len(parts) == 2: + if parts[0] == 0: + narrow_upper((0, parts[1] + 1), False) + else: + narrow_upper((parts[0] + 1,), False) + elif len(parts) == 3: + if parts[0] == 0 and parts[1] == 0: + narrow_upper((0, 0, parts[2] + 1), False) + elif parts[0] == 0: + narrow_upper((0, parts[1] + 1), False) + else: + narrow_upper((parts[0] + 1,), False) + + # At the end, we have an upper and lower bound which satisfies all the + # comparators in the set. This is what will become our RPM version + # requirements. + + # Special case: no effective bounds. + if not lower_bound and not upper_bound: + return [req] + + # Otherwise, produce RPM requirements for the upper and lower bounds. + deps = [] + if lower_bound not in [(), (0,), (0, 0), (0, 0, 0)]: + deps.append('{} {} {}'.format( + req, + '>=' if lower_bound_inclusive else '>', + '.'.join(str(part) for part in lower_bound))) + if upper_bound != (): + deps.append('{} {} {}'.format( + req, + '<=' if upper_bound_inclusive else '<', + '.'.join(str(part) for part in upper_bound))) + return deps + +if __name__ == '__main__': + main() diff --git a/SOURCES/nodejs_native.attr b/SOURCES/nodejs_native.attr new file mode 100644 index 0000000..0527af6 --- /dev/null +++ b/SOURCES/nodejs_native.attr @@ -0,0 +1,2 @@ +%__nodejs_native_requires %{_rpmconfigdir}/nodejs_native.req +%__nodejs_native_path ^/usr/lib.*/node_modules/.*\\.node$ diff --git a/SPECS/rh-nodejs10.spec b/SPECS/rh-nodejs10.spec new file mode 100644 index 0000000..ae1e8dc --- /dev/null +++ b/SPECS/rh-nodejs10.spec @@ -0,0 +1,340 @@ +%global scl_name_prefix rh- +%global scl_name_base nodejs +%global scl_name_version 10 + +%global scl %{scl_name_prefix}%{scl_name_base}%{scl_name_version} + +%scl_package %scl +%global install_scl 1 + +# do not produce empty debuginfo package +%global debug_package %{nil} + +Summary: %scl Software Collection +Name: %scl_name +Version: 3.2 +Release: 2%{?dist} + +Source1: macros.nodejs +Source2: nodejs.attr +Source3: nodejs.prov +Source4: nodejs.req +Source5: nodejs-symlink-deps +Source6: nodejs-fixdep +Source7: nodejs_native.attr +Source8: README +Source9: LICENSE +Source10: multiver_modules +Source11: nodejs-setversion + +License: MIT + +%if 0%{?install_scl} +Requires: %{scl_prefix}nodejs +Requires: %{scl_prefix}npm +Requires: %{scl_prefix}runtime +%endif + +BuildRequires: scl-utils-build +BuildRequires: python-devel +BuildRequires: help2man + +%description +This is the main package for %scl Software Collection. + +%package runtime +Summary: Package that handles %scl Software Collection. +Requires: %{_root_bindir}/scl_source + +%description runtime +Package shipping essential scripts to work with %scl Software Collection. + +%package build +Summary: Package shipping basic build configuration +Requires: scl-utils-build + +%description build +Package shipping essential configuration macros to build %scl Software Collection. + +%package scldevel +Summary: Package shipping development files for %scl + +%description scldevel +Package shipping development files, especially usefull for development of +packages depending on %scl Software Collection. + +%prep +%setup -c -T + +# This section generates README file from a template and creates man page +# from that file, expanding RPM macros in the template file. +cat >README <<'EOF' +%{expand:%(cat %{SOURCE8})} +EOF + +# copy the license file so %%files section sees it +cp %{SOURCE9} . + +%build +# generate a helper script that will be used by help2man +cat >h2m_helper <<'EOF' +#!/bin/bash +[ "$1" == "--version" ] && echo "%{scl_name} %{version} Software Collection" || cat README +EOF + +chmod a+x h2m_helper + +# generate the man page +help2man -N --section 7 ./h2m_helper -o %{scl_name}.7 + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}%{_scl_scripts}/root +cat >> %{buildroot}%{_scl_scripts}/enable << EOF +export PATH=%{_bindir}\${PATH:+:\${PATH}} +export LD_LIBRARY_PATH=%{_libdir}\${LD_LIBRARY_PATH:+:\${LD_LIBRARY_PATH}} +export PYTHONPATH=%{_scl_root}%{python_sitelib}\${PYTHONPATH:+:\${PYTHONPATH}} +export MANPATH=%{_mandir}:\$MANPATH +#. scl_source enable v8314 +# new nodejs bundles v8 +EOF + +# install rpm magic +install -Dpm0644 %{SOURCE1} %{buildroot}%{_root_sysconfdir}/rpm/macros.%{name} +install -Dpm0644 %{SOURCE2} %{buildroot}%{_rpmconfigdir}/fileattrs/%{name}.attr +install -pm0755 %{SOURCE3} %{buildroot}%{_rpmconfigdir}/%{name}.prov +install -pm0755 %{SOURCE4} %{buildroot}%{_rpmconfigdir}/%{name}.req +install -pm0755 %{SOURCE5} %{buildroot}%{_rpmconfigdir}/%{name}-symlink-deps +install -pm0755 %{SOURCE6} %{buildroot}%{_rpmconfigdir}/%{name}-fixdep +install -Dpm0644 %{SOURCE7} %{buildroot}%{_rpmconfigdir}/fileattrs/%{name}_native.attr +install -Dpm0644 %{SOURCE10} %{buildroot}%{_datadir}/node/multiver_modules +install -pm0755 %{SOURCE11} %{buildroot}%{_rpmconfigdir}/%{name}-symlink-deps + +cat >> %{buildroot}%{_root_sysconfdir}/rpm/macros.%{scl_name_base}-scldevel << EOF +%%scl_%{scl_name_base} %{scl} +%%scl_prefix_%{scl_name_base} %{scl_prefix} +EOF + +# ensure Requires are added to every native module that match the Provides from +# the nodejs build in the buildroot +cat << EOF > %{buildroot}%{_rpmconfigdir}/%{name}_native.req +#!/bin/sh +echo 'nodejs10-nodejs(abi) = %nodejs_abi' +echo 'nodejs10-nodejs(v8-abi) = %v8_abi' +EOF +chmod 0755 %{buildroot}%{_rpmconfigdir}/%{name}_native.req + +cat << EOF > %{buildroot}%{_rpmconfigdir}/%{name}-require.sh +#!/bin/sh +%{_rpmconfigdir}/%{name}.req $* +%{_rpmconfigdir}/find-requires $* +EOF +chmod 0755 %{buildroot}%{_rpmconfigdir}/%{name}-require.sh + +cat << EOF > %{buildroot}%{_rpmconfigdir}/%{name}-provide.sh +#!/bin/sh +%{_rpmconfigdir}/%{name}.prov $* +%{_rpmconfigdir}/find-provides $* +EOF +chmod 0755 %{buildroot}%{_rpmconfigdir}/%{name}-provide.sh + +%scl_install +# scl doesn't include this directory +mkdir -p %{buildroot}%{_scl_root}%{python_sitelib} +mkdir -p %{buildroot}%{_libdir}/pkgconfig + +# install generated man page +mkdir -p %{buildroot}%{_mandir}/man7/ +install -m 644 %{scl_name}.7 %{buildroot}%{_mandir}/man7/%{scl_name}.7 + +# own license dir (RHBZ#1420294) +mkdir -p %{buildroot}%{_datadir}/licenses/ + + +%files + +%files -f filesystem runtime +%doc README +%{!?_licensedir:%global license %%doc} +%license LICENSE +%scl_files +#%%dir %%{_scl_root}%%{python_sitelib} +%dir %{_prefix}/lib/python2.* +%dir %{_libdir}/pkgconfig +%dir %{_datadir}/licenses +%{_datadir}/node/multiver_modules +%{_mandir}/man7/%{scl_name}.* +%dir %{_datadir}/node + +%files build +%{_root_sysconfdir}/rpm/macros.%{scl}-config +%{_root_sysconfdir}/rpm/macros.%{name} +%{_rpmconfigdir}/fileattrs/%{name}*.attr +%{_rpmconfigdir}/%{name}* + +%files scldevel +%{_root_sysconfdir}/rpm/macros.%{scl_name_base}-scldevel + +%changelog +* Thu Sep 20 2018 Zuzana Svetlikova - 3.2-2 +- Resolves: RHBZ#1584252 +- update to fedora packaging, generate bundled provides automaticaly + +* Thu Jul 19 2018 Zuzana Svetlikova - 3.2-1 +- Update to v10 + +* Thu Jul 13 2017 Zuzana Svetlikova - 3.0-4 +- Use macro for python sitelib in doc + +* Mon Jul 03 2017 Zuzana Svetlikova - 3.0-3 +- Fix typo in symlink script + +* Tue Jun 27 2017 Zuzana Svetlikova - 3.0-2 +- Enable installing the collection + +* Mon Jun 19 2017 Zuzana Svetlikova - 3.0-1 +- SCL 3.0, nodejs v8.x + +* Thu Feb 16 2017 Zuzana Svetlikova - 2.4-5 +- Own %%{_licensedir} ((RHBZ#1420294)) + +* Fri Jan 27 2017 Zuzana Svetlikova - 2.4-4 +- Enable installing main package set + +* Wed Jan 11 2017 Zuzana Svetlikova - 2.4-2 +- RHSCL 2.4 +- Update macros +- Use zvetlik/rh-nodejs6 as base for rh-nodejs6, change sclo- for rh- + +* Wed Jan 11 2017 Zuzana Svetlikova - 2.4-1 +- Use zvetlik/rh-nodejs6 as base for rh-nodejs6 + +* Mon Sep 05 2016 Zuzana Svetlikova - 2.3-2 +- Use sclo- prefix + +* Tue Aug 30 2016 Zuzana Svetlikova - 2.3-1 +- New meta-package for Nodejs v6 + +* Thu Mar 03 2016 Zuzana Svetlikova - 2.2-5 +- Enable installing whole scl (RBZ#1314093) + +* Fri Feb 12 2016 Zuzana Svetlikova - 2.2-4 +- Add prefixes to provides and requires + +* Wed Feb 10 2016 Tomas Hrcka - 2.2-3 +- Add missing rh- prefix + +* Wed Feb 03 2016 Zuzana Svetlikova - 2.2-1 +- RHSCL 2.2 +- add %%license tag to %%files + +* Thu Jan 14 2016 Tomas Hrcka - 2.1-5 +- Include nodemon in collection +- Update packaging scripts and macros + +* Fri Oct 02 2015 Zuzana Svetlikova - 2.1-3 +- Enable installing of whole collection + +* Thu Jul 02 2015 Tomas Hrcka - 2.1-2 +- RHSCL 2.1 release +- disable installing of whole collection this will be enabled after devel period + +* Thu May 14 2015 Tomas Hrcka - 2.0-3 +- Red Hat Software collections 2.0 +- Own python modules directory + +* Wed Oct 08 2014 Tomas Hrcka - 1.2-29 +- Require scriptlet scl_devel from root_bindir not scl_bindir + +* Mon Oct 06 2014 Tomas Hrcka - 1.2-28 +- bump scl version + +* Mon Oct 06 2014 Tomas Hrcka - 1.2-27 +- Require scriptlet scl_devel instead of specific scl-utils version + +* Mon Sep 08 2014 Tomas Hrcka - 1.2-26 +- Fix version of scl-utils required by this package +- Bump version + +* Mon Mar 31 2014 Honza Horak - 1.1-25 +- Fix path typo in README + Related: #1061452 + +* Mon Feb 17 2014 Tomas Hrcka - 1.1-24 +- Require version of scl-utils + +* Wed Feb 12 2014 Tomas Hrcka - 1.1-23 +- Define scl_name_base and scl_name_version macros + +* Wed Feb 12 2014 Honza Horak - 1.1-22 +- Some more grammar fixes in README + Related: #1061452 + +* Tue Jan 21 2014 Tomas Hrcka - 1-21 +- Rebuilt for rhbz#1054252 + +* Thu Dec 05 2013 Tomas Hrcka - 1-20 +- install collection packages as dependencies + +* Wed Nov 27 2013 Tomas Hrcka - 1-19 +- rebuilt +- fiw v8314 dependency + +* Wed Nov 20 2013 Tomas Hrcka - 1-18 +- added dependency on v8314 scl + +* Thu Aug 15 2013 thrcka@redhat.com - 1-17 +- clean up after previous fix + +* Fri Aug 09 2013 thrcka@redhat.com - 1-16 +- RHBZ#993425 - nodejs010.req fails when !noarch + +* Mon Jun 03 2013 thrcka@redhat.com - 1-15 +- Changed licence to MIT + +* Thu May 23 2013 Tomas Hrcka - 1-14.1 +- fixed typo in MANPATH + +* Thu May 23 2013 Tomas Hrcka - 1-14 +- Changed MAN_PATH so it does not ignore man pages from host system + +* Thu May 9 2013 Stanislav Ochotnicky - 1-13 +- Remove colons forgotten in scriplets + +* Tue May 07 2013 Stanislav Ochotnicky - 1-12 +- Add runtime dependency on scl-runtime + +* Mon May 06 2013 Stanislav Ochotnicky - 1-11 +- Add pkgconfig file ownership + +* Mon May 06 2013 Stanislav Ochotnicky - 1-10 +- Workaround scl-utils not generating all directory ownerships (#956213) + +* Mon May 06 2013 Stanislav Ochotnicky - 1-9 +- Fix enable scriptlet evironment expansion (#956788) + +* Wed Apr 17 2013 Stanislav Ochotnicky - 1-8 +- Extend MANPATH env variable +- Add npm to meta package requires + +* Mon Apr 15 2013 Stanislav Ochotnicky - 1-7 +- Update macros and requires/provides generator to latest + +* Wed Apr 10 2013 Stanislav Ochotnicky - 1-6 +- Fix rpm requires/provides generator paths +- Add requires to main meta package + +* Mon Apr 08 2013 Stanislav Ochotnicky - 1-5 +- Make package architecture specific for libdir usage + +* Mon Apr 08 2013 Stanislav Ochotnicky - 1-4 +- Add rpm macros and tooling + +* Mon Apr 08 2013 Stanislav Ochotnicky - 1-3 +- Add proper scl-utils-build requires + +* Fri Apr 05 2013 Stanislav Ochotnicky - 1-2 +- Add PYTHONPATH to configuration + +* Tue Mar 26 2013 Stanislav Ochotnicky - 1-1 +- Initial version of the Node.js Software Collection