ceedling 0.27.0 → 0.28.1

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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/assets/project_as_gem.yml +6 -0
  3. data/assets/project_with_guts.yml +6 -0
  4. data/assets/project_with_guts_gcov.yml +88 -0
  5. data/assets/test_example_file_boom.c +13 -0
  6. data/assets/test_example_file_success.c +14 -0
  7. data/bin/ceedling +57 -113
  8. data/ceedling.gemspec +1 -1
  9. data/config/test_environment.rb +0 -1
  10. data/examples/blinky/project.yml +1 -1
  11. data/examples/temp_sensor/project.yml +7 -1
  12. data/examples/temp_sensor/rakefile.rb +3 -1
  13. data/lib/ceedling/build_invoker_utils.rb +14 -2
  14. data/lib/ceedling/configurator.rb +3 -1
  15. data/lib/ceedling/configurator_builder.rb +6 -4
  16. data/lib/ceedling/configurator_setup.rb +5 -1
  17. data/lib/ceedling/defaults.rb +5 -2
  18. data/lib/ceedling/dependinator.rb +1 -1
  19. data/lib/ceedling/file_path_utils.rb +1 -2
  20. data/lib/ceedling/generator_test_results.rb +3 -2
  21. data/lib/ceedling/generator_test_results_sanity_checker.rb +4 -3
  22. data/lib/ceedling/project_file_loader.rb +26 -9
  23. data/lib/ceedling/rakefile.rb +9 -2
  24. data/lib/ceedling/release_invoker.rb +1 -1
  25. data/lib/ceedling/reportinator.rb +18 -1
  26. data/lib/ceedling/system_utils.rb +6 -1
  27. data/lib/ceedling/system_wrapper.rb +2 -1
  28. data/lib/ceedling/target_loader.rb +2 -2
  29. data/lib/ceedling/tasks_filesystem.rake +8 -2
  30. data/lib/ceedling/tool_executor_helper.rb +71 -22
  31. data/lib/ceedling/version.rb +1 -1
  32. data/license.txt +1 -1
  33. data/out.fail +21 -0
  34. data/plugins/command_hooks/lib/command_hooks.rb +2 -1
  35. data/plugins/gcov/config/defaults.yml +22 -0
  36. data/plugins/gcov/gcov.rake +79 -65
  37. data/plugins/gcov/lib/gcov.rb +25 -38
  38. data/plugins/gcov/lib/gcov_constants.rb +16 -0
  39. data/spec/build_invoker_utils_spec.rb +54 -0
  40. data/spec/file_finder_helper_spec.rb +53 -0
  41. data/spec/gcov/gcov_deployment_spec.rb +70 -0
  42. data/spec/gcov/gcov_test_cases_spec.rb +91 -0
  43. data/spec/generator_test_results_sanity_checker_spec.rb +88 -0
  44. data/spec/generator_test_results_spec.rb +102 -0
  45. data/spec/reportinator_spec.rb +19 -0
  46. data/spec/spec_system_helper.rb +67 -5
  47. data/spec/support/other_target.yml +0 -0
  48. data/spec/support/target.yml +0 -0
  49. data/spec/support/test_example.fail +21 -0
  50. data/spec/support/test_example.pass +21 -0
  51. data/spec/support/test_example_empty.pass +13 -0
  52. data/spec/support/test_example_ignore.pass +21 -0
  53. data/spec/support/test_example_mangled.pass +19 -0
  54. data/spec/system/deployment_spec.rb +25 -5
  55. data/spec/system_utils_spec.rb +56 -0
  56. data/spec/target_loader_spec.rb +30 -0
  57. data/spec/tool_executor_helper_spec.rb +310 -0
  58. data/vendor/cmock/scripts/create_makefile.rb +35 -12
  59. data/vendor/unity/src/unity_internals.h +3 -3
  60. metadata +62 -27
  61. data/assets/rakefile_as_gem.rb +0 -3
  62. data/assets/rakefile_with_guts.rb +0 -6
  63. data/vendor/constructor/History.rdoc +0 -19
  64. data/vendor/constructor/README.rdoc +0 -72
  65. data/vendor/constructor/Rakefile +0 -33
  66. data/vendor/constructor/homepage/Notes.txt +0 -27
  67. data/vendor/constructor/homepage/Rakefile +0 -15
  68. data/vendor/constructor/homepage/index.erb +0 -27
  69. data/vendor/constructor/homepage/index.html +0 -36
  70. data/vendor/constructor/homepage/page_header.graffle +0 -0
  71. data/vendor/constructor/homepage/page_header.html +0 -9
  72. data/vendor/constructor/homepage/page_header.png +0 -0
  73. data/vendor/constructor/homepage/sample_code.png +0 -0
  74. data/vendor/constructor/homepage/sample_code.rb +0 -12
  75. data/vendor/constructor/lib/constructor.rb +0 -127
  76. data/vendor/constructor/lib/constructor_struct.rb +0 -33
  77. data/vendor/constructor/specs/constructor_spec.rb +0 -407
  78. data/vendor/constructor/specs/constructor_struct_spec.rb +0 -84
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 93c488605f82954ab5f2cccb06ecbfc489133c3b
4
- data.tar.gz: 5c97c451a98f9fb5c62522f46814f45aba20e4a6
3
+ metadata.gz: 71e849e4b01257b6bf46ff3f0c640ac834c75649
4
+ data.tar.gz: ad0c659fdc9dc461f80fe802876f1ef14901c4ec
5
5
  SHA512:
6
- metadata.gz: 8cf0b9dbce04687b13d374cfbf214641a72e147093b1c394c67e7e7775c73896c2bc290db3d108174cf8706f0bd378136eefe7540523c7115af2841b89a5695a
7
- data.tar.gz: f7575f0950a80118723f6a58fffd361fef164eddb2065ff622641ec1bdb5cbb6aa232149f6821ac495daa7f5086b835fc5c0a1ccd41af14e05271df16ce71fa6
6
+ metadata.gz: 21ce60fcc40db82d6f48067a5209a8ea9f7d6292005bb099e1143440b430fc3f5f73c4fcd345bf46683cec81ee62322a2dabae519c1ab05c1dc49d7e7ebd21a2
7
+ data.tar.gz: c7c120c485e554afaae2f4afeefdc6651b7636739d1501f37a919988d81bf38a6facb580bcb19a866bff023ca520ff7dca862a744836d2a845e524ffad6b6b2c
@@ -12,6 +12,9 @@
12
12
  :build_root: build
13
13
  # :release_build: TRUE
14
14
  :test_file_prefix: test_
15
+ :which_ceedling: gem
16
+ :default_tasks:
17
+ - test:all
15
18
 
16
19
  #:release_build:
17
20
  # :output: MyApp.out
@@ -57,6 +60,9 @@
57
60
  int8: INT8
58
61
  bool: UINT8
59
62
 
63
+ :gcov:
64
+ :html_report_type: basic
65
+
60
66
  #:tools:
61
67
  # Ceedling defaults to using gcc for compiling, linking, etc.
62
68
  # As [:tools] is blank, gcc will be used (so long as it's in your system path)
@@ -12,6 +12,9 @@
12
12
  :build_root: build
13
13
  # :release_build: TRUE
14
14
  :test_file_prefix: test_
15
+ :which_ceedling: vendor/ceedling
16
+ :default_tasks:
17
+ - test:all
15
18
 
16
19
  #:release_build:
17
20
  # :output: MyApp.out
@@ -57,6 +60,9 @@
57
60
  int8: INT8
58
61
  bool: UINT8
59
62
 
63
+ :gcov:
64
+ :html_report_type: basic
65
+
60
66
  #:tools:
61
67
  # Ceedling defaults to using gcc for compiling, linking, etc.
62
68
  # As [:tools] is blank, gcc will be used (so long as it's in your system path)
