-
-
Notifications
You must be signed in to change notification settings - Fork 12.5k
/
ruby.rb
277 lines (233 loc) · 9.25 KB
/
ruby.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
class Ruby < Formula
desc "Powerful, clean, object-oriented scripting language"
homepage "https://www.ruby-lang.org/"
license "Ruby"
head "https://github.com/ruby/ruby.git", branch: "master"
stable do
url "https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.1.tar.gz"
sha256 "3d385e5d22d368b064c817a13ed8e3cc3f71a7705d7ed1bae78013c33aa7c87f"
# Should be updated only when Ruby is updated (if an update is available).
# The exception is Rubygem security fixes, which mandate updating this
# formula & the versioned equivalents and bumping the revisions.
resource "rubygems" do
url "https://rubygems.org/rubygems/rubygems-3.6.2.tgz"
sha256 "d2f4e760eef098608692bbd6eff30df2e221b4723549da70dabcba116dc39680"
livecheck do
url "https://rubygems.org/pages/download"
regex(/href=.*?rubygems[._-]v?(\d+(?:\.\d+)+)\.t/i)
end
end
end
livecheck do
url "https://www.ruby-lang.org/en/downloads/releases/"
regex(/href=.*?ruby[._-]v?(\d+(?:\.\d+)+)\.t/i)
end
bottle do
rebuild 1
sha256 arm64_sequoia: "a11f7158aa46b332df40c93fba9348c5566952e1d6388d4cf4cb5254a217d929"
sha256 arm64_sonoma: "2a328dfe418369c55f51ff3893639e6637c2050166de98bb39594493450013e1"
sha256 arm64_ventura: "4d77b9eb5e005ea742383eef306f3ec0544d6d8137a7f06424029396fd0a58a2"
sha256 sonoma: "3c2c5e4956778c2e5c331f1104f7f4a1cfe9ea35c266e0800a5e9c555281d06e"
sha256 ventura: "817c7d0d6846e9745b704a9c021d8ed46e103f43d0da4c8a86a40c1c11ea225e"
sha256 x86_64_linux: "541296cf680716fc9439364c6559eaaed17afeeaa2b44ae30adab6a871d33c29"
end
keg_only :provided_by_macos
depends_on "autoconf" => :build
depends_on "pkgconf" => :build
depends_on "rust" => :build
depends_on "libyaml"
depends_on "openssl@3"
uses_from_macos "gperf"
uses_from_macos "libffi"
uses_from_macos "libxcrypt"
uses_from_macos "zlib"
def determine_api_version
Utils.safe_popen_read(bin/"ruby", "-e", "print Gem.ruby_api_version")
end
def api_version
if head?
if latest_head_prefix
determine_api_version
else
# Best effort guess
"#{stable.version.major.to_i}.#{stable.version.minor.to_i + 1}.0+0"
end
else
"#{version.major.to_i}.#{version.minor.to_i}.0"
end
end
def rubygems_bindir
HOMEBREW_PREFIX/"lib/ruby/gems/#{api_version}/bin"
end
def install
# otherwise `gem` command breaks
ENV.delete("SDKROOT")
# Prevent `make` from trying to install headers into the SDK
# TODO: Remove this workaround when the following PR is merged/resolved:
# https://github.com/Homebrew/brew/pull/12508
inreplace "tool/mkconfig.rb", /^(\s+val = )'"\$\(SDKROOT\)"'\+/, "\\1"
system "./autogen.sh" if build.head?
paths = %w[libyaml openssl@3].map { |f| Formula[f].opt_prefix }
args = %W[
--prefix=#{prefix}
--enable-shared
--disable-silent-rules
--with-sitedir=#{HOMEBREW_PREFIX}/lib/ruby/site_ruby
--with-vendordir=#{HOMEBREW_PREFIX}/lib/ruby/vendor_ruby
--with-opt-dir=#{paths.join(":")}
--without-gmp
]
args << "--with-baseruby=#{RbConfig.ruby}" if build.head?
args << "--disable-dtrace" if OS.mac? && !MacOS::CLT.installed?
# Correct MJIT_CC to not use superenv shim
args << "MJIT_CC=/usr/bin/#{DevelopmentTools.default_compiler}"
system "./configure", *args
# Ruby has been configured to look in the HOMEBREW_PREFIX for the
# sitedir and vendordir directories; however we don't actually want to create
# them during the install.
#
# These directories are empty on install; sitedir is used for non-rubygems
# third party libraries, and vendordir is used for packager-provided libraries.
inreplace "tool/rbinstall.rb" do |s|
s.gsub! 'prepare "extension scripts", sitelibdir', ""
s.gsub! 'prepare "extension scripts", vendorlibdir', ""
s.gsub! 'prepare "extension objects", sitearchlibdir', ""
s.gsub! 'prepare "extension objects", vendorarchlibdir', ""
end
system "make"
system "make", "install"
# A newer version of ruby-mode.el is shipped with Emacs
elisp.install Dir["misc/*.el"].reject { |f| f == "misc/ruby-mode.el" }
return if build.head? # Use bundled RubyGems for --HEAD (will be newer)
# This is easier than trying to keep both current & versioned Ruby
# formulae repeatedly updated with Rubygem patches.
resource("rubygems").stage do
ENV.prepend_path "PATH", bin
system bin/"ruby", "setup.rb", "--prefix=#{buildpath}/vendor_gem"
rg_in = lib/"ruby/#{api_version}"
rg_gems_in = lib/"ruby/gems/#{api_version}"
# Remove bundled Rubygem and Bundler
rm_r rg_in/"bundler"
rm rg_in/"bundler.rb"
rm_r Dir[rg_gems_in/"gems/bundler-*"]
rm Dir[rg_gems_in/"specifications/default/bundler-*.gemspec"]
rm_r rg_in/"rubygems"
rm rg_in/"rubygems.rb"
rm bin/"gem"
# Drop in the new version.
rg_in.install Dir[buildpath/"vendor_gem/lib/*"]
(rg_gems_in/"gems").install Dir[buildpath/"vendor_gem/gems/*"]
(rg_gems_in/"specifications/default").install Dir[buildpath/"vendor_gem/specifications/default/*"]
bin.install buildpath/"vendor_gem/bin/gem" => "gem"
(libexec/"gembin").install buildpath/"vendor_gem/bin/bundle" => "bundle"
(libexec/"gembin").install_symlink "bundle" => "bundler"
end
# remove all lockfiles in bin folder
rm Dir[bin/"*.lock"]
end
def post_install
# Since Gem ships Bundle we want to provide that full/expected installation
# but to do so we need to handle the case where someone has previously
# installed bundle manually via `gem install`.
rm(%W[
#{rubygems_bindir}/bundle
#{rubygems_bindir}/bundler
].select { |file| File.exist?(file) })
rm_r(Dir[HOMEBREW_PREFIX/"lib/ruby/gems/#{api_version}/gems/bundler-*"])
rubygems_bindir.install_symlink Dir[libexec/"gembin/*"]
# Customize rubygems to look/install in the global gem directory
# instead of in the Cellar, making gems last across reinstalls
config_file = lib/"ruby/#{api_version}/rubygems/defaults/operating_system.rb"
config_file.unlink if config_file.exist?
config_file.write rubygems_config(api_version)
# Create the sitedir and vendordir that were skipped during install
%w[sitearchdir vendorarchdir].each do |dir|
mkdir_p `#{bin}/ruby -rrbconfig -e 'print RbConfig::CONFIG["#{dir}"]'`
end
end
def rubygems_config(api_version)
<<~EOS
module Gem
class << self
alias :old_default_dir :default_dir
alias :old_default_path :default_path
alias :old_default_bindir :default_bindir
alias :old_ruby :ruby
alias :old_default_specifications_dir :default_specifications_dir
end
def self.default_dir
path = [
"#{HOMEBREW_PREFIX}",
"lib",
"ruby",
"gems",
"#{api_version}"
]
@homebrew_path ||= File.join(*path)
end
def self.private_dir
path = if defined? RUBY_FRAMEWORK_VERSION then
[
File.dirname(RbConfig::CONFIG['sitedir']),
'Gems',
RbConfig::CONFIG['ruby_version']
]
elsif RbConfig::CONFIG['rubylibprefix'] then
[
RbConfig::CONFIG['rubylibprefix'],
'gems',
RbConfig::CONFIG['ruby_version']
]
else
[
RbConfig::CONFIG['libdir'],
ruby_engine,
'gems',
RbConfig::CONFIG['ruby_version']
]
end
@private_dir ||= File.join(*path)
end
def self.default_path
if Gem.user_home && File.exist?(Gem.user_home)
[user_dir, default_dir, old_default_dir, private_dir]
else
[default_dir, old_default_dir, private_dir]
end
end
def self.default_bindir
"#{rubygems_bindir}"
end
def self.ruby
"#{opt_bin}/ruby"
end
# https://github.com/Homebrew/homebrew-core/issues/40872#issuecomment-542092547
# https://github.com/Homebrew/homebrew-core/pull/48329#issuecomment-584418161
def self.default_specifications_dir
File.join(Gem.old_default_dir, "specifications", "default")
end
end
EOS
end
def caveats
<<~EOS
By default, binaries installed by gem will be placed into:
#{rubygems_bindir}
You may want to add this to your PATH.
EOS
end
test do
hello_text = shell_output("#{bin}/ruby -e 'puts :hello'")
assert_equal "hello\n", hello_text
assert_equal api_version, determine_api_version
ENV["GEM_HOME"] = testpath
system bin/"gem", "install", "json"
(testpath/"Gemfile").write <<~EOS
source 'https://rubygems.org'
gem 'github-markup'
EOS
system bin/"bundle", "exec", "ls" # https://github.com/Homebrew/homebrew-core/issues/53247
system bin/"bundle", "install", "--binstubs=#{testpath}/bin"
assert_predicate testpath/"bin/github-markup", :exist?, "github-markup is not installed in #{testpath}/bin"
end
end