appbundler 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b6d3790061544bed9cee8bd44d5c94bcd235b46b
4
- data.tar.gz: 050a352e5d29f64ad1dd512abeef8759f9a17dfd
2
+ SHA256:
3
+ metadata.gz: 867a7edc3b0cb2bb729b3ec62f2c7afde7c9fcb46a58d7812d5ff261e1fe864e
4
+ data.tar.gz: 4c1edc5d6e127e064332406396574b28ae38891eb3c62ff92006dc8f399b18e8
5
5
  SHA512:
6
- metadata.gz: 46f7c7536c8090ba2ebd83b4678041e89965344cacc40d3d455897884beea826c258080f5add78a1d2387ba397e986863d95abaf4393aad1741e88fbb9d9a37e
7
- data.tar.gz: 4b2a888810f9199e41f17ffda7d4be4043d6569be893e46cbb7f9239793a6ad60ca837949d5774b552c2c1308822657e152c161d5647073bf7024058b3520836
6
+ metadata.gz: c9b76a7be7c70f2cb91e5fe25d80d70133f64abccc55fc40632b44f1d8e6edfceeb9b30111118b566859629b7b4360c6c7f92ef4a0db98e97eea2203c2b736a8
7
+ data.tar.gz: 1567880de2199ad880710c06169871be66dbb40af131c133ee18f940fe27658618a6f25474cb41b96d0e85d21f6cd8cbe5861071fd6a10e2cd2d57b67e86bac3
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "rake"
24
24
  spec.add_development_dependency "rspec", "~> 3.0"
25
25
  spec.add_development_dependency "pry"
26
- spec.add_development_dependency "mixlib-shellout", "~> 2.0"
27
26
 
27
+ spec.add_dependency "mixlib-shellout", "~> 2.0"
28
28
  spec.add_dependency "mixlib-cli", "~> 1.4"
29
29
  end
@@ -1,5 +1,7 @@
1
1
  require "bundler"
2
2
  require "fileutils"
3
+ require "mixlib/shellout"
4
+ require "tempfile"
3
5
  require "pp"
4
6
 
5
7
  module Appbundler
@@ -22,17 +24,112 @@ module Appbundler
22
24
  @name = name
23
25
  end
24
26
 
