rscons 0.0.14 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,44 @@
1
1
  module Rscons
2
2
  describe Environment do
3
- describe '.clone' do
3
+ describe "#initialize" do
4
+ it "stores the construction variables passed in" do
5
+ env = Environment.new("CFLAGS" => ["-g"], "CPPPATH" => ["dir"])
6
+ env["CFLAGS"].should == ["-g"]
7
+ env["CPPPATH"].should == ["dir"]
8
+ end
9
+
10
+ it "adds the default builders when they are not excluded" do
11
+ env = Environment.new
12
+ env.builders.size.should be > 0
13
+ env.builders.map {|name, builder| builder.is_a?(Builder)}.all?.should be_true
14
+ env.builders.find {|name, builder| name == "Object"}.should_not be_nil
15
+ env.builders.find {|name, builder| name == "Program"}.should_not be_nil
16
+ env.builders.find {|name, builder| name == "Library"}.should_not be_nil
17
+ end
18
+
19
+ it "excludes the default builders with exclude_builders: :all" do
20
+ env = Environment.new(exclude_builders: :all)
21
+ env.builders.size.should == 0
22
+ end
23
+
24
+ it "excludes the named builders" do
25
+ env = Environment.new(exclude_builders: ["Library"])
26
+ env.builders.size.should be > 0
27
+ env.builders.find {|name, builder| name == "Object"}.should_not be_nil
28
+ env.builders.find {|name, builder| name == "Program"}.should_not be_nil
29
+ env.builders.find {|name, builder| name == "Library"}.should be_nil
30
+ end
31
+
32
+ context "when a block is given" do
33
+ it "yields self and invokes #process()" do
34
+ env = Environment.new do |env|
35
+ env.should_receive(:process)
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ describe "#clone" do
4
42
  it 'should create unique copies of each construction variable' do
5
43
  env = Environment.new
6
44
  env["CPPPATH"] << "path1"
@@ -9,15 +47,229 @@ module Rscons
9
47
  env["CPPPATH"].should == ["path1"]
10
48
  env2["CPPPATH"].should == ["path1", "path2"]
11
49
  end
50
+
51
+ context "when a block is given" do
52
+ it "yields self and invokes #process()" do
53
+ env = Environment.new
54
+ env.clone do |env2|
55
+ env2.should_receive(:process)
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ describe "#add_builder" do
62
+ it "adds the builder to the list of builders" do
63
+ env = Environment.new(exclude_builders: :all)
64
+ env.builders.keys.should == []
65
+ env.add_builder(Rscons::Object.new)
66
+ env.builders.keys.should == ["Object"]
67
+ end
68
+ end
69
+
70
+ describe "#get_build_fname" do
71
+ context "with no build directories" do
72
+ it "returns the name of the source file with suffix changed" do
73
+ env = Environment.new
74
+ env.get_build_fname("src/dir/file.c", ".o").should == "src/dir/file.o"
75
+ env.get_build_fname("src\\dir\\other.d", ".a").should == "src/dir/other.a"
76
+ env.get_build_fname("source.cc", ".o").should == "source.o"
77
+ end
78
+ end
79
+
80
+ context "with build directories" do
81
+ it "uses the build directories to create the output file name" do
82
+ env = Environment.new
83
+ env.build_dir("src", "bld")
84
+ env.build_dir(%r{^libs/([^/]+)}, 'build/libs/\1')
85
+ env.get_build_fname("src/input.cc", ".o").should == "bld/input.o"
86
+ env.get_build_fname("libs/lib1/some/file.c", ".o").should == "build/libs/lib1/some/file.o"
87
+ env.get_build_fname("libs/otherlib/otherlib.cc", ".o").should == "build/libs/otherlib/otherlib.o"
88
+ env.get_build_fname("other_directory/o.d", ".a").should == "other_directory/o.a"
89
+ end
90
+ end
91
+ end
92
+
93
+ describe "#[]" do
94
+ it "allows reading construction variables" do
95
+ env = Environment.new("CFLAGS" => ["-g", "-Wall"])
96
+ env["CFLAGS"].should == ["-g", "-Wall"]
97
+ end
98
+ end
99
+
100
+ describe "#[]=" do
101
+ it "allows writing construction variables" do
102
+ env = Environment.new("CFLAGS" => ["-g", "-Wall"])
103
+ env["CFLAGS"] -= ["-g"]
104
+ env["CFLAGS"] += ["-O3"]
105
+ env["CFLAGS"].should == ["-Wall", "-O3"]
106
+ env["other_var"] = "val33"
107
+ env["other_var"].should == "val33"
108
+ end
109
+ end
110
+
111
+ describe "#append" do
112
+ it "allows adding many construction variables at once" do
113
+ env = Environment.new("CFLAGS" => ["-g"], "CPPPATH" => ["inc"])
114
+ env.append("CFLAGS" => ["-Wall"], "CPPPATH" => ["include"])
115
+ env["CFLAGS"].should == ["-Wall"]
116
+ env["CPPPATH"].should == ["include"]
117
+ end
12
118
  end
