#-- # 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' require 'English' class TheTest < Test::Unit::TestCase def setup @base_dir = "#{Dir.tmpdir}/require_all_test" FileUtils.mkdir @base_dir @deep_dir = "really/really/deep/subdir" $loaded = [] end def teardown FileUtils.rm_rf @base_dir end def test_repeat_requires create_ruby_file 'moo.rb' require_all File.dirname(@base_dir) assert_equal ['moo.rb'], $loaded require "#{@base_dir}/moo.rb" assert_equal ['moo.rb'], $loaded # Good! It refuses to load it again, even if we drop the ".rb" part! require "#{@base_dir}/moo" assert_equal ['moo.rb'], $loaded # But, we can still trick it! $LOAD_PATH << @base_dir require "moo" assert_equal ['moo.rb', 'moo.rb'], $loaded load "moo.rb" assert_equal ['moo.rb', 'moo.rb', 'moo.rb'], $loaded end def test_deep_subdir create_ruby_file 'flip.rb' create_ruby_file @deep_dir + "/flop.rb" require_all File.dirname(@base_dir) assert_equal ['flip.rb', @deep_dir + "/flop.rb"], $loaded end def test_exclude_pattern create_ruby_file 'require_me.rb' create_ruby_file 'please_ignore_me.rb' require_all File.dirname(@base_dir), :exclude => [/ignore/] assert_equal ['require_me.rb'], $loaded end def test_exclude_pattern_with_directory create_ruby_file 'subdir/test/assert_even.rb' create_ruby_file 'subdir/test/assert_odd.rb' require_all File.dirname(@base_dir), :exclude => [/[^|\/]test/] assert_equal [], $loaded end def test_exclude_filename create_ruby_file 'yes.rb' create_ruby_file 'all.rb' # :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 ['yes.rb'], $loaded end def create_ruby_file(file_name) if file_name =~ /(.*)\// FileUtils.mkdir_p @base_dir + '/' + $1 end File.open(@base_dir + '/' + file_name, "w") {|f| f.puts "$loaded << '#{file_name}'"} end end =end