$:.unshift File.expand_path('../lib', __FILE__) $:.unshift File.expand_path('../test', __FILE__) require 'bundler/gem_tasks' require 'rake/testtask' require 'yaml' require 'fileutils' require 'holidays' DEFINITION_PATH = 'definitions' DEFINITION_TESTS_PATH = 'test/defs' Rake::TestTask.new(:test) do |t| t.libs << 'test' t.test_files = FileList['test/**/test_*.rb'] end task :default => :test desc "Run tests for only a single region. Do not provide sub regions. Example (without quotes): 'rake test_region jp'" task :test_region do # Magic to define empty tasks on the fly so we have nicer arguments, see http://cobwwweb.com/4-ways-to-pass-arguments-to-a-rake-task ARGV.each { |a| task a.to_sym do ; end } if ARGV[1].nil? || ARGV[1].empty? raise ArgumentError.new("You must provide a region. Example (without quotes): 'rake test_region us'") end region = ARGV[1].downcase unless Holidays.available_regions.include?(region.to_sym) raise ArgumentError.new("Region '#{region}' not recognized") end unless File.file?("#{DEFINITION_TESTS_PATH}/test_defs_#{region}.rb") raise ArgumentError.new("Test file not found for region '#{region}'. Do not use sub regions, try the overall region instead. Example: 'us' instead of 'us_dc'") end sh "bundle exec ruby #{DEFINITION_TESTS_PATH}/test_defs_#{region}.rb" end desc 'Launch IRB session' task :console do sh "irb -r rubygems -I lib -r holidays.rb" end desc 'Generate definitions and tests used in main holiday logic based on raw YAML definitions' namespace :generate do desc 'Generate the holiday definition files' task :definitions do # load the index def_index = YAML.load_file("#{DEFINITION_PATH}/index.yaml") # create a dir for the generated tests FileUtils.mkdir_p(DEFINITION_TESTS_PATH) # TODO: This entire section should be moved into '/lib/holidays/definition'. I don't think such an # important part of the gem should be left in the Rakefile and without unit tests. There's no # reason we can't move it. all_regions = {} def_index['defs'].each do |region, files| puts "Building #{region} definition module:" files = files.collect { |f| "#{DEFINITION_PATH}/#{f}" }.uniq regions, rules_by_month, custom_methods, tests = Holidays::Factory::Definition.file_parser.parse_definition_files(files) module_src, test_src = Holidays::Factory::Definition.source_generator.generate_definition_source(region, files, regions, rules_by_month, custom_methods, tests) File.open("lib/#{Holidays::DEFINITIONS_PATH}/#{region.downcase.to_s}.rb","w") do |file| file.puts module_src end unless test_src.empty? File.open("#{DEFINITION_TESTS_PATH}/test_defs_#{region.downcase.to_s}.rb","w") do |file| file.puts test_src end end all_regions[region.downcase.to_sym] = regions puts "Done.\n\n" end puts "Building regions master file for later validation:" File.open("lib/#{Holidays::DEFINITIONS_PATH}/REGIONS.rb","w") do |file| file.puts Holidays::Factory::Definition.regions_generator.call(all_regions) end puts "Done.\n\n" end desc 'Build the definition manifest' task :manifest do File.open("lib/#{Holidays::DEFINITIONS_PATH}/MANIFEST","w") do |file| # TODO: Generating the file source should be done internally, in the /lib dir, not in the Rakefile file.puts <<-EOH ==== Regional definitions The following definition files are included in this installation: EOH FileList.new("lib/#{Holidays::DEFINITIONS_PATH}/*.rb").exclude(/version/).each do |str| file.puts('* ' + str.gsub(/^lib\/|\.rb$/, '')) end end puts "Updated manifest file." end end task :generate => ['generate:definitions', 'generate:manifest']