25
- # Copy over any .bundler and Gemfile.lock files to the target gem
26
- # directory. This will let us run tests from under that directory.
27
- def copy_bundler_env
28
- gem_path = app_gemspec.gem_dir
29
- # If we're already using that directory, don't copy (it won't work anyway)
30
- return if gem_path == File.dirname(gemfile_lock)
31
- FileUtils.install(gemfile_lock, gem_path, :mode => 0644)
32
- if File.exist?(dot_bundle_dir) && File.directory?(dot_bundle_dir)
33
- FileUtils.cp_r(dot_bundle_dir, gem_path)
34
- FileUtils.chmod_R("ugo+rX", File.join(gem_path, ".bundle"))
27
+ def gemfile_path
28
+ "#{app_dir}/Gemfile"
29
+ end
30
+
31
+ def safe_resolve_local_gem(s)
32
+ Gem::Specification.find_by_name(s.name, s.version)
33
+ rescue Gem::MissingSpecError
34
+ nil
35
+ end
36
+
37
+ def requirement_to_str(req)
38
+ req.as_list.map { |r| "\"#{r}\"" }.join(", ")
39
+ end
40
+
41
+ def requested_dependencies(without)
42
+ Bundler.settings.temporary(without: without) do
43
+ definition = Bundler::Definition.build(gemfile_path, gemfile_lock, nil)
44
+ definition.send(:requested_dependencies)
45
+ end
46
+ end
47
+
48
+ # This is a blatant ChefDK 2.0 hack. We need to audit all of our Gemfiles, make sure
49
+ # that github_changelog_generator is in its own group and exclude that group from all
50
+ # of our appbundle calls. But to ship ChefDK 2.0 we just do this.
51
+ SHITLIST = [
52
+ "github_changelog_generator",
53
+ ]
54
+
55
+ def external_lockfile?
56
+ app_dir != File.dirname(gemfile_lock)
57
+ end
58
+
59
+ def local_gemfile_lock_specs
60
+ gemfile_lock_specs.map do |s|
61
+ #if SHITLIST.include?(s.name)
62
+ # nil
63
+ #else
64
+ safe_resolve_local_gem(s)
65
+ #end
66
+ end.compact
67
+ end
68
+
69
+ def write_merged_lockfiles(without: [])
70
+ # just return we don't have an external lockfile
71
+ return unless external_lockfile?
72
+
73
+ # handle external lockfile
74
+ Tempfile.open(".appbundler-gemfile", app_dir) do |t|
75
+ t.puts "source 'https://rubygems.org'"
76
+
77
+ locked_gems = {}
78
+
79
+ gemfile_lock_specs.each do |s|
80
+ #next if SHITLIST.include?(s.name)
81
+ spec = safe_resolve_local_gem(s)
82
+ next if spec.nil?
83
+
84
+ case s.source
85
+ when Bundler::Source::Path
86
+ locked_gems[spec.name] = %Q{gem "#{spec.name}", path: "#{spec.gem_dir}"}
87
+ when Bundler::Source::Rubygems
88
+ # FIXME: should add the spec.version as a gem requirement below
89
+ locked_gems[spec.name] = %Q{gem "#{spec.name}", "= #{spec.version}"}
90
+ when Bundler::Source::Git
91
+ raise "FIXME: appbundler needs a patch to support Git gems"
92
+ else
93
+ raise "appbundler doens't know this source type"
94
+ end
95
+ end
96
+
97
+ seen_gems = {}
98
+
99
+ t.puts "# GEMS FROM GEMFILE:"
100
+
101
+ requested_dependencies(without).each do |dep|
102
+ next if SHITLIST.include?(dep.name)
103
+ if locked_gems[dep.name]
104
+ t.puts locked_gems[dep.name]
105
+ else
106
+ string = %Q{gem "#{dep.name}", #{requirement_to_str(dep.requirement)}}
107
+ string << %Q{, platform: #{dep.platforms}} unless dep.platforms.empty?
108
+ t.puts string
109
+ end
110
+ seen_gems[dep.name] = true
111
+ end
112
+
113
+ t.puts "# GEMS FROM LOCKFILE: "
114
+
115
+ locked_gems.each do |name, line|
116
+ next if SHITLIST.include?(name)
117
+ next if seen_gems[name]
118
+ t.puts line
119
+ end
120
+
121
+ t.close
122
+ puts IO.read(t.path) # debugging
123
+ Dir.chdir(app_dir) do
124
+ FileUtils.rm_f "#{app_dir}/Gemfile.lock"
125
+ Bundler.with_clean_env do
126
+ so = Mixlib::ShellOut.new("bundle lock", env: { "BUNDLE_GEMFILE" => t.path })
127
+ so.run_command
128
+ so.error!
129
+ end
130
+ end
35
131
  end
132
+ return "#{app_dir}/Gemfile.lock"
36
133
  end
37
134
 
38
135
  def write_executable_stubs
@@ -152,7 +249,11 @@ E
152
249
  end
153
250
 
154
251
  def runtime_dep_specs
155
- add_dependencies_from(app_spec)
252
+ if external_lockfile?
253
+ local_gemfile_lock_specs
254
+ else
255
+ add_dependencies_from(app_spec)
256
+ end
156
257
  end
157
258
 
158
259
  def app_dependency_names
@@ -167,6 +268,10 @@ E
167
268
  spec_for(name)
168
269
  end
169
270
 
271
+ def app_dir
272
+ app_gemspec.gem_dir
273
+ end
274
+
170
275
  def gemfile_lock_specs
171
276
  parsed_gemfile_lock.specs
172
277
  end
@@ -20,6 +20,13 @@ Your bundled application must already be gem installed. Generated binstubs
20
20
  will point to the gem, not your working copy.
21
21
  BANNER
22
22
 
23
+ # this is used by chef-dk, its probably not an external API, here be dragons
24
+ option :without,
25
+ :long => "--without GROUPS",
26
+ :description => "Comma separated list of groups to exclude when building transitive Gemfile.locks (internal API)",
27
+ :proc => lambda { |o| o.split(/[\s,]+/) },
28
+ :default => []
29
+
23
30
  option :version,
24
31
  :short => "-v",
25
32
  :long => "--version",
@@ -123,7 +130,8 @@ BANNER
123
130
  created_stubs.each do |real_executable_path, stub_path|
124
131
  $stdout.puts "Generated binstub #{stub_path} => #{real_executable_path}"
125
132
  end
126
- app.copy_bundler_env
133
+ created_lockfile = app.write_merged_lockfiles(without: config[:without])
134
+ $stdout.puts "Generated merged lockfile at #{created_lockfile}" if created_lockfile
127
135
  end
128
136
  end
129
137
 
@@ -1,3 +1,3 @@
1
1
  module Appbundler
2
- VERSION = "0.10.0"
2
+ VERSION = "0.11.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appbundler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan DeLeo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-29 00:00:00.000000000 Z
11
+ date: 2018-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -59,7 +59,7 @@ dependencies:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '2.0'
62
- type: :development
62
+ type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
@@ -133,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
133
  version: '0'
134
134
  requirements: []
135
135
  rubyforge_project:
136
- rubygems_version: 2.6.8
136
+ rubygems_version: 2.7.4
137
137
  signing_key:
138
138
  specification_version: 4
139
139
  summary: Extracts a dependency solution from bundler's Gemfile.lock to speed gem activation