Blame SOURCES/nodejs-symlink-deps

3cc9b1
#!/usr/bin/python
3cc9b1
3cc9b1
"""Symlink a node module's dependencies into the node_modules directory so users
3cc9b1
can `npm link` RPM-installed modules into their personal projects."""
3cc9b1
3cc9b1
# Copyright 2012, 2013 T.C. Hollingsworth <tchollingsworth@gmail.com>
3cc9b1
#
3cc9b1
# Permission is hereby granted, free of charge, to any person obtaining a copy
3cc9b1
# of this software and associated documentation files (the "Software"), to
3cc9b1
# deal in the Software without restriction, including without limitation the
3cc9b1
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
3cc9b1
# sell copies of the Software, and to permit persons to whom the Software is
3cc9b1
# furnished to do so, subject to the following conditions:
3cc9b1
#
3cc9b1
# The above copyright notice and this permission notice shall be included in
3cc9b1
# all copies or substantial portions of the Software.
3cc9b1
#
3cc9b1
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3cc9b1
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3cc9b1
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3cc9b1
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3cc9b1
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
3cc9b1
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
3cc9b1
# IN THE SOFTWARE.
3cc9b1
3cc9b1
import json
3cc9b1
import os
3cc9b1
import shutil
3cc9b1
import sys
3cc9b1
3cc9b1
def symlink(source, dest):
3cc9b1
    try:
3cc9b1
        os.symlink(source, dest)
3cc9b1
    except OSError:
3cc9b1
        if os.path.islink(dest) and os.path.realpath(dest) == os.path.normpath(source):
3cc9b1
            sys.stderr.write("""
3cc9b1
WARNING: the symlink for dependency "{0}" already exists
3cc9b1
3cc9b1
This could mean that the dependency exists in both devDependencies and 
3cc9b1
dependencies, which may cause trouble for people using this module with npm.
3cc9b1
3cc9b1
Please report this to upstream. For more information, see:
3cc9b1
    <https://github.com/tchollingsworth/nodejs-packaging/pull/1>
3cc9b1
""".format(dest))
3cc9b1
            
3cc9b1
        elif '--force' in sys.argv:
3cc9b1
            if os.path.isdir(dest):
3cc9b1
                shutil.rmtree(dest)
3cc9b1
            else:
3cc9b1
                os.unlink(dest)
3cc9b1
                
3cc9b1
            os.symlink(source, dest)
3cc9b1
            
3cc9b1
        else:
3cc9b1
            sys.stderr.write("""
3cc9b1
ERROR: the path for dependency "{0}" already exists
3cc9b1
3cc9b1
This could mean that bundled modules are being installed.  Bundled libraries are
3cc9b1
forbidden in Fedora. For more information, see:
3cc9b1
    <https://fedoraproject.org/wiki/Packaging:No_Bundled_Libraries>
3cc9b1
    
3cc9b1
It is generally reccomended to remove the entire "node_modules" directory in
3cc9b1
%prep when it exists. For more information, see:
3cc9b1
    <https://fedoraproject.org/wiki/Packaging:Node.js#Removing_bundled_modules>
3cc9b1
    
3cc9b1
If you have obtained permission from the Fedora Packaging Committee to bundle
3cc9b1
libraries, please use `%nodejs_fixdep -r` in %prep to remove the dependency on
3cc9b1
the bundled module. This will prevent an unnecessary dependency on the system
3cc9b1
version of the module and eliminate this error.
3cc9b1
""".format(dest))
3cc9b1
            sys.exit(1)
3cc9b1
        
3cc9b1
3cc9b1
def symlink_deps(deps, check):
3cc9b1
    if isinstance(deps, dict):
3cc9b1
        #read in the list of mutiple-versioned packages
3cc9b1
        mvpkgs = open('/opt/rh/rh-nodejs8/root/usr/share/node/multiver_modules').read().split('\n')
3cc9b1
            
3cc9b1
        for dep, ver in deps.iteritems():
3cc9b1
            if dep in mvpkgs and ver != '' and ver != '*':
3cc9b1
                depver = ver.lstrip('~').split('.')[0]
3cc9b1
                target = os.path.join(sitelib, '{0}@{1}'.format(dep, depver))
3cc9b1
            else:
3cc9b1
                target = os.path.join(sitelib, dep)
3cc9b1
                
3cc9b1
            if not check or os.path.exists(target):
3cc9b1
                symlink(target, dep)
3cc9b1
                
3cc9b1
    elif isinstance(deps, list):
3cc9b1
        for dep in deps:
3cc9b1
            target = os.path.join(sitelib, dep)
3cc9b1
            if not check or os.path.exists(target):
3cc9b1
                symlink(target, dep)
3cc9b1
    
3cc9b1
    elif isinstance(deps, basestring):
3cc9b1
        target = os.path.join(sitelib, deps)
3cc9b1
        if not check or os.path.exists(target):
3cc9b1
            symlink(target, deps)
3cc9b1
            
3cc9b1
    else:
3cc9b1
        raise TypeError("Invalid package.json: dependencies weren't a recognized type")
3cc9b1
3cc9b1
3cc9b1
#the %nodejs_symlink_deps macro passes %nodejs_sitelib as the first argument
3cc9b1
sitelib = sys.argv[1]
3cc9b1
3cc9b1
if '--check' in sys.argv or '--build' in sys.argv:
3cc9b1
    check = True
3cc9b1
    modules = [os.getcwd()]
3cc9b1
else:
3cc9b1
    check = False
3cc9b1
    br_sitelib = os.path.join(os.environ['RPM_BUILD_ROOT'], sitelib.lstrip('/'))
3cc9b1
    modules = [os.path.join(br_sitelib, module) for module in os.listdir(br_sitelib)]
3cc9b1
3cc9b1
for path in modules:
3cc9b1
    os.chdir(path)
3cc9b1
    md = json.load(open('package.json'))
3cc9b1
    
3cc9b1
    if 'dependencies' in md or (check and 'devDependencies' in md):
3cc9b1
        try:
3cc9b1
            os.mkdir('node_modules')
3cc9b1
        except OSError:
3cc9b1
            sys.stderr.write('WARNING: node_modules already exists. Make sure you have ' +
3cc9b1
                                'no bundled dependencies.\n')
3cc9b1
3cc9b1
        os.chdir('node_modules')
3cc9b1
3cc9b1
        if 'dependencies' in md:
3cc9b1
            symlink_deps(md['dependencies'], check)
3cc9b1
3cc9b1
        if check and '--no-devdeps' not in sys.argv and 'devDependencies' in md:
3cc9b1
            symlink_deps(md['devDependencies'], check)