# Author:: Tyler Rick # Copyright:: Copyright (c) 2007 QualitySmith, Inc. # License:: Ruby License # Submit to Facets?:: Yes require 'rubygems' require 'facets/more/filelist' require 'facets/core/kernel/require_local' require_local '../file/exact_match_regexp' module Kernel # Recursively requires all Ruby files in base_dir or any of its subdirectories. # :exclude: An array of regular expressions or glob patterns that will be passed to FileList#exclude. If you specify this option, a file will not be included if it matches *any* of these patterns. # :exclude_files: An array of filenames to exclude. These will be matched exactly, so if you tell it to exclude 'bar.rb', 'foobar.rb' will _not_ be excluded. # # Note: # # Examples: # require_all 'lib/', :exclude => [/ignore/, /bogus/] # will require 'lib/a.rb', 'lib/long/path/b.rb', but not 'lib/ignore/c.rb' # require_all File.dirname(__FILE__), :exclude_files => ['blow_up_stuff.rb'] def require_all(base_dir, options = {}) base_dir += '/' unless base_dir[-1].chr == '/' exclusions = nil files = FileList[base_dir + "**/*.rb"] files = files.exclude(*exclusions) if (exclusions = options.delete(:exclude)) files = files.exclude(*exclusions.map {|a| File.exact_match_regexp(a) }) if (exclusions = options.delete(:exclude_files)) files.each do |filename| # puts "requiring #{filename}" if filename =~ /test/ require filename end end end # _____ _ # |_ _|__ ___| |_ # | |/ _ \/ __| __| # | | __/\__ \ |_ # |_|\___||___/\__| # =begin test require 'tmpdir' require 'fileutils' class TheTest < Test::Unit::TestCase def setup @main_subdir = 'require_all_test' @base_dir = "#{Dir.tmpdir}/#{@main_subdir}" FileUtils.mkdir @base_dir FileUtils.mkdir_p @deep_dir = @base_dir + "/really/really/deep/subdir" $loaded = Array.new(2) end def teardown FileUtils.rm_rf @base_dir end def test_repeat_requires $loaded[0] = 0 File.open("#{@base_dir}/moo.rb", "w") {|f| f.puts "$loaded[0] += 1"} require_all File.dirname(@base_dir) assert_equal [1, nil], $loaded require "#{@base_dir}/moo.rb" assert_equal [1, nil], $loaded # Good! It refuses to load it again, even if we drop the ".rb" part! require "#{@base_dir}/moo" assert_equal [1, nil], $loaded # But, we can still trick it! $LOAD_PATH << @base_dir require "moo" assert_equal [2, nil], $loaded load "moo.rb" assert_equal [3, nil], $loaded end def test_deep_subdir File.open("#{@base_dir}/flip.rb", "w") {|f| f.puts "$loaded[0] = true"} File.open("#{@deep_dir}/flop.rb", "w") {|f| f.puts "$loaded[1] = true"} require_all File.dirname(@base_dir) assert_equal [true, true], $loaded end def test_exclude_pattern File.open("#{@base_dir}/require_me.rb", "w") {|f| f.puts "$loaded[0] = true"} File.open("#{@base_dir}/please_ignore_me.rb", "w") {|f| f.puts "$loaded[1] = true"} require_all File.dirname(@base_dir), :exclude => [/ignore/] assert_equal [true, nil], $loaded end def test_exclude_filename File.open("#{@base_dir}/yes.rb", "w") {|f| f.puts "$loaded[0] = true"} File.open("#{@base_dir}/all.rb", "w") {|f| f.puts "$loaded[1] = true"} # :todo: Interesting how none of these patterns work. I would have expected them to. Is there a bug in FileList? Find out... # /usr/lib/ruby/gems/1.8/gems/facets-1.8.51/lib/facets/more/filelist.rb #require_all File.dirname(@base_dir), :exclude => ['all.rb'] #require_all File.dirname(@base_dir), :exclude => ['**/all'] #require_all File.dirname(@base_dir), :exclude => [/^all\.rb$/] # This works, but it's too much to expect users to type out!: #require_all File.dirname(@base_dir), :exclude => [/(\/|^)all\.rb$/] # So...... I added an :exclude_files option so that people wouldn't have to! require_all File.dirname(@base_dir), :exclude_files => ['all.rb'] assert_equal [true, nil], $loaded end end =end