Blame SOURCES/nodejs-symlink-deps

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