prebundler 0.0.4 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/lib/prebundler/cli/install.rb +69 -11
- data/lib/prebundler/gem_ref.rb +25 -11
- data/lib/prebundler/gemfile.rb +14 -0
- data/lib/prebundler/gemfile_interpreter.rb +12 -9
- data/lib/prebundler/git_gem_ref.rb +18 -9
- data/lib/prebundler/path_gem_ref.rb +19 -1
- data/lib/prebundler/version.rb +1 -1
- data/prebundler.gemspec +1 -2
- metadata +2 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8f3573257ed6d3ae187bd8cc9b3e37ce6787373
|
4
|
+
data.tar.gz: 7780812efb908e7e533e1e7a3299b529f281bda5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51e0f4e6e61305cd9535de52ca2bd3366694f63b99a0ea43d20ac084571815be95683a035698983ea0aa7eaeb4f14bf903f97aecb7b32988df1d4d296ba0834d
|
7
|
+
data.tar.gz: b1890c8532ddce82b3da898d5aae18d1c5da929b328fd460df090949310d5c70ec2d3cd3f7c98bdb1b2315fd44875e60b4594e2f91de7a87c115bb94683edbab
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'securerandom'
|
2
2
|
require 'tmpdir'
|
3
3
|
require 'parallel'
|
4
|
-
require '
|
4
|
+
require 'fileutils'
|
5
|
+
require 'yaml'
|
5
6
|
|
6
7
|
module Prebundler
|
7
8
|
module Cli
|
@@ -9,15 +10,34 @@ module Prebundler
|
|
9
10
|
def run
|
10
11
|
prepare
|
11
12
|
install
|
13
|
+
update_bundle_config
|
14
|
+
generate_binstubs
|
12
15
|
check
|
13
16
|
end
|
14
17
|
|
15
18
|
private
|
16
19
|
|
17
20
|
def prepare
|
18
|
-
|
21
|
+
FileUtils.mkdir_p(bundle_path)
|
22
|
+
|
23
|
+
gem_list.each do |name, gem_ref|
|
19
24
|
next if backend_file_list.include?(gem_ref.tar_file)
|
20
25
|
next unless member_of_installable_group?(gem_ref)
|
26
|
+
|
27
|
+
# Edge case: installation could fail if dependencies of this
|
28
|
+
# gem ref haven't been installed yet. They should have been
|
29
|
+
# prepared by this point because of the tsort logic in the
|
30
|
+
# gemfile class, but we need to actually install them in
|
31
|
+
# order to install this current gem. A good example is nokogiri,
|
32
|
+
# which can't build its native extension without mini-portile2.
|
33
|
+
gem_ref.dependencies.each do |dep|
|
34
|
+
if gem_list.gems[dep]
|
35
|
+
install_gem_ref(gem_list.gems[dep])
|
36
|
+
else
|
37
|
+
out.puts "Oops, couldn't find dependency #{dep}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
21
41
|
install_gem(gem_ref) if gem_ref.installable?
|
22
42
|
end
|
23
43
|
end
|
@@ -79,17 +99,51 @@ module Prebundler
|
|
79
99
|
config.storage_backend.store_file(dest_file, gem_ref.tar_file)
|
80
100
|
end
|
81
101
|
|
102
|
+
def update_bundle_config
|
103
|
+
file = Bundler.app_config_path.join('config').to_s
|
104
|
+
config = File.exist?(file) ? YAML.load_file(file) : {}
|
105
|
+
config['BUNDLE_WITH'] = with_groups.join(':') unless with_groups.empty?
|
106
|
+
config['BUNDLE_WITHOUT'] = without_groups.join(':') unless without_groups.empty?
|
107
|
+
File.write(file, YAML.dump(config))
|
108
|
+
end
|
109
|
+
|
110
|
+
def generate_binstubs
|
111
|
+
out.puts 'Generating binstubs...'
|
112
|
+
|
113
|
+
gems_with_executables = gem_list.gems.values.select do |gem_ref|
|
114
|
+
next false unless member_of_installable_group?(gem_ref)
|
115
|
+
!gem_ref.executables.empty?
|
116
|
+
end
|
117
|
+
|
118
|
+
return if gems_with_executables.empty?
|
119
|
+
|
120
|
+
system "bundle binstubs #{gems_with_executables.map(&:name).join(' ')}"
|
121
|
+
system "bundle binstubs --force bundler"
|
122
|
+
out.puts 'Done generating binstubs'
|
123
|
+
end
|
124
|
+
|
82
125
|
def check
|
83
|
-
system
|
126
|
+
system "bundle check --gemfile #{gemfile_path}"
|
84
127
|
|
85
128
|
if $?.exitstatus != 0
|
86
129
|
out.puts 'Bundle not satisfied, falling back to `bundle install`'
|
87
|
-
system
|
130
|
+
system "bundle install #{bundle_install_args}"
|
88
131
|
end
|
89
132
|
end
|
90
133
|
|
134
|
+
def bundle_install_args
|
135
|
+
[].tap do |args|
|
136
|
+
args << "--gemfile #{gemfile_path}"
|
137
|
+
args << "--with #{with_groups}" unless with_groups.empty?
|
138
|
+
args << "--without #{without_groups}" unless without_groups.empty?
|
139
|
+
args << "--jobs #{options[:jobs]}"
|
140
|
+
end.join(' ')
|
141
|
+
end
|
142
|
+
|
91
143
|
def gem_list
|
92
|
-
@gem_list ||= Prebundler::GemfileInterpreter.interpret(
|
144
|
+
@gem_list ||= Prebundler::GemfileInterpreter.interpret(
|
145
|
+
gemfile_path, bundle_path
|
146
|
+
)
|
93
147
|
end
|
94
148
|
|
95
149
|
def backend_file_list
|
@@ -115,14 +169,18 @@ module Prebundler
|
|
115
169
|
|
116
170
|
def groups
|
117
171
|
@groups ||= begin
|
118
|
-
all_groups = gem_list.flat_map { |_, gem_ref| gem_ref.groups }.uniq
|
119
|
-
|
120
|
-
without_groups = (options[:without] || '').split(',').map { |g| g.strip.to_sym }
|
121
|
-
|
122
|
-
groups = with_groups.empty? ? all_groups : with_groups
|
123
|
-
groups - without_groups
|
172
|
+
all_groups = gem_list.flat_map { |_, gem_ref| gem_ref.groups.to_a }.uniq
|
173
|
+
(all_groups + with_groups).uniq - without_groups
|
124
174
|
end
|
125
175
|
end
|
176
|
+
|
177
|
+
def with_groups
|
178
|
+
@with_groups ||= (options[:with] || '').split(/[:, ]/).map { |g| g.strip.to_sym }
|
179
|
+
end
|
180
|
+
|
181
|
+
def without_groups
|
182
|
+
@without_groups ||= (options[:without] || '').split(/[:, ]/).map { |g| g.strip.to_sym }
|
183
|
+
end
|
126
184
|
end
|
127
185
|
end
|
128
186
|
end
|
data/lib/prebundler/gem_ref.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'fileutils'
|
2
|
+
require 'set'
|
2
3
|
|
3
4
|
module Prebundler
|
4
5
|
class GemRef
|
@@ -12,13 +13,13 @@ module Prebundler
|
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
15
|
-
attr_reader :name, :bundle_path
|
16
|
+
attr_reader :name, :bundle_path, :groups
|
16
17
|
attr_accessor :spec, :dependencies
|
17
18
|
|
18
19
|
def initialize(name, bundle_path, options = {})
|
19
20
|
@name = name
|
20
21
|
@bundle_path = bundle_path
|
21
|
-
@groups = options[:groups]
|
22
|
+
@groups = Set.new(options[:groups])
|
22
23
|
@source = options[:source]
|
23
24
|
@dependencies = options[:dependencies]
|
24
25
|
end
|
@@ -27,10 +28,6 @@ module Prebundler
|
|
27
28
|
@dependencies ||= []
|
28
29
|
end
|
29
30
|
|
30
|
-
def groups
|
31
|
-
@groups ||= []
|
32
|
-
end
|
33
|
-
|
34
31
|
def source
|
35
32
|
@source ||= DEFAULT_SOURCE
|
36
33
|
end
|
@@ -44,8 +41,8 @@ module Prebundler
|
|
44
41
|
end
|
45
42
|
|
46
43
|
def install
|
47
|
-
system "gem install -N
|
48
|
-
$?.exitstatus
|
44
|
+
system({ "GEM_HOME" => bundle_path }, "gem install -N --ignore-dependencies --source #{source} #{name} -v #{version}")
|
45
|
+
$?.exitstatus
|
49
46
|
end
|
50
47
|
|
51
48
|
def install_from_tar(tar_file)
|
@@ -57,11 +54,28 @@ module Prebundler
|
|
57
54
|
tar_flags = File.exist?(tar_file) ? '-rf' : '-cf'
|
58
55
|
|
59
56
|
system "tar -C #{bundle_path} #{tar_flags} #{tar_file} #{relative_gem_dir}"
|
60
|
-
|
57
|
+
|
58
|
+
relative_gemspec_files.each do |relative_gemspec_file|
|
59
|
+
system "tar -C #{bundle_path} -rf #{tar_file} #{relative_gemspec_file}"
|
60
|
+
end
|
61
61
|
|
62
62
|
if File.directory?(extension_dir)
|
63
63
|
system "tar -C #{bundle_path} -rf #{tar_file} #{relative_extension_dir}"
|
64
64
|
end
|
65
|
+
|
66
|
+
executables.each do |executable|
|
67
|
+
system "tar -C #{bundle_path} -rf #{tar_file} #{File.join('bin', executable)}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def executables
|
72
|
+
gemspecs.flat_map(&:executables)
|
73
|
+
end
|
74
|
+
|
75
|
+
def gemspecs
|
76
|
+
@gemspecs ||= relative_gemspec_files.map do |relative_gemspec_file|
|
77
|
+
Bundler.load_gemspec(File.join(bundle_path, relative_gemspec_file))
|
78
|
+
end
|
65
79
|
end
|
66
80
|
|
67
81
|
def installable?
|
@@ -96,8 +110,8 @@ module Prebundler
|
|
96
110
|
File.join('gems', id)
|
97
111
|
end
|
98
112
|
|
99
|
-
def
|
100
|
-
File.join('specifications', gemspec_file)
|
113
|
+
def relative_gemspec_files
|
114
|
+
[File.join('specifications', gemspec_file)]
|
101
115
|
end
|
102
116
|
|
103
117
|
def tar_file
|
data/lib/prebundler/gemfile.rb
CHANGED
@@ -9,6 +9,10 @@ module Prebundler
|
|
9
9
|
|
10
10
|
def initialize(gems)
|
11
11
|
@gems = gems
|
12
|
+
|
13
|
+
gems.each do |_, gem_ref|
|
14
|
+
assign_groups(gem_ref, [])
|
15
|
+
end
|
12
16
|
end
|
13
17
|
|
14
18
|
def each
|
@@ -23,6 +27,16 @@ module Prebundler
|
|
23
27
|
|
24
28
|
private
|
25
29
|
|
30
|
+
# propagate groups to dependencies
|
31
|
+
def assign_groups(gem_ref, seen)
|
32
|
+
gem_ref.dependencies.each do |dep|
|
33
|
+
next if seen.include?(dep)
|
34
|
+
next unless gems[dep]
|
35
|
+
gem_ref.groups.each { |group| gems[dep].groups << group }
|
36
|
+
assign_groups(gems[dep], seen + [dep])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
26
40
|
def tsort_each_node(&block)
|
27
41
|
gems.keys.each(&block)
|
28
42
|
end
|
@@ -1,18 +1,21 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
1
3
|
module Prebundler
|
2
4
|
class GemfileInterpreter
|
3
|
-
def self.interpret(
|
4
|
-
Gemfile.new(new(
|
5
|
+
def self.interpret(gemfile_path, bundle_path)
|
6
|
+
Gemfile.new(new(gemfile_path, bundle_path).gems)
|
5
7
|
end
|
6
8
|
|
7
|
-
attr_reader :gems, :bundle_path
|
9
|
+
attr_reader :gems, :gemfile_path, :bundle_path
|
8
10
|
|
9
|
-
def initialize(
|
11
|
+
def initialize(gemfile_path, bundle_path)
|
10
12
|
@gems = {}
|
11
|
-
@current_groups = []
|
13
|
+
@current_groups = [:global]
|
14
|
+
@gemfile_path = gemfile_path
|
12
15
|
@bundle_path = bundle_path
|
13
|
-
instance_eval(File.read(
|
16
|
+
instance_eval(File.read(gemfile_path))
|
14
17
|
|
15
|
-
lockfile = Bundler::LockfileParser.new(File.read("#{
|
18
|
+
lockfile = Bundler::LockfileParser.new(File.read("#{gemfile_path}.lock"))
|
16
19
|
|
17
20
|
lockfile.specs.each do |spec|
|
18
21
|
gems[spec.name] ||= GemRef.create(spec.name, bundle_path)
|
@@ -35,7 +38,7 @@ module Prebundler
|
|
35
38
|
end
|
36
39
|
|
37
40
|
def path(dir)
|
38
|
-
@current_path = dir
|
41
|
+
@current_path = File.join(File.dirname(gemfile_path), dir)
|
39
42
|
yield if block_given?
|
40
43
|
@current_path = nil
|
41
44
|
end
|
@@ -49,7 +52,7 @@ module Prebundler
|
|
49
52
|
def group(*groups)
|
50
53
|
@current_groups = groups
|
51
54
|
yield if block_given?
|
52
|
-
@current_groups = []
|
55
|
+
@current_groups = [:global]
|
53
56
|
end
|
54
57
|
|
55
58
|
def gemspec
|
@@ -15,10 +15,13 @@ module Prebundler
|
|
15
15
|
def initialize(name, bundle_path, options = {})
|
16
16
|
super
|
17
17
|
@strategy = options.include?(:git) ? :git : :github
|
18
|
-
@uri = options[@strategy]
|
19
18
|
end
|
20
19
|
|
21
20
|
def install
|
21
|
+
FileUtils.mkdir_p(spec_path)
|
22
|
+
FileUtils.mkdir_p(install_path)
|
23
|
+
FileUtils.mkdir_p(cache_path)
|
24
|
+
|
22
25
|
return if File.exist?(cache_dir) || File.exist?(install_dir)
|
23
26
|
system "git clone #{uri} \"#{cache_dir}\" --bare --no-hardlinks --quiet"
|
24
27
|
return $? if $?.exitstatus != 0
|
@@ -55,11 +58,7 @@ module Prebundler
|
|
55
58
|
end
|
56
59
|
|
57
60
|
def uri
|
58
|
-
|
59
|
-
"git://github.com/#{@uri}.git"
|
60
|
-
else
|
61
|
-
@uri
|
62
|
-
end
|
61
|
+
spec.source.uri
|
63
62
|
end
|
64
63
|
|
65
64
|
alias_method :source, :uri
|
@@ -68,16 +67,26 @@ module Prebundler
|
|
68
67
|
spec.source.revision
|
69
68
|
end
|
70
69
|
|
70
|
+
def gemspecs
|
71
|
+
@gemspecs ||= gemspec_files.map do |gemspec_file|
|
72
|
+
Bundler.load_gemspec(gemspec_file)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
71
76
|
private
|
72
77
|
|
78
|
+
def gemspec_files
|
79
|
+
@gemspec_files ||= Dir[File.join(install_dir, '*.gemspec')]
|
80
|
+
end
|
81
|
+
|
73
82
|
def copy_gemspecs
|
74
|
-
FileUtils.cp(
|
83
|
+
FileUtils.cp(gemspec_files, spec_path)
|
75
84
|
end
|
76
85
|
|
77
86
|
# adapted from
|
78
87
|
# https://github.com/bundler/bundler/blob/fea23637886c1b1bde471c98344b8844f82e60ce/lib/bundler/source/git.rb#L237
|
79
88
|
def serialize_gemspecs
|
80
|
-
|
89
|
+
gemspec_files.each do |path|
|
81
90
|
# Evaluate gemspecs and cache the result. Gemspecs
|
82
91
|
# in git might require git or other dependencies.
|
83
92
|
# The gemspecs we cache should already be evaluated.
|
@@ -100,7 +109,7 @@ module Prebundler
|
|
100
109
|
# If there is no URI scheme, assume it is an ssh/git URI
|
101
110
|
input = uri
|
102
111
|
end
|
103
|
-
|
112
|
+
Bundler::SharedHelpers.digest(:SHA1).hexdigest(input)
|
104
113
|
end
|
105
114
|
end
|
106
115
|
end
|
@@ -10,7 +10,11 @@ module Prebundler
|
|
10
10
|
|
11
11
|
def initialize(name, bundle_path, options = {})
|
12
12
|
super
|
13
|
-
|
13
|
+
|
14
|
+
# @TODO: Individual gem calls can also specify a path, which
|
15
|
+
# we don't currently handle. For now just use the gem's name
|
16
|
+
# to complete the path.
|
17
|
+
@path = File.join(options[:path], name)
|
14
18
|
end
|
15
19
|
|
16
20
|
def installable?
|
@@ -21,6 +25,20 @@ module Prebundler
|
|
21
25
|
false
|
22
26
|
end
|
23
27
|
|
28
|
+
def gemspecs
|
29
|
+
@gemspecs ||= gemspec_files.map do |gemspec_file|
|
30
|
+
Dir.chdir(File.dirname(gemspec_file)) do
|
31
|
+
Bundler.load_gemspec(File.basename(gemspec_file))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
24
36
|
alias_method :source, :path
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def gemspec_files
|
41
|
+
@gemspec_files ||= Dir[File.join(path, '*.gemspec')]
|
42
|
+
end
|
25
43
|
end
|
26
44
|
end
|
data/lib/prebundler/version.rb
CHANGED
data/prebundler.gemspec
CHANGED
@@ -17,9 +17,8 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.add_dependency 'parallel', '~> 1.0'
|
18
18
|
s.add_dependency 'gli', '~> 2.0'
|
19
19
|
|
20
|
-
# @TODO:
|
20
|
+
# @TODO: move s3 support into separate gem
|
21
21
|
s.add_dependency 'aws-sdk', '~> 2.0'
|
22
|
-
s.add_dependency 'pry-byebug'
|
23
22
|
|
24
23
|
s.executables << 'prebundle'
|
25
24
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prebundler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cameron Dutro
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,20 +66,6 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '2.0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: pry-byebug
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :runtime
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
69
|
description: Gem dependency prebuilder
|
84
70
|
email:
|
85
71
|
- camertron@gmail.com
|