#!/usr/bin/env ruby ROOT = File.expand_path('..', __dir__) LIBS = %w[ admin api backend core sample legacy_promotions ] # Ignore line info, e.g. foo/bar.rb:123 would become foo/bar.rb without_line = ->(path) { path.split(':', 2).first } # Is it a spec file or a CLI option? is_spec = ->(path) { File.directory?(path) ? path.include?('/spec') : without_line[path].end_with?('_spec.rb') } # Find the Solidus library for this path find_lib = ->(path) { path = without_line[path] LIBS.find { |lib| path.start_with? File.join(ROOT, lib) +'/' } } # Let all paths be absolute, if the file is missing try prepending one of the LIBS, # this allows calling `bin/rspec spec/api/foo/bar_spec.rb` without needing to add # the api/ prefix. expand_existing = ->(path) { [ File.expand_path(path), *LIBS.map { |l| File.expand_path(path, l) } ].find { |p| File.exist?(without_line[p]) } } spec_files, options = ARGV.partition(&is_spec) # Separate specs and options specs = {} if spec_files.any? specs = spec_files.map do |f| expand_existing[f] or abort "Couldn't find spec file: #{f.inspect}" end.group_by(&find_lib) else # If no files are provided run all specs in each lib. LIBS.each { |lib| specs[lib] = [] } end # Run specs for each lib separately specs.each do |lib, files| Dir.chdir(lib) do command = ['bundle', 'exec', 'rspec', *options, *files] warn "$ cd #{lib}; #{command.join(' ')}; cd -" system *command exit $?.exitstatus unless $?.success? end end