add Install builder - close #6

This commit is contained in:
Josh Holtrop 2015-02-07 09:49:29 -05:00
parent 9c49a09f69
commit f678803a5d
3 changed files with 145 additions and 1 deletions

View File

@ -6,10 +6,11 @@ require_relative "rscons/varset"
require_relative "rscons/version" require_relative "rscons/version"
# default builders # default builders
require_relative "rscons/builders/command"
require_relative "rscons/builders/cfile" require_relative "rscons/builders/cfile"
require_relative "rscons/builders/command"
require_relative "rscons/builders/directory" require_relative "rscons/builders/directory"
require_relative "rscons/builders/disassemble" require_relative "rscons/builders/disassemble"
require_relative "rscons/builders/install"
require_relative "rscons/builders/library" require_relative "rscons/builders/library"
require_relative "rscons/builders/object" require_relative "rscons/builders/object"
require_relative "rscons/builders/preprocess" require_relative "rscons/builders/preprocess"
@ -25,6 +26,7 @@ module Rscons
:CFile, :CFile,
:Directory, :Directory,
:Disassemble, :Disassemble,
:Install,
:Library, :Library,
:Object, :Object,
:Preprocess, :Preprocess,

View File

@ -0,0 +1,59 @@
require "pathname"
module Rscons
module Builders
# The Install builder copies files/directories to new locations.
class Install < Builder
# Run the builder to produce a build target.
#
# @param target [String] Target file name.
# @param sources [Array<String>] Source file name(s).
# @param cache [Cache] The Cache object.
# @param env [Environment] The Environment executing the builder.
# @param vars [Hash,VarSet] Extra construction variables.
#
# @return [String,false]
# Name of the target file on success or false on failure.
def run(target, sources, cache, env, vars)
target_is_dir = (sources.length > 1) ||
Dir.exists?(sources.first) ||
Dir.exists?(target)
outdir = target_is_dir ? target : File.dirname(target)
# Collect the list of files to copy over.
file_map = {}
if target_is_dir
sources.each do |src|
if Dir.exists? src
Dir.glob("#{src}/**/*", File::FNM_DOTMATCH).select do |f|
File.file?(f)
end.each do |subfile|
subpath = Pathname.new(subfile).relative_path_from(Pathname.new(src)).to_s
file_map[subfile] = "#{outdir}/#{subpath}"
end
else
file_map[src] = "#{outdir}/#{File.basename(src)}"
end
end
else
file_map[sources.first] = target
end
printed_message = false
file_map.each do |src, dest|
# Check the cache and copy if necessary
unless cache.up_to_date?(dest, :Copy, [src], env)
unless printed_message
puts "#{name} #{target}"
printed_message = true
end
cache.mkdir_p(File.dirname(dest))
FileUtils.cp(src, dest, :preserve => true)
end
cache.register_build(dest, :Copy, [src], env)
end
target if (target_is_dir ? Dir.exists?(target) : File.exists?(target))
end
end
end
end

View File

@ -832,4 +832,87 @@ EOF
end end
end end
context "Install buildler" do
let(:base_env) do
test_dir("build_dir")
Rscons::Environment.new do |env|
env["CPPPATH"] = Dir["src/**/"]
env["sources"] = Dir["src/**/*.c"]
env.Program("simple.exe", "${sources}")
end
end
it "copies a file to the target file name" do
env = base_env.clone do |env|
lines
env.Install("inst.exe", "simple.exe")
end
expect(lines).to eq(["Install inst.exe"])
env.Install("inst.exe", "simple.exe")
env.process
expect(lines).to eq([])
expect(File.exists?("inst.exe")).to be_truthy
expect(File.read("inst.exe", mode: "rb")).to eq(File.read("simple.exe", mode: "rb"))
FileUtils.rm("inst.exe")
env.Install("inst.exe", "simple.exe")
env.process
expect(lines).to eq(["Install inst.exe"])
end
it "copies a file to the target directory name" do
env = base_env.clone do |env|
lines
env.Directory("inst")
env.Install("inst", "simple.exe")
end
expect(lines).to eq([
"Directory inst",
"Install inst",
])
env.Install("inst", "simple.exe")
env.process
expect(lines).to eq([])
expect(File.exists?("inst/simple.exe")).to be_truthy
expect(File.read("inst/simple.exe", mode: "rb")).to eq(File.read("simple.exe", mode: "rb"))
end
it "copies a directory to the non-existent target directory name" do
env = base_env.clone do |env|
lines
env.Install("dist/src", "src")
end
expect(lines).to eq(["Install dist/src"])
env.Install("dist/src", "src")
env.process
expect(lines).to eq([])
%w[src/one/one.c src/two/two.c src/two/two.h].each do |f|
expect(File.exists?("dist/#{f}")).to be_truthy
expect(File.read("dist/#{f}", mode: "rb")).to eq(File.read(f, mode: "rb"))
end
end
it "copies a directory to the existent target directory name" do
env = base_env.clone do |env|
lines
env.Directory("dist/src")
env.Install("dist/src", "src")
end
expect(lines).to eq([
"Directory dist/src",
"Install dist/src",
])
env.Install("dist/src", "src")
env.process
expect(lines).to eq([])
%w[src/one/one.c src/two/two.c src/two/two.h].each do |f|
expect(File.exists?("dist/#{f}")).to be_truthy
expect(File.read("dist/#{f}", mode: "rb")).to eq(File.read(f, mode: "rb"))
end
FileUtils.rm("dist/src/two/two.c")
env.Install("dist/src", "src")
env.process
expect(lines).to eq(["Install dist/src"])
end
end
end end