13
119
 
14
- describe '.parse_makefile_deps' do
120
+ describe "#process" do
121
+ it "runs builders for all of the targets specified" do
122
+ env = Environment.new
123
+ env.Program("a.out", "main.c")
124
+
125
+ cache = "cache"
126
+ Cache.should_receive(:new).and_return(cache)
127
+ env.should_receive(:run_builder).with(anything, "a.out", ["main.c"], cache, {}).and_return(true)
128
+ cache.should_receive(:write)
129
+
130
+ env.process
131
+ end
132
+
133
+ it "builds dependent targets first" do
134
+ env = Environment.new
135
+ env.Program("a.out", "main.o")
136
+ env.Object("main.o", "other.cc")
137
+
138
+ cache = "cache"
139
+ Cache.should_receive(:new).and_return(cache)
140
+ env.should_receive(:run_builder).with(anything, "main.o", ["other.cc"], cache, {}).and_return("main.o")
141
+ env.should_receive(:run_builder).with(anything, "a.out", ["main.o"], cache, {}).and_return("a.out")
142
+ cache.should_receive(:write)
143
+
144
+ env.process
145
+ end
146
+
147
+ it "raises a BuildError when building fails" do
148
+ env = Environment.new
149
+ env.Program("a.out", "main.o")
150
+ env.Object("main.o", "other.cc")
151
+
152
+ cache = "cache"
153
+ Cache.should_receive(:new).and_return(cache)
154
+ env.should_receive(:run_builder).with(anything, "main.o", ["other.cc"], cache, {}).and_return(false)
155
+ cache.should_receive(:write)
156
+
157
+ expect { env.process }.to raise_error BuildError, /Failed.to.build.main.o/
158
+ end
159
+ end
160
+
161
+ describe "#build_command" do
162
+ it "returns a command based on the variables in the Environment" do
163
+ env = Environment.new
164
+ env["path"] = ["dir1", "dir2"]
165
+ env["flags"] = ["-x", "-y", "${specialflag}"]
166
+ env["specialflag"] = "-z"
167
+ template = ["cmd", "-I${path}", "${flags}", "${_source}", "${_dest}"]
168
+ cmd = env.build_command(template, "_source" => "infile", "_dest" => "outfile")
169
+ cmd.should == ["cmd", "-Idir1", "-Idir2", "-x", "-y", "-z", "infile", "outfile"]
170
+ end
171
+ end
172
+
173
+ describe "#execute" do
174
+ context "with echo: :short" do
175
+ context "with no errors" do
176
+ it "prints the short description and executes the command" do
177
+ env = Environment.new(echo: :short)
178
+ env.should_receive(:puts).with("short desc")
179
+ env.should_receive(:system).with("a", "command", {}).and_return(true)
180
+ env.execute("short desc", ["a", "command"])
181
+ end
182
+ end
183
+
184
+ context "with errors" do
185
+ it "prints the short description, executes the command, and prints the failed command line" do
186
+ env = Environment.new(echo: :short)
187
+ env.should_receive(:puts).with("short desc")
188
+ env.should_receive(:system).with("a", "command", {}).and_return(false)
189
+ $stdout.should_receive(:write).with("Failed command was: ")
190
+ env.should_receive(:puts).with("a command")
191
+ env.execute("short desc", ["a", "command"])
192
+ end
193
+ end
194
+ end
195
+
196
+ context "with echo: :command" do
197
+ it "prints the command executed and executes the command" do
198
+ env = Environment.new(echo: :command)
199
+ env.should_receive(:puts).with("a command '--arg=val with spaces'")
200
+ env.should_receive(:system).with("a", "command", "--arg=val with spaces", opt: :val).and_return(false)
201
+ env.execute("short desc", ["a", "command", "--arg=val with spaces"], opt: :val)
202
+ end
203
+ end
204
+ end
205
+
206
+ describe "#method_missing" do
207
+ it "calls the original method missing when the target method is not a known builder" do
208
+ env = Environment.new
209
+ env.should_receive(:orig_method_missing).with(:foobar)
210
+ env.foobar
211
+ end
212
+
213
+ it "records the target when the target method is a known builder" do
214
+ env = Environment.new
215
+ env.instance_variable_get(:@targets).should == {}
216
+ env.Program("target", ["src1", "src2"], var: "val")
217
+ target = env.instance_variable_get(:@targets)["target"]
218
+ target.should_not be_nil
219
+ target[:builder].is_a?(Builder).should be_true
220
+ target[:source].should == ["src1", "src2"]
221
+ target[:vars].should == {var: "val"}
222
+ target[:args].should == []
223
+ end
224
+
225
+ it "raises an error when vars is not a Hash" do
226
+ env = Environment.new
227
+ expect { env.Program("a.out", "main.c", "other") }.to raise_error /Unexpected construction variable set/
228
+ end
229
+ end
230
+
231
+ describe "#build_sources" do
232
+ class ABuilder < Builder
233
+ def produces?(target, source, env)
234
+ target =~ /\.ab_out$/ and source =~ /\.ab_in$/
235
+ end
236
+ end
237
+
238
+ it "finds and invokes a builder to produce output files with the requested suffixes" do
239
+ cache = "cache"
240
+ env = Environment.new
241
+ env.add_builder(ABuilder.new)
242
+ env.builders["Object"].should_receive(:run).with("mod.o", ["mod.c"], cache, env, anything).and_return("mod.o")
243
+ env.builders["ABuilder"].should_receive(:run).with("mod2.ab_out", ["mod2.ab_in"], cache, env, anything).and_return("mod2.ab_out")
244
+ env.build_sources(["precompiled.o", "mod.c", "mod2.ab_in"], [".o", ".ab_out"], cache, {}).should == ["precompiled.o", "mod.o", "mod2.ab_out"]
245
+ end
246
+ end
247
+
248
+ describe "#run_builder" do
249
+ it "modifies the construction variables using given build hooks and invokes the builder" do
250
+ env = Environment.new
251
+ env.add_build_hook do |build_op|
252
+ if build_op[:sources].first =~ %r{src/special}
253
+ build_op[:vars]["CFLAGS"] += ["-O3", "-DSPECIAL"]
254
+ end
255
+ end
256
+ env.builders["Object"].stub(:run) do |target, sources, cache, env, vars|
257
+ vars["CFLAGS"].should == []
258
+ end
259
+ env.run_builder(env.builders["Object"], "build/normal/module.o", ["src/normal/module.c"], "cache", {})
260
+ env.builders["Object"].stub(:run) do |target, sources, cache, env, vars|
261
+ vars["CFLAGS"].should == ["-O3", "-DSPECIAL"]
262
+ end
263
+ env.run_builder(env.builders["Object"], "build/special/module.o", ["src/special/module.c"], "cache", {})
264
+ end
265
+ end
266
+
267
+ describe ".parse_makefile_deps" do
15
268
  it 'handles dependencies on one line' do
