From 7869d38dd83dd4cab65c1b9e47c18d42f675a3d8 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 7 Nov 2018 22:22:07 -0500 Subject: [PATCH] implement ConfigureOp#check_executable --- .../configure/check_executable_failure.rb | 3 + .../configure/check_executable_no_fail.rb | 3 + .../configure/check_executable_success.rb | 3 + lib/rscons/application.rb | 5 ++ lib/rscons/configure_op.rb | 55 ++++++++++++++++++- spec/build_tests_spec.rb | 26 +++++++++ 6 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 build_tests/configure/check_executable_failure.rb create mode 100644 build_tests/configure/check_executable_no_fail.rb create mode 100644 build_tests/configure/check_executable_success.rb diff --git a/build_tests/configure/check_executable_failure.rb b/build_tests/configure/check_executable_failure.rb new file mode 100644 index 0000000..152f66e --- /dev/null +++ b/build_tests/configure/check_executable_failure.rb @@ -0,0 +1,3 @@ +configure do + check_executable "executable-that-is-not-found" +end diff --git a/build_tests/configure/check_executable_no_fail.rb b/build_tests/configure/check_executable_no_fail.rb new file mode 100644 index 0000000..21eddae --- /dev/null +++ b/build_tests/configure/check_executable_no_fail.rb @@ -0,0 +1,3 @@ +configure do + check_executable "executable-that-is-not-found", fail: false +end diff --git a/build_tests/configure/check_executable_success.rb b/build_tests/configure/check_executable_success.rb new file mode 100644 index 0000000..c914402 --- /dev/null +++ b/build_tests/configure/check_executable_success.rb @@ -0,0 +1,3 @@ +configure do + check_executable "find" +end diff --git a/lib/rscons/application.rb b/lib/rscons/application.rb index fcec883..da8501d 100644 --- a/lib/rscons/application.rb +++ b/lib/rscons/application.rb @@ -115,6 +115,11 @@ module Rscons co.check_d_import(*cdi) end end + if ces = @script.check_executables + ces.each do |ce| + co.check_executable(*ce) + end + end rescue ConfigureOp::ConfigureFailure rv = 1 end diff --git a/lib/rscons/configure_op.rb b/lib/rscons/configure_op.rb index 4844945..053c117 100644 --- a/lib/rscons/configure_op.rb +++ b/lib/rscons/configure_op.rb @@ -161,6 +161,27 @@ module Rscons common_config_checks(status, options) end + # Check for an executable. + def check_executable(executable, options = {}) + $stdout.write("Checking for executable '#{executable}'... ") + found = false + if executable["/"] or executable["\\"] + if File.file?(executable) and File.executable?(executable) + found = true + success_message = executable + end + else + path_entries = ENV["PATH"].split(File::PATH_SEPARATOR) + path_entries.find do |path_entry| + if path = test_path_for_executable(path_entry, executable) + found = true + success_message = path + end + end + end + common_config_checks(found ? 0 : 1, options.merge(success_message: success_message)) + end + private # Test a C compiler. @@ -307,9 +328,12 @@ module Rscons # Whether to fail configuration if the requested item is not found. # @option options [String] :set_define # A define to set (in CPPDEFINES) if the requested item is found. + # @option options [String] :success_message + # Message to print on success (default "found"). def common_config_checks(status, options) + success_message = options[:success_message] || "found" if status == 0 - Ansi.write($stdout, :green, "found\n") + Ansi.write($stdout, :green, "#{success_message}\n") else if options.has_key?(:fail) and not options[:fail] Ansi.write($stdout, :yellow, "not found\n") @@ -323,5 +347,34 @@ module Rscons end end + # Check if a directory contains a certain executable. + # + # @param path_entry [String] + # Directory to look in. + # @param executable [String] + # Executable to look for. + def test_path_for_executable(path_entry, executable) + is_executable = lambda do |path| + File.file?(path) and File.executable?(path) + end + if RbConfig::CONFIG["host_os"] =~ /mswin|windows|mingw/i + executable = executable.downcase + dir_entries = Dir.entries(path_entry) + dir_entries.find do |entry| + path = "#{path_entry}/#{entry}" + entry = entry.downcase + if ((entry == executable) or + (entry == "#{executable}.exe") or + (entry == "#{executable}.com") or + (entry == "#{executable}.bat")) and is_executable[path] + return path + end + end + else + path = "#{path_entry}/#{executable}" + return path if is_executable[path] + end + end + end end diff --git a/spec/build_tests_spec.rb b/spec/build_tests_spec.rb index 0571dd4..3032db0 100644 --- a/spec/build_tests_spec.rb +++ b/spec/build_tests_spec.rb @@ -1698,6 +1698,32 @@ EOF expect(result.stdout).to match /Checking for D import 'not\.found'... not found/ end end + + context "check_executable" do + it "succeeds when the requested executable is found" do + test_dir "configure" + result = run_rscons(rsconsfile: "check_executable_success.rb", op: "configure") + expect(result.stderr).to eq "" + expect(result.status).to eq 0 + expect(result.stdout).to match /Checking for executable 'find'... .*find/ + end + + it "fails when the requested executable is not found" do + test_dir "configure" + result = run_rscons(rsconsfile: "check_executable_failure.rb", op: "configure") + expect(result.stderr).to eq "" + expect(result.status).to_not eq 0 + expect(result.stdout).to match /Checking for executable 'executable-that-is-not-found'... not found/ + end + + it "succeeds when the requested executable is not found but :fail is set to false" do + test_dir "configure" + result = run_rscons(rsconsfile: "check_executable_no_fail.rb", op: "configure") + expect(result.stderr).to eq "" + expect(result.status).to eq 0 + expect(result.stdout).to match /Checking for executable 'executable-that-is-not-found'... not found/ + end + end end end