This repository has been archived by the owner on Jul 14, 2021. It is now read-only.
/
gem-install-software-def.rb
121 lines (104 loc) · 3.77 KB
/
gem-install-software-def.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
113
114
115
116
117
118
119
120
121
require "bundler"
require "omnibus"
require_relative "../build-chef-dk-gem"
module BuildChefDKGem
class GemInstallSoftwareDef
def self.define(software, software_filename)
new(software, software_filename).send(:define)
end
protected
def initialize(software, software_filename)
@software = software
@software_filename = software_filename
end
attr_reader :software, :software_filename
def define
software.name "#{File.basename(software_filename)[0..-4]}"
software.default_version gem_version
# If the source directory for building stuff changes, tell omnibus to
# de-cache us
software.source path: File.expand_path("../..", __FILE__)
# ruby and bundler and friends
software.dependency "ruby"
software.dependency "rubygems"
gem_name = self.gem_name
gem_version = self.gem_version
gemspec = self.gemspec
lockfile_path = self.lockfile_path
software.build do
extend BuildChefDKGem
if gem_version == "<skip>"
if gemspec
block do
log.info(log_key) { "#{gem_name} has source #{gemspec.source.name} in #{lockfile_path}. We only cache rubygems.org installs in omnibus to keep things simple. The chef-dk step will build #{gem_name} ..." }
end
else
block do
log.info(log_key) { "#{gem_name} is not in the #{lockfile_path}. This can happen if your OS doesn't build it, or if chef-dk no longer depends on it. Skipping ..." }
end
end
else
block do
log.info(log_key) { "Found version #{gem_version} of #{gem_name} in #{lockfile_path}. Building early to take advantage of omnibus caching ..." }
end
gem "install #{gem_name} -v #{gem_version} --ignore-dependencies --verbose -- #{install_args_for(gem_name)}", env: env
end
end
end
# Path above omnibus (where Gemfile is)
def root_path
File.expand_path("../..", software.project.files_path)
end
def gemfile_path
# gemfile path could be relative to software filename (and often is)
@gemfile_path ||= begin
# Grab the version (and maybe source) from the lockfile so omnibus knows whether
# to toss the cache or not
gemfile_path = File.join(root_path, "Gemfile")
platform_gemfile_path = "#{gemfile_path}.#{Omnibus::Ohai["platform"]}"
if File.exist?(platform_gemfile_path)
gemfile_path = platform_gemfile_path
end
gemfile_path
end
end
def lockfile_path
@lockfile_path ||= "#{gemfile_path}.lock"
end
def gem_name
@gem_name ||= begin
# File must be named chef-dk-<gemname>.rb
# Will look at chef-dk/Gemfile.lock and install that version of the gem using "gem install"
# (and only that version)
if File.basename(software_filename) =~ /^chef-dk-gem-(.+)\.rb$/
$1
else
raise "#{software_filename} must be named chef-dk-<gemname>.rb to build a gem automatically"
end
end
end
def gemspec
@gemspec ||= begin
old_frozen = Bundler.settings[:frozen]
Bundler.settings[:frozen] = true
begin
bundle = Bundler::Definition.build(gemfile_path, lockfile_path, nil)
gemspec = bundle.resolve.find { |spec| spec.name == gem_name }
raise "#{gem_name} not found in #{lockfile_path}" unless gemspec
gemspec
ensure
Bundler.settings[:frozen] = old_frozen
end
end
end
def gem_version
@gem_version ||= begin
if gemspec && gemspec.source.name == "rubygems repository https://rubygems.org/"
gemspec.version.to_s
else
"<skip>"
end
end
end
end
end