16
269
  File.should_receive(:read).with('makefile').and_return(<<EOS)
17
270
  module.o: source.cc
18
271
  EOS
19
- env = Environment.new
20
- env.parse_makefile_deps('makefile', 'module.o').should == ['source.cc']
272
+ Environment.parse_makefile_deps('makefile', 'module.o').should == ['source.cc']
21
273
  end
22
274
 
23
275
  it 'handles dependencies split across many lines' do
@@ -26,8 +278,7 @@ module.o: module.c \\
26
278
  module.h \\
27
279
  other.h
28
280
  EOS
29
- env = Environment.new
30
- env.parse_makefile_deps('makefile', 'module.o').should == [
281
+ Environment.parse_makefile_deps('makefile', 'module.o').should == [
31
282
  'module.c', 'module.h', 'other.h']
32
283
  end
33
284
  end
@@ -84,30 +84,35 @@ module Rscons
84
84
  v = VarSet.new("CFLAGS" => ["-Wall", "-O2"],
85
85
  "CC" => "gcc",
86
86
  "CPPPATH" => ["dir1", "dir2"],
87
- "compiler" => "$CC",
88
- "cmd" => ["$CC", "-c", "$CFLAGS", "-I$[CPPPATH]"])
87
+ "compiler" => "${CC}",
88
+ "cmd" => ["${CC}", "-c", "${CFLAGS}", "-I${CPPPATH}"])
89
89
  it "expands to the string itself if the string is not a variable reference" do