@@ -0,0 +1,88 @@
1
+ ---
2
+
3
+ # Notes:
4
+ # Sample project C code is not presently written to produce a release artifact.
5
+ # As such, release build options are disabled.
6
+ # This sample, therefore, only demonstrates running a collection of unit tests.
7
+
8
+ :project:
9
+ :use_exceptions: FALSE
10
+ :use_test_preprocessor: TRUE
11
+ :use_auxiliary_dependencies: TRUE
12
+ :build_root: build
13
+ # :release_build: TRUE
14
+ :test_file_prefix: test_
15
+
16
+ #:release_build:
17
+ # :output: MyApp.out
18
+ # :use_assembly: FALSE
19
+
20
+ :environment:
21
+
22
+ :extension:
23
+ :executable: .out
24
+
25
+ :paths:
26
+ :test:
27
+ - +:test/**
28
+ - -:test/support
29
+ :source:
30
+ - src/**
31
+ :support:
32
+ - test/support
33
+
34
+ :defines:
35
+ # in order to add common defines:
36
+ # 1) remove the trailing [] from the :common: section
37
+ # 2) add entries to the :common: section (e.g. :test: has TEST defined)
38
+ :commmon: &common_defines []
39
+ :test:
40
+ - *common_defines
41
+ - TEST
42
+ :test_preprocess:
43
+ - *common_defines
44
+ - TEST
45
+
46
+ :cmock:
47
+ :mock_prefix: mock_
48
+ :when_no_prototypes: :warn
49
+ :enforce_strict_ordering: TRUE
50
+ :plugins:
51
+ - :ignore
52
+ - :callback
53
+ :treat_as:
54
+ uint8: HEX8
55
+ uint16: HEX16
56
+ uint32: UINT32
57
+ int8: INT8
58
+ bool: UINT8
59
+
60
+ :gcov:
61
+ :html_report_type: basic
62
+
63
+ #:tools:
64
+ # Ceedling defaults to using gcc for compiling, linking, etc.
65
+ # As [:tools] is blank, gcc will be used (so long as it's in your system path)
66
+ # See documentation to configure a given toolchain for use
67
+
68
+ # LIBRARIES
69
+ # These libraries are automatically injected into the build process. Those specified as
70
+ # common will be used in all types of builds. Otherwise, libraries can be injected in just
71
+ # tests or releases. These options are MERGED with the options in supplemental yaml files.
72
+ :libraries:
73
+ :placement: :end
74
+ :flag: "${1}" # or "-L ${1}" for example
75
+ :common: &common_libraries []
76
+ :test:
77
+ - *common_libraries
78
+ :release:
79
+ - *common_libraries
80
+
81
+ :plugins:
82
+ :load_paths:
83
+ - vendor/ceedling/plugins
84
+ :enabled:
85
+ - stdout_pretty_tests_report
86
+ - module_generator
87
+ - gcov
88
+ ...
@@ -0,0 +1,13 @@
1
+ #include "unity.h"
2
+ #include "example_file.h"
3
+
4
+ void setUp(void) {}
5
+ void tearDown(void) {}
6
+
7
+ void test_add_numbers_adds_numbers(void) {
8
+ TEST_ASSERT_EQUAL(2, add_numbers(1,1) //Removed semicolon & parenthesis to make a compile error.
9
+ }
10
+
11
+ void test_add_numbers_will_fail(void) {
12
+ TEST_ASSERT_EQUAL(2, add_numbers(2,2));
13
+ }
@@ -0,0 +1,14 @@
1
+ #include "unity.h"
2
+ #include "example_file.h"
3
+
4
+ void setUp(void) {}
5
+ void tearDown(void) {}
6
+
7
+ void test_add_numbers_adds_numbers(void) {
8
+ TEST_ASSERT_EQUAL(2, add_numbers(1,1));
9
+ }
10
+
11
+ void test_add_numbers_will_fail_but_is_ignored_for_now(void) {
12
+ TEST_IGNORE();
13
+ TEST_ASSERT_EQUAL(2, add_numbers(2,2));
14
+ }
@@ -11,9 +11,8 @@ if (!project_found)
11
11
  main_filepath = "project.yml"
12
12
  project_found = File.exists?(main_filepath)
13
13
  end
14
- rakefile_found = (File.exists? "rakefile.rb")
15
14
 
16
- unless (project_found && rakefile_found)
15
+ unless (project_found)
17
16
  #===================================== We Do Not Have A Project ================================================
18
17
 
19
18
  puts "Welcome to Ceedling!"
@@ -27,20 +26,31 @@ unless (project_found && rakefile_found)
27
26
  include Thor::Actions
28
27
 
29
28
  desc "new PROJECT_NAME", "create a new ceedling project"
30
- method_option :nodocs, :type => :boolean, :default => false, :desc => "No docs in vendor directory"
29
+ method_option :no_docs, :type => :boolean, :default => false, :desc => "No docs in vendor directory"
30
+ method_option :nodocs, :type => :boolean, :default => false
31
31
  method_option :as_gem, :type => :boolean, :default => false, :desc => "Create the scaffold using Ceedling as a gem instead of filling in the vendor directory. Implies --no-docs."
32
+ method_option :no_configs, :type => :boolean, :default => false, :desc => "Don't install starter configuration files."
33
+ method_option :noconfigs, :type => :boolean, :default => false
32
34
  def new(name, silent = false)
33
- copy_assets_and_create_structure(name, silent, false, options[:nodocs], options[:as_gem])
35
+ copy_assets_and_create_structure(name, silent, false, options)
34
36
  end
35
37
 
36
38
  desc "upgrade PROJECT_NAME", "upgrade ceedling for a project (not req'd if gem used)"
37
- method_option :nodocs, :type => :boolean, :default => false, :desc => "No docs in vendor directory"
39
+ method_option :no_docs, :type => :boolean, :default => false, :desc => "No docs in vendor directory"
40
+ method_option :nodocs, :type => :boolean, :default => false
41
+ method_option :no_configs, :type => :boolean, :default => true, :desc => "Don't install starter configuration files."
42
+ method_option :noconfigs, :type => :boolean, :default => false
38
43
  def upgrade(name, silent = false)
39
- copy_assets_and_create_structure(name, silent, true, options[:nodocs])
44
+ copy_assets_and_create_structure(name, silent, true, options)
40
45
  end
41
46
 
42
47
  no_commands do
43
- def copy_assets_and_create_structure(name, silent=false, force=false, no_docs=false, as_gem=false)
48
+ def copy_assets_and_create_structure(name, silent=false, force=false, options = {})
49
+
50
+ no_docs = options[:no_docs] || options[:nodocs] || false
51
+ no_configs = options[:no_configs] || options[:noconfigs] || false
52
+ as_gem = options[:as_gem] || options[:asgem] || false
53
+
44
54
  ceedling_path = File.join(name, 'vendor', 'ceedling')
45
55
  source_path = File.join(name, 'src')
46
56
  test_path = File.join(name, 'test')
@@ -91,7 +101,6 @@ unless (project_found && rakefile_found)
91
101
  {:src => 'vendor/cmock/lib/', :dst => 'vendor/cmock/lib'},
92
102
  {:src => 'vendor/cmock/release/', :dst => 'vendor/cmock/release'},
93
103
  {:src => 'vendor/cmock/src/', :dst => 'vendor/cmock/src'},
94
- {:src => 'vendor/constructor/lib/', :dst => 'vendor/constructor/lib'},
95
104
  {:src => 'vendor/deep_merge/lib/', :dst => 'vendor/deep_merge/lib'},
96
105
  {:src => 'vendor/diy/lib', :dst => 'vendor/diy/lib'},
97
106
  {:src => 'vendor/unity/auto/', :dst => 'vendor/unity/auto'},
@@ -104,12 +113,12 @@ unless (project_found && rakefile_found)
104
113
  end
105
114
  end
106
115
 
107
- if as_gem
108
- copy_file(File.join('assets', 'project_as_gem.yml'), File.join(name, 'project.yml'), :force => force)
109
- copy_file(File.join('assets', 'rakefile_as_gem.rb'), File.join(name, 'rakefile.rb'), :force => force)
110
- else
111
- copy_file(File.join('assets', 'project_with_guts.yml'), File.join(name, 'project.yml'), :force => force)
112
- copy_file(File.join('assets', 'rakefile_with_guts.rb'), File.join(name, 'rakefile.rb'), :force => force)
116
+ unless (no_configs)
117
+ if as_gem
118
+ copy_file(File.join('assets', 'project_as_gem.yml'), File.join(name, 'project.yml'), :force => force)
119
+ else
120
+ copy_file(File.join('assets', 'project_with_guts.yml'), File.join(name, 'project.yml'), :force => force)
121
+ end
113
122
  end
114
123
 
115
124
  unless silent
@@ -138,20 +147,17 @@ unless (project_found && rakefile_found)
138
147
 
139
148
  dest_src = File.join(dest,'src')
140
149
  dest_test = File.join(dest,'test')
141
- dest_rakefile = File.join(dest,'rakefile.rb')
142
150
  dest_project = File.join(dest,'project.yml')
143
151
 
144
152
  directory "examples/#{proj_name}/src", dest_src
145
153
  directory "examples/#{proj_name}/test", dest_test
146
- remove_file dest_rakefile
147
154
  remove_file dest_project
148
- copy_file "examples/#{proj_name}/rakefile.rb", dest_rakefile
149
155
  copy_file "examples/#{proj_name}/project.yml", dest_project
150
156
 
151
157
  puts "\n"
152
158
  puts "Example project '#{proj_name}' created!"
153
159
  puts " - Tool documentation is located in vendor/ceedling/docs"
154
- puts " - Execute 'rake -T' to view available test & build tasks"
160
+ puts " - Execute 'ceedling help' to view available test & build tasks"
155
161
  puts ''
156
162
  end
157
163
 
@@ -178,66 +184,9 @@ unless (project_found && rakefile_found)
178
184
 
179
185
  #===================================== We Have A Project Already ================================================
180
186
  else
181
- begin
182
- require 'pty'
183
-
184
- #if available, we use PTY because it will live-stream our data instead of buffering it all up
185
- def spawn_command(cmd, &block)
186
- begin
187
- PTY.spawn(cmd) do |stdout, stdin, pid|
188
- begin
189
- block.call(stdout)
190
- rescue Errno::EIO
191
- end
192
- end
193
- rescue Exception => e
194
- STDERR.puts e.inspect unless (e == PTY::ChildExited)
195
- end
196
- end
197
-
198
- rescue LoadError
199
-
200
- begin
201
-
202
- require 'popen4'
203
-
204
- #if pty wasn't available, we'll use POPEN instead
205
- def spawn_command(cmd, &block)
206
- POpen4.popen4(cmd) do |stdout, stderr, stdin|
207
- begin
208
- block.call(stdout)
209
- rescue Errno::EIO
210
- end
211
- end
212
- end
213
-
214
- rescue LoadError
215
-
216
- #if neither of these libraries were available, we can just shell out to the command and collect results
217
- def spawn_command(cmd, &block)
218
- results = `#{cmd}`
219
- if ($?.exitstatus != 0)
220
- block.call( StringIO.new("ERROR: Aborted with Exit Code #{$?.exitstatus.to_s}") )
221
- else
222
- block.call( StringIO.new(results) )
223
- end
224
- end
225
- end
226
-
227
- end
228
-
229
187
  require 'yaml'
230
188
  require 'rbconfig'
231
189
 
232
- #determine the width of the screen
233
- cols = 80
234
- begin
235
- require 'curses'
236
- Curses.init_screen()
237
- cols = Curses.cols
238
- rescue LoadError
239
- end
240
-
241
190
  #determine platform
242
191
  platform = begin
243
192
  case(RbConfig::CONFIG['host_os'])
@@ -254,12 +203,13 @@ else
254
203
 
255
204
  #create our default meta-runner option set
256
205
  options = {
257
- :pretend_we_are_gtest => false,
258
- :args => "",
259
206
  :pretest => nil,
260
- :outfile => nil,
261
207
  :add_path => [],
262
208
  :path_connector => (platform == :mswin) ? ";" : ":",
209
+ :graceful_fail => false,
210
+ :which_ceedling => (Dir.exists?("vendor/ceedling") ? "vendor/ceedling" : 'gem'),
211
+ :default_tasks => [ 'test:all' ],
212
+ :list_tasks => false
263
213
  }
264
214
 
265
215
  #guess that we need a special script file first if it exists
@@ -271,15 +221,16 @@ else
271
221
 
272
222
  #merge in project settings if they can be found here
273
223
  yaml_options = YAML.load_file(main_filepath)
274
- options[:pretend_we_are_gtest] = (yaml_options[:plugins][:enabled].include? :stdout_gtestlike_tests_report) if (yaml_options[:plugins] && yaml_options[:plugins][:enabled])
275
224
  if (yaml_options[:paths])
276
225
  options[:add_path] = yaml_options[:paths][:tools] || []
277
226
  else
278
227
  options[:add_path] = []
279
228
  end
229
+ options[:graceful_fail] = yaml_options[:graceful_fail] if yaml_options[:graceful_fail]
230
+ options[:which_ceedling] = yaml_options[:project][:which_ceedling] if (yaml_options[:project] && yaml_options[:project][:which_ceedling])
231
+ options[:default_tasks] = yaml_options[:default_tasks] if yaml_options[:default_tasks]
280
232
 
281
233
  #sort through command line options
282
- options[:args]
283
234
  ARGV.each do |v|
284
235
  case(v)
285
236
  when /^(?:new|examples?|templates?)$/
@@ -288,16 +239,12 @@ else
288
239
  " but it looks like you're already in a project. If you really \n" +
289
240
  " want to do this, try moving to an empty folder.\n\n"
290
241
  abort
291
- when /^--gtest/
292
- options[:pretend_we_are_gtest] = true
293
- when /^--debug/
294
- options[:outfile] = "debug.txt"
295
242
  when /^help$/
296
- options[:args] += "-T "
243
+ options[:list_tasks] = true
297
244
  when /^project:(\w+)/
298
245
  ENV['CEEDLING_USER_PROJECT_FILE'] = "#{$1}.yml"
299
246
  else
300
- options[:args] += v + " "
247
+ #nothing
301
248
  end
302
249
  end
303
250
 
@@ -311,37 +258,34 @@ else
311
258
  ENV["PATH"] = path
312
259
  end
313
260
 
314
- if (options[:outfile])
315
- f = File.open(options[:outfile],'w')
316
- f << ARGV.inspect << "\n\n"
317
- f << options.inspect << "\n\n"
318
- end
319
-
320
- #run rake and capture all the output
321
- options[:cmd] = if (options[:pretest].nil? || options[:pretest].empty?)
322
- "rake #{options[:args]}"
261
+ # Load Ceedling (either through the rakefile OR directly)
262
+ if (File.exists?("rakefile.rb"))
263
+ load 'rakefile.rb'
323
264
  else
324
- "#{options[:pretest]} && rake #{options[:args]}"
325
- end
326
- spawn_command(options[:cmd]) do |stdout|
327
- stdout.each do |line|
328
- if (!options[:pretend_we_are_gtest] || (line.match(/^\[.*\]/)) || (line.match(/\d+ FAILED TESTS/)))
329
- f.puts(line) if (options[:outfile])
330
- if (options[:args].strip == "-T")
331
- line.gsub!(/(?<!\w)rake(?!\w)/,'ceedling')
332
- if (line.length > cols)
333
- endings = line.match(/[\r\n]+/)[0]
334
- line.gsub!(endings,'')
335
- line = line.slice(0, cols-3) + '...' + endings
336
- end
337
- end
338
- puts(line)
339
- end
265
+ if (options[:which_ceedling] == 'gem')
266
+ require 'ceedling'
267
+ else
268
+ load "#{options[:which_ceedling]}/lib/ceedling.rb"
340
269
  end
270
+ Ceedling.load_project
341
271
  end
342
272
 
343
- f.close if options[:outfile]
273
+ Rake.application.standard_exception_handling do
274
+ if options[:list_tasks]
275
+ # Display helpful task list when requested. This required us to dig into Rake internals a bit
276
+ Rake.application.define_singleton_method(:name=) {|n| @name = n}
277
+ Rake.application.name = 'ceedling'
278
+ Rake.application.options.show_tasks = :tasks
279
+ Rake.application.options.show_task_pattern = /^(?!.*build).*$/
280
+ Rake.application.display_tasks_and_comments()
281
+ else
282
+ task :default => options[:default_tasks]
283
+
284
+ # Run our Tasks!
285
+ Rake.application.collect_command_line_tasks(ARGV)
286
+ Rake.application.top_level
287
+ end
288
+ end
344
289
  true
345
-
346
290
  #===================================================================================================================
347
291
  end
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
16
16
 
17
17
  s.add_dependency "thor", ">= 0.14.5"
18
18
  s.add_dependency "rake", ">= 0.8.7"
19
- # s.add_dependency "curses", ">= 1.0.0"
19
+ s.add_runtime_dependency "constructor", ">= 1.0.4"
20
20
 
21
21
  # Files needed from submodules
22
22
  s.files = []