From e279959d7926758c61d63cbc0573bb8105659233 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Mon, 13 Oct 2014 12:27:05 -0400 Subject: [PATCH] Added a command builder to the list of default builders --- README.md | 13 ++++++++++++ lib/rscons.rb | 2 ++ lib/rscons/builders/command.rb | 30 ++++++++++++++++++++++++++++ spec/rscons/builders/command_spec.rb | 16 +++++++++++++++ 4 files changed, 61 insertions(+) create mode 100644 lib/rscons/builders/command.rb create mode 100755 spec/rscons/builders/command_spec.rb diff --git a/README.md b/README.md index f654bf8..a0d75a3 100644 --- a/README.md +++ b/README.md @@ -210,6 +210,7 @@ end Rscons ships with a number of builders: +* Command, which executes a user-defined command to produce the target * CFile, which builds a C or C++ source file from a lex or yacc input file * Disassemble, which disassembles an object file to a disassembly listing * Library, which collects object files into a static library archive file @@ -220,6 +221,18 @@ Rscons ships with a number of builders: If you want to create an Environment that does not contain any builders, you can use the `exclude_builders` key to the Environment constructor. +#### Command + +```ruby +env.Command(target, sources, 'CMD' => command) +# Example +env.Command("docs.html", "docs.md", + CMD => ['pandoc', '-fmarkdown', '-thtml', '-o${_TARGET}', '${_SOURCES}']) +``` + +The command builder executes a user-defined command in order to produce the +desired target file based on the provided source files. + #### CFile ```ruby diff --git a/lib/rscons.rb b/lib/rscons.rb index de324d2..a566821 100644 --- a/lib/rscons.rb +++ b/lib/rscons.rb @@ -6,6 +6,7 @@ require_relative "rscons/varset" require_relative "rscons/version" # default builders +require_relative "rscons/builders/command" require_relative "rscons/builders/cfile" require_relative "rscons/builders/disassemble" require_relative "rscons/builders/library" @@ -18,6 +19,7 @@ module Rscons # Names of the default builders which will be added to all newly created # {Environment} objects. DEFAULT_BUILDERS = [ + :Command, :CFile, :Disassemble, :Library, diff --git a/lib/rscons/builders/command.rb b/lib/rscons/builders/command.rb new file mode 100644 index 0000000..5cef156 --- /dev/null +++ b/lib/rscons/builders/command.rb @@ -0,0 +1,30 @@ +module Rscons + module Builders + # Execute a command that will produce the given target based on the given + # sources. + # + # Example:: + # env.Command("docs.html", "docs.md", + # CMD => ['pandoc', '-fmarkdown', '-thtml', '-o${_TARGET}', '${_SOURCES}']) + class Command < Builder + # Run the builder to produce a build target. + # + # @param target [String] Target file name. + # @param sources [Array] 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) + vars = vars.merge({ + "_TARGET" => target, + "_SOURCES" => sources, + }) + command = env.build_command("${CMD}", vars) + standard_build("CMD #{target}", target, command, sources, env, cache) + end + end + end +end diff --git a/spec/rscons/builders/command_spec.rb b/spec/rscons/builders/command_spec.rb new file mode 100755 index 0000000..4c99a5c --- /dev/null +++ b/spec/rscons/builders/command_spec.rb @@ -0,0 +1,16 @@ +module Rscons + module Builders + describe Command do + let(:command) { ['pandoc', '-fmarkdown', '-thtml', '-o${_TARGET}', '${_SOURCES}'] } + let(:env) {Environment.new} + subject {Command.new} + + + it "invokes the command to build the target" do + expected_cmd = ['pandoc', '-fmarkdown', '-thtml', '-ofoo.html', 'foo.md'] + expect(subject).to receive(:standard_build).with("CMD foo.html", "foo.html", expected_cmd, ["foo.md"], env, :cache) + subject.run("foo.html", ["foo.md"], :cache, env, {'CMD' => command}) + end + end + end +end