-
Notifications
You must be signed in to change notification settings - Fork 0
/
rbset_local_bundle.rb
executable file
·112 lines (93 loc) · 2.8 KB
/
rbset_local_bundle.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
111
112
#!/usr/bin/env ruby
require 'bundler'
require 'fileutils'
require 'pp'
def ruby_version
v = Gem::Version.new(File.read(File.join(Dir.pwd, '.ruby-version')).chomp)
"#{v.segments[0]}.#{v.segments[1]}.0"
end
class GemSync
def initialize(dst)
@dst = dst
end
def sync_gems(gem_dirs)
gem_dirs.each do |gem_dir|
gem_dir.dirs.each do |src, dst_stub|
sync_thing(src, dst_stub)
end
end
end
def sync_thing(src, dst_stub)
dst = File.join(@dst, dst_stub)
FileUtils.makedirs dst
# TODO: cp -s ain't on OS X. ln won't recurse, so ... just need to recurse ourselves, creating dirs, and links.
cmd = "rsync -a #{src} #{dst}"
puts cmd
system cmd
end
end
class GitSourceGemDirs
def initialize(root, name)
@root = root
@name = name
end
def dirs
[
[File.join(@root, 'bundler', 'gems', "#{@name}-*"), File.join('bundler', 'gems')],
[File.join(@root, 'cache', 'bundler', 'git', "#{@name}-*"), File.join('cache', 'bundler', 'git')]
]
end
end
class GemDirs
def initialize(root, name, version)
@root = root
@name = name
@version = version
end
def dirs
return [] if gem_filename.empty?
[
[File.join(@root, 'cache', "#{gem_filename}.gem"), File.join('cache')],
extensions_entry,
[File.join(@root, 'gems', "#{gem_filename}", '*'), File.join('gems', "#{gem_filename}")],
[File.join(@root, 'specifications', "#{gem_filename}.gemspec"), File.join('specifications')]
].compact
end
def extensions_entry
hit = Dir[File.join(@root, 'extensions', '**', "#{gem_version}")].first.to_s
unless hit.empty?
[File.join(hit, '*'), hit.sub("#{@root}/", '')]
end
end
def gem_version
"#{@name}-#{@version.to_s}"
end
def gem_filename
@gem_filename ||= begin
# dunno if can do optional characters in glob. so ... two globs
glob_generic = File.join(@root, 'cache', "#{gem_version}.gem")
# looking for native gems with platform in the name
glob_platform = File.join(@root, 'cache', "#{gem_version}-*.gem")
File.basename((Dir[glob_generic] + Dir[glob_platform]).first.to_s.sub(/\.gem\z/, ''))
end
end
end
system 'bundle config --local path .bundle'
system 'bundle config --local disable_shared_gems true'
lockfile = File.join(Dir.pwd, 'Gemfile.lock')
puts "Parsing #{lockfile}..."
parser = Bundler::LockfileParser.new(Bundler.read_file(lockfile))
# pp parser.specs.detect { |s| s.name =~ /lib/ }; exit
@root = File.expand_path("~/.bundle/ruby/#{ruby_version}")
@dst = File.join(Dir.pwd, '.bundle', 'ruby', ruby_version)
FileUtils.makedirs @dst
sync = GemSync.new(@dst)
sync.sync_gems(
parser.specs.map do |s|
if s.source.is_a?(Bundler::Source::Git)
GitSourceGemDirs.new(@root, s.name)
else
GemDirs.new(@root, s.name, s.version)
end
end
)