Class: RubyInstaller::Build::Msys2Installation
- Inherits:
-
Object
- Object
- RubyInstaller::Build::Msys2Installation
- Defined in:
- lib/ruby_installer/build/msys2_installation.rb
Overview
:nodoc:
Defined Under Namespace
Classes: CommandError, MsysNotFound
Constant Summary collapse
- MSYS2_INSTALL_KEY =
"SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall/"- MSYS2_INSTALL_KEY_WOW =
"SOFTWARE/WOW6432Node/Microsoft/Windows/CurrentVersion/Uninstall/"- @@pacman_lock =
Mutex.new
Instance Attribute Summary collapse
-
#mingw_package_prefix ⇒ Object
readonly
Returns the value of attribute mingw_package_prefix.
-
#mingwarch ⇒ Object
readonly
Returns the value of attribute mingwarch.
-
#mingwdir ⇒ Object
readonly
Returns the value of attribute mingwdir.
-
#ruby_bin_dir ⇒ Object
readonly
Returns the value of attribute ruby_bin_dir.
Instance Method Summary collapse
- #disable_dll_search_paths ⇒ Object
- #disable_msys_apps(if_no_msys: :hint) ⇒ Object
-
#disable_msys_apps_per_cmd ⇒ Object
This method is used for the ridk command.
-
#disable_msys_apps_per_ps1 ⇒ Object
This method is used for the ridk command.
- #enable_dll_search_paths ⇒ Object
- #enable_msys_apps(if_no_msys: :hint, for_gem_install: false) ⇒ Object
-
#enable_msys_apps_per_cmd ⇒ Object
This method is used for the ridk command.
-
#enable_msys_apps_per_ps1 ⇒ Object
This method is used for the ridk command.
-
#initialize(msys_path: nil, mingwarch: nil, mingw_package_prefix: nil, ruby_bin_dir: nil) ⇒ Msys2Installation
constructor
A new instance of Msys2Installation.
- #install_mingw_packages(packages, verbose: false) ⇒ Object
- #install_packages(packages, verbose: false) ⇒ Object
- #iterate_msys_paths {|File.join(RbConfig::TOPDIR, "msys64")| ... } ⇒ Object
- #mingw_bin_path ⇒ Object
- #mingw_prefix ⇒ Object
- #msys_bin_path ⇒ Object
- #msys_path ⇒ Object
- #reset_cache ⇒ Object
- #with_msys_apps_disabled(**args) ⇒ Object
- #with_msys_apps_enabled(**args) ⇒ Object
Constructor Details
#initialize(msys_path: nil, mingwarch: nil, mingw_package_prefix: nil, ruby_bin_dir: nil) ⇒ Msys2Installation
Returns a new instance of Msys2Installation.
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 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 20 def initialize(msys_path: nil, mingwarch: nil, mingw_package_prefix: nil, ruby_bin_dir: nil) @msys_path = msys_path @msys_path_fixed = msys_path ? true : false @mingwdir = nil @mingwarch = mingwarch || ( case RUBY_PLATFORM when /x64.*ucrt/ then 'ucrt64' when /x64.*mingw32/ then 'mingw64' when /i386.*mingw32/ then 'mingw32' when /aarch64-mingw-ucrt/ then 'clangarm64' else raise "unsupported ruby platform #{RUBY_PLATFORM.inspect}" end ) @mingw_package_prefix = mingw_package_prefix || begin case @mingwarch when 'mingw32' then "mingw-w64-i686" when 'mingw64' then "mingw-w64-x86_64" when 'ucrt64' then "mingw-w64-ucrt-x86_64" when 'clangarm64' then "mingw-w64-clang-aarch64" else raise "unknown mingwarch #{@mingwarch.inspect}" end end @ruby_bin_dir = ruby_bin_dir || File.join(RbConfig::TOPDIR, "bin") end |
Instance Attribute Details
#mingw_package_prefix ⇒ Object (readonly)
Returns the value of attribute mingw_package_prefix.
17 18 19 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 17 def mingw_package_prefix @mingw_package_prefix end |
#mingwarch ⇒ Object (readonly)
Returns the value of attribute mingwarch.
16 17 18 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 16 def mingwarch @mingwarch end |
#mingwdir ⇒ Object (readonly)
Returns the value of attribute mingwdir.
15 16 17 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 15 def mingwdir @mingwdir end |
#ruby_bin_dir ⇒ Object (readonly)
Returns the value of attribute ruby_bin_dir.
18 19 20 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 18 def ruby_bin_dir @ruby_bin_dir end |
Instance Method Details
#disable_dll_search_paths ⇒ Object
143 144 145 146 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 143 def disable_dll_search_paths @mingwdir.remove if @mingwdir @mingwdir = nil end |
#disable_msys_apps(if_no_msys: :hint) ⇒ Object
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 251 def disable_msys_apps(if_no_msys: :hint) vars = with_msys_install_hint(if_no_msys) do msys_apps_envvars end changed = false if path=vars.delete("PATH") old_path = ENV['PATH'] ENV['PATH'] = old_path.gsub(path + ";", "") changed = ENV['PATH'] != old_path end vars.each do |key, val| changed = true if ENV[key] ENV.delete(key) end changed end |
#disable_msys_apps_per_cmd ⇒ Object
This method is used for the ridk command.
299 300 301 302 303 304 305 306 307 308 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 299 def disable_msys_apps_per_cmd vars = with_msys_install_hint{ msys_apps_envvars } str = "".dup if path=vars.delete("PATH") str << "PATH=#{ ENV['PATH'].gsub(path + ";", "") }\n" end str << vars.map do |key, val| "#{key}=" end.join("\n") end |
#disable_msys_apps_per_ps1 ⇒ Object
This method is used for the ridk command.
322 323 324 325 326 327 328 329 330 331 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 322 def disable_msys_apps_per_ps1 vars = with_msys_install_hint{ msys_apps_envvars } str = "".dup if path=vars.delete("PATH") str << "$env:PATH=\"#{ ENV['PATH'].gsub(path + ";", "").gsub('"', '`"') }\";" end str << vars.map do |key, val| "$env:#{key}=''" end.join(";") end |
#enable_dll_search_paths ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 130 def enable_dll_search_paths @mingwdir ||= begin DllDirectory.set_defaults # Add bundled dll directory for libcrypto.dll loading zlib.dll and legacy.dll loading libcrypto.dll DllDirectory.new(RbConfig::CONFIG["rubyarchdir"]) # Add MSYS2-MINGW DLL directory for user-installed gems path = mingw_bin_path DllDirectory.new(path) if File.directory?(path) rescue MsysNotFound # We silently ignore this error to allow Ruby installations without MSYS2. end end |
#enable_msys_apps(if_no_msys: :hint, for_gem_install: false) ⇒ Object
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 226 def enable_msys_apps(if_no_msys: :hint, for_gem_install: false) vars = with_msys_install_hint(if_no_msys) do msys_apps_envvars end changed = false if (path=vars.delete("PATH")) && !ENV['PATH'].include?(path) phrase = "Temporarily enhancing PATH for MSYS/MINGW..." if for_gem_install && defined?(Gem) Gem.ui.say(phrase) if Gem.configuration.verbose elsif $DEBUG $stderr.puts phrase end changed = true ENV['PATH'] = path + ";" + ENV['PATH'] end vars.each do |key, val| changed = true if ENV[key] != val ENV[key] = val end changed end |
#enable_msys_apps_per_cmd ⇒ Object
This method is used for the ridk command.
288 289 290 291 292 293 294 295 296 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 288 def enable_msys_apps_per_cmd vars = with_msys_install_hint{ msys_apps_envvars } if (path=vars.delete("PATH")) && !ENV['PATH'].include?(path) vars['PATH'] = path + ";" + ENV['PATH'] end vars.map do |key, val| "#{key}=#{val}" end.join("\n") end |
#enable_msys_apps_per_ps1 ⇒ Object
This method is used for the ridk command.
311 312 313 314 315 316 317 318 319 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 311 def enable_msys_apps_per_ps1 vars = with_msys_install_hint{ msys_apps_envvars } if (path=vars.delete("PATH")) && !ENV['PATH'].include?(path) vars['PATH'] = path + ";" + ENV['PATH'] end vars.map do |key, val| "$env:#{key}=\"#{val.gsub('"', '`"')}\"" end.join(";") end |
#install_mingw_packages(packages, verbose: false) ⇒ Object
367 368 369 370 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 367 def install_mingw_packages(packages, verbose: false) packages = packages.map{|pack| "#{mingw_package_prefix}-#{pack}" } install_packages(packages, verbose: verbose) end |
#install_packages(packages, verbose: false) ⇒ Object
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 338 def install_packages(packages, verbose: false) return if packages.empty? with_msys_apps_enabled do with_pacman_lock do # Find packages that are already installed skips, installs = packages.partition do |package| IO.popen(["pacman", "-Q", package], err: :out, &:read) $?.success? end Gem.ui.say("Using msys2 packages: #{skips.join(" ")}") if verbose && skips.any? # Install required packages if installs.any? Gem.ui.say("Installing required msys2 packages: #{installs.join(" ")}") if verbose args = ["pacman", "-S", "--needed", "--noconfirm", *installs] Gem.ui.say("> #{args.join(" ")}") if verbose==1 res = IO.popen(args, &:read) raise CommandError, "pacman failed with the following output:\n#{res}" if !$? || $?.exitstatus != 0 Gem.ui.say(res) if verbose==1 end end end end |
#iterate_msys_paths {|File.join(RbConfig::TOPDIR, "msys64")| ... } ⇒ Object
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 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 50 def iterate_msys_paths # Prefer MSYS2_PATH if ENV set if ENV["MSYS2_PATH"] yield ENV["MSYS2_PATH"] end # Prefer MSYS2 when installed within the ruby directory. yield File.join(RbConfig::TOPDIR, "msys64") yield File.join(RbConfig::TOPDIR, "msys32") # Then try MSYS2 next to the ruby directory. yield File.join(File.dirname(RbConfig::TOPDIR), "msys64") yield File.join(File.dirname(RbConfig::TOPDIR), "msys32") # If msys2 is installed at the default location yield "c:/msys64" yield "c:/msys32" # If msys2 is installed per installer.exe require "win32/registry" [ [Win32::Registry::HKEY_CURRENT_USER, MSYS2_INSTALL_KEY], [Win32::Registry::HKEY_CURRENT_USER, MSYS2_INSTALL_KEY_WOW], [Win32::Registry::HKEY_LOCAL_MACHINE, MSYS2_INSTALL_KEY], [Win32::Registry::HKEY_LOCAL_MACHINE, MSYS2_INSTALL_KEY_WOW], ].each do |reg_root, base_key| begin reg_root.open(backslachs(base_key)) do |reg| reg.each_key do |subkey| subreg = reg.open(subkey) begin if subreg['DisplayName'] =~ /^MSYS2 / && File.directory?(il=subreg['InstallLocation']) yield il end rescue Encoding::InvalidByteSequenceError, Win32::Registry::Error # Ignore entries without valid installer data or broken character encoding end end rescue Encoding::InvalidByteSequenceError, Encoding::UndefinedConversionError # Avoid crash even if subkey includes inconvertible characters to internal encoding end rescue Win32::Registry::Error end end ENV['PATH'] && ENV['PATH'].split(";").each do |path| # If /path/to/msys64 is in the PATH (e.g. Chocolatey) yield path end # If msys2 is installed by scoop package manager begin yield IO.popen(["scoop", "prefix", "msys2"], &:read).strip rescue SystemCallError end raise MsysNotFound, "MSYS2 could not be found" end |
#mingw_bin_path ⇒ Object
122 123 124 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 122 def mingw_bin_path backslachs( File.join(msys_path, mingwarch, "bin") ) end |
#mingw_prefix ⇒ Object
126 127 128 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 126 def mingw_prefix "/#{mingwarch}" end |
#msys_bin_path ⇒ Object
118 119 120 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 118 def msys_bin_path backslachs( File.join(msys_path, "/usr/bin") ) end |
#msys_path ⇒ Object
108 109 110 111 112 113 114 115 116 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 108 def msys_path @msys_path ||= begin iterate_msys_paths do |path| if File.exist?(File.join(path, "usr/bin/msys-2.0.dll")) break backslachs(path) end end end end |
#reset_cache ⇒ Object
46 47 48 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 46 def reset_cache @msys_path = nil unless @msys_path_fixed end |
#with_msys_apps_disabled(**args) ⇒ Object
278 279 280 281 282 283 284 285 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 278 def with_msys_apps_disabled(**args) changed = disable_msys_apps(**args) begin yield ensure enable_msys_apps(**args) if changed end end |
#with_msys_apps_enabled(**args) ⇒ Object
269 270 271 272 273 274 275 276 |
# File 'lib/ruby_installer/build/msys2_installation.rb', line 269 def with_msys_apps_enabled(**args) changed = enable_msys_apps(**args) begin yield ensure disable_msys_apps(**args) if changed end end |