lib/rake/funnel/support/msbuild/build_tool.rb in rake-funnel-0.21.2 vs lib/rake/funnel/support/msbuild/build_tool.rb in rake-funnel-0.22.0

- old
+ new

@@ -5,44 +5,67 @@ module Support module MSBuild class BuildTool class << self def find - mono_build || from_registry.compact.first + vswhere || + from_registry || + mono || + raise('No compatible MSBuild build tool was found') end private - def mono_build - return nil if Rake::Win32.windows? - - begin - out, status = Open3.capture2('mono', '--version') - raise "Could not determine mono version: #{status}" unless status.success? - rescue Errno::ENOENT - raise 'mono is not installed' + def mono + out, status = Open3.capture2('mono', '--version') + unless status.success? + warn "Could not determine mono version: #{status}" + return nil end return 'msbuild'.freeze if out[/^Mono JIT compiler version ([\d\.]+)/, 1] >= '5.0' 'xbuild'.freeze + rescue Errno::ENOENT + nil end + def vswhere # rubocop:disable Metrics/MethodLength + # -products * is required. + # https://github.com/Microsoft/vswhere/issues/61#issuecomment-298691077 + args = %w(vswhere.exe + -products * + -latest + -requires Microsoft.Component.MSBuild + -property installationPath) + + path, status = Open3.capture2(*args) + unless status.success? + warn "vswhere failed: #{status}" + return nil + end + + Dir[File.join(Rake::Win32.normalize(path.strip), + 'MSBuild/*/Bin/MSBuild.exe')] + .find { |e| File.file?(e) } + rescue Errno::ENOENT + nil + end + KEY = 'SOFTWARE\Microsoft\MSBuild\ToolsVersions'.freeze + REGISTRY_VERSIONS = %w(14.0 12.0 4.0 3.5 2.0).freeze def from_registry return nil unless require_registry - versions.map do |version| + candidates = REGISTRY_VERSIONS.map do |version| version_key(version) do |reg| candidate = File.join(reg['MSBuildToolsPath'] || '', 'msbuild.exe') next candidate if File.exist?(candidate) end end - end - def versions - %w(14.0 12.0 4.0 3.5 2.0) + candidates.compact.first end def require_registry require 'win32/registry' true