Support passing a directory to rscons() method - close #128

This commit is contained in:
Josh Holtrop 2021-11-13 11:36:25 -05:00
parent a7b46093e9
commit ca747232cd
6 changed files with 110 additions and 23 deletions

View File

@ -0,0 +1,10 @@
configure do
rscons "sub"
rscons "sub", "-f", "Rsconscript2", "configure"
puts "top configure"
end
build do
rscons "sub", "-f", "Rsconscript2", "build"
puts "top build"
end

View File

@ -0,0 +1,4 @@
build do
rscons "second", "build"
puts "top build"
end

View File

@ -0,0 +1,3 @@
build do
puts "second build"
end

View File

@ -882,11 +882,18 @@ This can be used, for example, when a subproject is imported and a top-level
`configure` or `build` operation should also perform the same operation in the
subproject directory.
The first argument to the `rscons` method specifies either a directory name, or
the path to the subsidiary Rsconscript file to execute.
Any additional arguments are passed to `rscons` when it executes the subsidiary
script.
`rscons` will change working directories to the directory containing the
subsidiary script when executing it.
For example:
```ruby
configure do
rscons "subproject/Rsconscript", "configure"
rscons "subproject", "configure"
end
build do

View File

@ -8,21 +8,28 @@ module Rscons
# Invoke rscons in a subprocess for a subsidiary Rsconscript file.
#
# @param script_path [String]
# Path to subsidiary Rsconscript to execute.
# @param path [String]
# Path to subsidiary Rsconscript to execute, or path to subsidiary
# directory to run rscons in.
# @param args[Array<String>]
# Arguments to pass to rscons subprocess.
def rscons(script_path, *args)
script_path = File.expand_path(script_path)
def rscons(path, *args)
me = File.expand_path($0)
command = [me, "-f", script_path, *args]
path = File.expand_path(path)
if File.directory?(path)
command = [me, *args]
dir = path
else
command = [me, "-f", path, *args]
dir = File.dirname(path)
end
print_dir = dir != "." && dir != File.expand_path(Dir.pwd)
if ENV["specs"] and not ENV["dist_specs"] # specs
command = ["ruby", $LOAD_PATH.map {|p| ["-I", p]}, command].flatten # specs
end # specs
dir = File.dirname(script_path)
puts "Entering directory '#{dir}'..."
puts "rscons: Entering directory '#{dir}'" if print_dir
result = system(*command, chdir: dir)
puts "Leaving directory '#{dir}'..."
puts "rscons: Leaving directory '#{dir}'" if print_dir
unless result
raise RsconsError.new("Failed command: " + command.join(" "))
end

View File

@ -2607,28 +2607,84 @@ EOF
end
context "with subsidiary scripts" do
it "executes the subsidiary script from configure block" do
test_dir "subsidiary"
context "with a script specified" do
it "executes the subsidiary script from configure block" do
test_dir "subsidiary"
result = run_rscons(op: %W[configure])
expect(result.stderr).to eq ""
verify_lines(lines(result.stdout), [
%r{sub Rsconscript configure},
%r{sub Rsconscript build},
%r{sub Rsconscript2 configure},
%r{top configure},
])
result = run_rscons(op: %W[configure])
expect(result.stderr).to eq ""
verify_lines(lines(result.stdout), [
%r{Entering directory '.*/sub'},
%r{sub Rsconscript configure},
%r{Leaving directory '.*/sub'},
%r{Entering directory '.*/sub'},
%r{sub Rsconscript build},
%r{Leaving directory '.*/sub'},
%r{Entering directory '.*/sub'},
%r{sub Rsconscript2 configure},
%r{Leaving directory '.*/sub'},
%r{top configure},
])
end
it "executes the subsidiary script from build block" do
test_dir "subsidiary"
result = run_rscons(op: %W[configure])
expect(result.stderr).to eq ""
result = run_rscons(op: %W[build])
expect(result.stderr).to eq ""
verify_lines(lines(result.stdout), [
%r{sub Rsconscript2 build},
%r{top build},
])
end
end
it "executes the subsidiary script from build block" do
context "with a directory specified" do
it "executes the subsidiary script from configure block" do
test_dir "subsidiary"
result = run_rscons(rsconscript: "Rsconscript_dir", op: %W[configure])
expect(result.stderr).to eq ""
verify_lines(lines(result.stdout), [
%r{Entering directory '.*/sub'},
%r{sub Rsconscript configure},
%r{Leaving directory '.*/sub'},
%r{Entering directory '.*/sub'},
%r{sub Rsconscript build},
%r{Leaving directory '.*/sub'},
%r{Entering directory '.*/sub'},
%r{sub Rsconscript2 configure},
%r{Leaving directory '.*/sub'},
%r{top configure},
])
end
it "executes the subsidiary script from build block" do
test_dir "subsidiary"
result = run_rscons(rsconscript: "Rsconscript_dir", op: %W[configure])
expect(result.stderr).to eq ""
result = run_rscons(rsconscript: "Rsconscript_dir", op: %W[build])
expect(result.stderr).to eq ""
verify_lines(lines(result.stdout), [
%r{sub Rsconscript2 build},
%r{top build},
])
end
end
it "does not print entering/leaving directory messages when the subsidiary script is in the same directory" do
test_dir "subsidiary"
result = run_rscons(op: %W[configure])
result = run_rscons(rsconscript: "Rsconscript_samedir", op: %W[configure])
expect(result.stderr).to eq ""
result = run_rscons(op: %W[build])
result = run_rscons(rsconscript: "Rsconscript_samedir", op: %W[build])
expect(result.stderr).to eq ""
expect(result.stdout).to_not match(%{(Entering|Leaving) directory})
verify_lines(lines(result.stdout), [
%r{sub Rsconscript2 build},
%r{second build},
%r{top build},
])
end