-
Notifications
You must be signed in to change notification settings - Fork 2
/
nodejs-symlink-deps.rb
executable file
·110 lines (98 loc) · 4.56 KB
/
nodejs-symlink-deps.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/usr/bin/env ruby
# symlink is a two way thing: link modules in this package to the global sitelib;
# or link global modules back here:
# 1. for bundled packaging, the later is needless, because our package contains
# a full dependency cycle. but if you want to link some modules to the global
# sitelib (like `npm link (in package dir)` will do), you can run:
# 'nodejs-symlink-deps -b -m a,b,c'.
# 2. for single packaging, the later is a must. because `npm link <module>` may
# be applied to our package. so it becomes local dependency for another module.
# but remember we don't have any bundled dependencies. so we can't run ourselves.
# symlinking every dependency in package.json will do the trick.
# so for single packaging, just run 'nodejs-symlinks-deps' itself.
require 'json'
require 'fileutils'
require 'node2rpm'
require 'optparse'
require 'ostruct'
buildroot = Node2RPM::System.buildroot
sitelib = Node2RPM::System.sitelib
options = OpenStruct.new
parser = OptionParser.new do |opts|
opts.banner = 'Usage: nodejs-symlink-deps -b -m a,b,c
it will symlink the bundled dependencies in node_modules
to the global sitelib. it is useful if you want this
package to also provide some other modules.
or nodejs-symlink-deps without any parameter will creating
false symlinks (the source may not exist on your system at
all) for every dependency in package.json, from the global
sitelib to your package\'s node_modules.
it is useful for single packaging because package doesn\'t
contain any dependencies itself, and every installed module
has global access in that case. (we don\'t care if it\'s
installed, it\'s the job for nodejs.req) so `npm link <module>`
will work now because dependencies needed are symlinked.'
opts.separator ''
opts.separator 'Specific Options:'
opts.on('-b', '--bundle-mode', 'Specify if this package has bundled dependencies') do
options.bundle = true
end
opts.on('-m <array>', '--modules <array>', Array, 'Specify the modules to be linked to global sitelib') do |mods|
options.mods = mods
end
opts.on('-v <array>', '--versions <array>', Array, 'Specify the versions for the above modules, they have to match') do |vers|
options.vers = vers
end
opts.separator ''
opts.separator 'Common Options:'
opts.on_tail('-h', '--help', 'Show this message') do
puts opts
exit
end
end
parser.parse!(ARGV)
if options.bundle
raise 'you need to provide some modules to symlink!' if options.mods.nil?
Dir.glob(buildroot + sitelib + '/**/package.json').each do |js|
json = JSON.parse(open(js, 'r:UTF-8').read)
next if json['dependencies'].nil? || json['dependencies'].empty?
dedupe = json['dependencies'].keys & options.mods
next if dedupe.empty?
h = Hash[options.mods.zip(options.vers)] unless options.vers.nil?
dedupe.each do |i|
orig_dir = File.join(File.split(js)[0], i)
dest_dir = File.join(buildroot + sitelib, i)
ver = JSON.parse(open(File.join(orig_dir, 'package.json'), 'r:UTF-8').read)['version']
next unless h.nil? || h[i] == ver
if File.symlink?(orig_dir)
Node2RPM.server.new.send :real_symlink, orig_dir, dest_dir
else
FileUtils.ln_sf orig_dir.sub(buildroot, ''), dest_dir
end
end
end
else
# single-mode packaging goes here.
# FIXME: should write a new check in nodejs_check to see if symlink has been run
pkg = Dir.glob(buildroot + sitelib + '/**/package.json').sort { |x| x.size }[0]
path = File.join(File.split(pkg)[0], 'node_modules')
if File.exist?(path)
raise 'node_modules directory already exists!
this indicates this package contains \'bundleDependency\' provided
upstream. the common practice is to remove the node_modules before
running nodejs_symlink_deps. unless you got permission from openSUSE
nodejs team, please DO NOT skip the nodejs_symlink_deps procedure
for single-mode packaging. It\'s dangerous!
'
end
FileUtils.mkdir_p path
json = JSON.parse(open(pkg, 'r:UTF-8').read)
unless json['dependencies'].nil? || json['dependencies'].empty?
# FIXME: should write a post macro to check if the version of the symlinked module
# is the same as the version required here in package.json. because no way to check
# that at build time.
json['dependencies'].keys.each do |k|
FileUtils.ln_sf File.join(sitelib, k), File.join(path, k)
end
end
end