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