90
90
  v.expand_varref("CC").should == "CC"
91
91
  v.expand_varref("CPPPATH").should == "CPPPATH"
92
92
  v.expand_varref("str").should == "str"
93
93
  end
94
94
  it "expands a single variable reference beginning with a '$'" do
95
- v.expand_varref("$CC").should == "gcc"
96
- v.expand_varref("$CPPPATH").should == ["dir1", "dir2"]
95
+ v.expand_varref("${CC}").should == "gcc"
96
+ v.expand_varref("${CPPPATH}").should == ["dir1", "dir2"]
97
97
  end
98
- it "expands a single variable reference in $[arr] notation" do
99
- v.expand_varref("prefix$[CFLAGS]suffix").should == ["prefix-Wallsuffix", "prefix-O2suffix"]
98
+ it "expands a single variable reference in ${arr} notation" do
99
+ v.expand_varref("prefix${CFLAGS}suffix").should == ["prefix-Wallsuffix", "prefix-O2suffix"]
100
100
  v.expand_varref(v["cmd"]).should == ["gcc", "-c", "-Wall", "-O2", "-Idir1", "-Idir2"]
101
101
  end
102
102
  it "expands a variable reference recursively" do
103
- v.expand_varref("$compiler").should == "gcc"
104
- v.expand_varref("$cmd").should == ["gcc", "-c", "-Wall", "-O2", "-Idir1", "-Idir2"]
103
+ v.expand_varref("${compiler}").should == "gcc"
104
+ v.expand_varref("${cmd}").should == ["gcc", "-c", "-Wall", "-O2", "-Idir1", "-Idir2"]
105
105
  end
106
- it "raises an error when array notation is applied to a non-array variable" do
107
- expect { v.expand_varref("$[CC]") }.to raise_error /Array.expected/
106
+ it "resolves multiple variable references in one element by enumerating all combinations" do
107
+ v.expand_varref("cflag: ${CFLAGS}, cpppath: ${CPPPATH}, compiler: ${compiler}").should == [
108
+ "cflag: -Wall, cpppath: dir1, compiler: gcc",
109
+ "cflag: -O2, cpppath: dir1, compiler: gcc",
110
+ "cflag: -Wall, cpppath: dir2, compiler: gcc",
111
+ "cflag: -O2, cpppath: dir2, compiler: gcc",
112
+ ]
108
113
  end
109
114
  it "raises an error when a variable reference refers to a non-existent variable" do
110
- expect { v.expand_varref("$not_here") }.to raise_error /Could.not.find.variable..not_here/
115
+ expect { v.expand_varref("${not_here}") }.to raise_error /I do not know how to expand a variable reference to a NilClass/
111
116
  end
112
117
  end
113
118
  end
