99
1010@failure_count = 0
1111@passfail = proc { |result | result ? "✓" : "✗" }
12+ @backend = nil
1213
1314# Use some basic parsing to allow command-line overrides of config
1415class Parser
@@ -29,11 +30,6 @@ def self.parse(options)
2930 output_options [ :skip_unittests ] = p
3031 end
3132
32- opts . on ( "--skip-compilation" , "Don't compile example sketches (deprecated)" ) do |p |
33- puts "The option --skip-compilation has been deprecated in favor of --skip-examples-compilation"
34- output_options [ :skip_compilation ] = p
35- end
36-
3733 opts . on ( "--skip-examples-compilation" , "Don't compile example sketches" ) do |p |
3834 output_options [ :skip_compilation ] = p
3935 end
@@ -68,11 +64,11 @@ def self.parse(options)
6864def terminate ( final = nil )
6965 puts "Failures: #{ @failure_count } "
7066 unless @failure_count . zero? || final
71- puts "Last message: #{ @arduino_backend . last_msg } "
67+ puts "Last message: #{ @backend . last_msg } "
7268 puts "========== Stdout:"
73- puts @arduino_backend . last_out
69+ puts @backend . last_out
7470 puts "========== Stderr:"
75- puts @arduino_backend . last_err
71+ puts @backend . last_err
7672 end
7773 retcode = @failure_count . zero? ? 0 : 1
7874 exit ( retcode )
@@ -172,25 +168,33 @@ def display_files(pathname)
172168 non_hidden . each { |p | puts "#{ margin } #{ p } " }
173169end
174170
175- def install_arduino_library_dependencies ( aux_libraries )
176- aux_libraries . each do |l |
177- if @arduino_backend . library_present? ( l )
178- inform ( "Using pre-existing library" ) { l . to_s }
171+ # @return [Array<String>] The list of installed libraries
172+ def install_arduino_library_dependencies ( library_names , on_behalf_of , already_installed = [ ] )
173+ installed = already_installed . clone
174+ library_names . map { |n | @backend . library_of_name ( n ) } . each do |l |
175+ if installed . include? ( l )
176+ # do nothing
177+ elsif l . installed?
178+ inform ( "Using pre-existing dependency of #{ on_behalf_of } " ) { l . name }
179179 else
180- assure ( "Installing aux library '#{ l } '" ) { @arduino_backend . install_library ( l ) }
180+ assure ( "Installing dependency of #{ on_behalf_of } : '#{ l . name } '" ) do
181+ next nil unless l . install
182+
183+ l . name
184+ end
181185 end
186+ installed << l . name
187+ installed += install_arduino_library_dependencies ( l . arduino_library_dependencies , l . name , installed )
182188 end
189+ installed
183190end
184191
185- def perform_unit_tests ( file_config )
192+ def perform_unit_tests ( cpp_library , file_config )
186193 if @cli_options [ :skip_unittests ]
187194 inform ( "Skipping unit tests" ) { "as requested via command line" }
188195 return
189196 end
190197 config = file_config . with_override_config ( @cli_options [ :ci_config ] )
191- cpp_library = ArduinoCI ::CppLibrary . new ( Pathname . new ( "." ) ,
192- @arduino_backend . lib_dir ,
193- config . exclude_dirs . map ( &Pathname . method ( :new ) ) )
194198
195199 # check GCC
196200 compilers = config . compilers_to_use
@@ -216,7 +220,7 @@ def perform_unit_tests(file_config)
216220 if !cpp_library . tests_dir . exist?
217221 # alert future me about running the script from the wrong directory, instead of doing the huge file dump
218222 # otherwise, assume that the user might be running the script on a library with no actual unit tests
219- if ( Pathname . new ( __dir__ ) . parent == Pathname . new ( Dir . pwd ) )
223+ if Pathname . new ( __dir__ ) . parent == Pathname . new ( Dir . pwd )
220224 inform_multiline ( "arduino_ci seems to be trying to test itself" ) do
221225 [
222226 "arduino_ci (the ruby gem) isn't an arduino project itself, so running the CI test script against" ,
@@ -243,7 +247,7 @@ def perform_unit_tests(file_config)
243247 elsif config . platforms_to_unittest . empty?
244248 inform ( "Skipping unit tests" ) { "no platforms were requested" }
245249 else
246- install_arduino_library_dependencies ( config . aux_libraries_for_unittest )
250+ install_arduino_library_dependencies ( config . aux_libraries_for_unittest , "<unittest/libraries>" )
247251
248252 config . platforms_to_unittest . each do |p |
249253 config . allowable_unittest_files ( cpp_library . test_files ) . each do |unittest_path |
@@ -271,36 +275,12 @@ def perform_unit_tests(file_config)
271275 end
272276end
273277
274- def perform_compilation_tests ( config )
278+ def perform_example_compilation_tests ( cpp_library , config )
275279 if @cli_options [ :skip_compilation ]
276280 inform ( "Skipping compilation of examples" ) { "as requested via command line" }
277281 return
278282 end
279283
280- # initialize library under test
281- installed_library_path = attempt ( "Installing library under test" ) do
282- @arduino_backend . install_local_library ( Pathname . new ( "." ) )
283- end
284-
285- if !installed_library_path . nil? && installed_library_path . exist?
286- inform ( "Library installed at" ) { installed_library_path . to_s }
287- else
288- assure_multiline ( "Library installed successfully" ) do
289- if installed_library_path . nil?
290- puts @arduino_backend . last_msg
291- else
292- # print out the contents of the deepest directory we actually find
293- @arduino_backend . lib_dir . ascend do |path_part |
294- next unless path_part . exist?
295-
296- break display_files ( path_part )
297- end
298- false
299- end
300- end
301- end
302- library_examples = @arduino_backend . library_examples ( installed_library_path )
303-
304284 # gather up all required boards for compilation so we can install them up front.
305285 # start with the "platforms to unittest" and add the examples
306286 # while we're doing that, get the aux libraries as well
@@ -309,6 +289,7 @@ def perform_compilation_tests(config)
309289 aux_libraries = Set . new ( config . aux_libraries_for_build )
310290 # while collecting the platforms, ensure they're defined
311291
292+ library_examples = cpp_library . example_sketches
312293 library_examples . each do |path |
313294 ovr_config = config . from_example ( path )
314295 ovr_config . platforms_to_build . each do |platform |
@@ -329,33 +310,35 @@ def perform_compilation_tests(config)
329310 # do that, set the URLs, and download the packages
330311 all_packages = example_platform_info . values . map { |v | v [ :package ] } . uniq . reject ( &:nil? )
331312
313+ builtin_packages , external_packages = all_packages . partition { |p | config . package_builtin? ( p ) }
314+
332315 # inform about builtin packages
333- all_packages . select { | p | config . package_builtin? ( p ) } . each do |p |
316+ builtin_packages . each do |p |
334317 inform ( "Using built-in board package" ) { p }
335318 end
336319
337320 # make sure any non-builtin package has a URL defined
338- all_packages . reject { | p | config . package_builtin? ( p ) } . each do |p |
321+ external_packages . each do |p |
339322 assure ( "Board package #{ p } has a defined URL" ) { board_package_url [ p ] }
340323 end
341324
342325 # set up all the board manager URLs.
343326 # we can safely reject nils now, they would be for the builtins
344- all_urls = all_packages . map { |p | board_package_url [ p ] } . uniq . reject ( &:nil? )
327+ all_urls = external_packages . map { |p | board_package_url [ p ] } . uniq . reject ( &:nil? )
345328
346329 unless all_urls . empty?
347330 assure ( "Setting board manager URLs" ) do
348- @arduino_backend . board_manager_urls = all_urls
331+ @backend . board_manager_urls = all_urls
349332 end
350333 end
351334
352- all_packages . each do |p |
335+ external_packages . each do |p |
353336 assure ( "Installing board package #{ p } " ) do
354- @arduino_backend . install_boards ( p )
337+ @backend . install_boards ( p )
355338 end
356339 end
357340
358- install_arduino_library_dependencies ( aux_libraries )
341+ install_arduino_library_dependencies ( aux_libraries , "<compile/libraries>" )
359342
360343 if config . platforms_to_build . empty?
361344 inform ( "Skipping builds" ) { "no platforms were requested" }
@@ -367,41 +350,51 @@ def perform_compilation_tests(config)
367350 return
368351 end
369352
370- # switching boards takes time, so iterate board first
371- # _then_ whichever examples match it
372- examples_by_platform = library_examples . each_with_object ( { } ) do |example_path , acc |
353+ library_examples . each do |example_path |
373354 ovr_config = config . from_example ( example_path )
374355 ovr_config . platforms_to_build . each do |p |
375- acc [ p ] = [ ] unless acc . key? ( p )
376- acc [ p ] << example_path
377- end
378- end
379-
380- examples_by_platform . each do |platform , example_paths |
381- board = example_platform_info [ platform ] [ :board ]
382- example_paths . each do |example_path |
356+ board = example_platform_info [ p ] [ :board ]
383357 example_name = File . basename ( example_path )
384358 attempt ( "Compiling #{ example_name } for #{ board } " ) do
385- ret = @arduino_backend . compile_sketch ( example_path , board )
359+ ret = @backend . compile_sketch ( example_path , board )
386360 unless ret
387361 puts
388- puts "Last command: #{ @arduino_backend . last_msg } "
389- puts @arduino_backend . last_err
362+ puts "Last command: #{ @backend . last_msg } "
363+ puts @backend . last_err
390364 end
391365 ret
392366 end
393367 end
394368 end
395-
396369end
397370
398371# initialize command and config
399372config = ArduinoCI ::CIConfig . default . from_project_library
400373
401- @arduino_backend = ArduinoCI ::ArduinoInstallation . autolocate!
402- inform ( "Located arduino-cli binary" ) { @arduino_backend . binary_path . to_s }
374+ @backend = ArduinoCI ::ArduinoInstallation . autolocate!
375+ inform ( "Located arduino-cli binary" ) { @backend . binary_path . to_s }
376+
377+ # initialize library under test
378+ cpp_library = assure ( "Installing library under test" ) do
379+ @backend . install_local_library ( Pathname . new ( "." ) )
380+ end
381+
382+ if !cpp_library . nil?
383+ inform ( "Library installed at" ) { cpp_library . path . to_s }
384+ else
385+ # this is a longwinded way of failing, we aren't really "assuring" anything at this point
386+ assure_multiline ( "Library installed successfully" ) do
387+ puts @backend . last_msg
388+ false
389+ end
390+ end
391+
392+ install_arduino_library_dependencies (
393+ cpp_library . arduino_library_dependencies ,
394+ "<#{ ArduinoCI ::CppLibrary ::LIBRARY_PROPERTIES_FILE } >"
395+ )
403396
404- perform_unit_tests ( config )
405- perform_compilation_tests ( config )
397+ perform_unit_tests ( cpp_library , config )
398+ perform_example_compilation_tests ( cpp_library , config )
406399
407400terminate ( true )
0 commit comments