@@ -0,0 +1,26 @@
1
+ describe Rscons do
2
+ describe ".clean" do
3
+ it "removes all build targets and created directories" do
4
+ cache = "cache"
5
+ Rscons::Cache.should_receive(:new).and_return(cache)
6
+ cache.should_receive(:targets).and_return(["build/a.out", "build/main.o"])
7
+ FileUtils.should_receive(:rm_f).with("build/a.out")
8
+ FileUtils.should_receive(:rm_f).with("build/main.o")
9
+ cache.should_receive(:directories).and_return(["build/one", "build/one/two", "build", "other"])
10
+ File.should_receive(:directory?).with("build/one/two").and_return(true)
11
+ Dir.should_receive(:entries).with("build/one/two").and_return([".", ".."])
12
+ Dir.should_receive(:rmdir).with("build/one/two")
13
+ File.should_receive(:directory?).with("build/one").and_return(true)
14
+ Dir.should_receive(:entries).with("build/one").and_return([".", ".."])
15
+ Dir.should_receive(:rmdir).with("build/one")
16
+ File.should_receive(:directory?).with("build").and_return(true)
17
+ Dir.should_receive(:entries).with("build").and_return([".", ".."])
18
+ Dir.should_receive(:rmdir).with("build")
19
+ File.should_receive(:directory?).with("other").and_return(true)
20
+ Dir.should_receive(:entries).with("other").and_return([".", "..", "other.file"])
21
+ Rscons::Cache.should_receive(:clear)
22
+
23
+ Rscons.clean
24
+ end
25
+ end
26
+ end
@@ -1,5 +1,7 @@
1
1
  require "simplecov"
2
2
 
3
- SimpleCov.start
3
+ SimpleCov.start do
4
+ add_filter "/spec/"
5
+ end
4
6
 
5
7
  require "rscons"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rscons
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-29 00:00:00.000000000 Z
12
+ date: 2013-11-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec-core
@@ -167,28 +167,20 @@ files:
167
167
  - Gemfile
168
168
  - LICENSE.txt
169
169
  - README.md
170
- - Rakefile
171
- - build_tests/build_dir/build.rb
170
+ - Rakefile.rb
172
171
  - build_tests/build_dir/src/one/one.c
173
172
  - build_tests/build_dir/src/two/two.c
174
173
  - build_tests/build_dir/src/two/two.h
175
- - build_tests/build_dir/tweaker_build.rb
176
- - build_tests/clone_env/build.rb
177
174
  - build_tests/clone_env/src/program.c
178
- - build_tests/custom_builder/build.rb
179
175
  - build_tests/custom_builder/program.c
180
- - build_tests/header/build.rb
176
+ - build_tests/d/main.d
181
177
  - build_tests/header/header.c
182
178
  - build_tests/header/header.h
183
- - build_tests/library/build.rb
184
179
  - build_tests/library/one.c
185
180
  - build_tests/library/three.c
186
181
  - build_tests/library/two.c
187
- - build_tests/simple/build.rb
188
182
  - build_tests/simple/simple.c
189
- - build_tests/simple_cc/build.rb
190
183
  - build_tests/simple_cc/simple.cc
191
- - build_tests/two_sources/build.rb
192
184
  - build_tests/two_sources/one.c
193
185
  - build_tests/two_sources/two.c
194
186
  - lib/rscons.rb
@@ -204,9 +196,11 @@ files:
204
196
  - lib/rscons/version.rb
205
197
  - rscons.gemspec
206
198
  - spec/build_tests_spec.rb
199
+ - spec/rscons/cache_spec.rb
207
200
  - spec/rscons/environment_spec.rb
208
201
  - spec/rscons/monkey/module_spec.rb
209
202
  - spec/rscons/varset_spec.rb
203
+ - spec/rscons_spec.rb
210
204
  - spec/spec_helper.rb
211
205
  homepage: https://github.com/holtrop/rscons
212
206
  licenses:
@@ -223,7 +217,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
223
217
  version: '0'
224
218
  segments:
225
219
  - 0
226
- hash: 982055185
220
+ hash: 306135951
227
221
  required_rubygems_version: !ruby/object:Gem::Requirement
228
222
  none: false
229
223
  requirements:
@@ -232,7 +226,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
232
226
  version: '0'
233
227
  segments:
234
228
  - 0
235
- hash: 982055185
229
+ hash: 306135951
236
230
  requirements: []
237
231
  rubyforge_project:
238
232
  rubygems_version: 1.8.23
@@ -241,8 +235,10 @@ specification_version: 3
241
235
  summary: Software construction library inspired by SCons and implemented in Ruby
242
236
  test_files:
243
237
  - spec/build_tests_spec.rb
238
+ - spec/rscons/cache_spec.rb
244
239
  - spec/rscons/environment_spec.rb
245
240
  - spec/rscons/monkey/module_spec.rb
246
241
  - spec/rscons/varset_spec.rb
242
+ - spec/rscons_spec.rb
247
243
  - spec/spec_helper.rb
248
244
  has_rdoc: