Rakefile 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. # Available options:
  2. #
  3. # rake test - Runs all test cases.
  4. # rake package - Runs test cases and builds packages for distribution.
  5. # rake rdoc - Builds API documentation in doc dir.
  6. # rake build_tz_modules - Builds Timezone modules and the Country index.
  7. # Expects to find source data in ../data.
  8. # rake build_tz_module zone=Zone/Name - Builds a single Timezone module.
  9. # Expects to find source data in ../data.
  10. # rake build_countries - Builds the Country index.
  11. # Expects to find source data in ../data.
  12. require 'rake'
  13. require 'rake/testtask'
  14. require 'rake/rdoctask'
  15. require 'rake/gempackagetask'
  16. require 'fileutils'
  17. Rake::TaskManager.class_eval do
  18. def remove_task(task_name)
  19. @tasks.delete(task_name.to_s)
  20. end
  21. end
  22. def remove_task(task_name)
  23. Rake.application.remove_task(task_name)
  24. end
  25. self.class.class_eval { alias_method :orig_sh, :sh }
  26. private :orig_sh
  27. def sh(*cmd, &block)
  28. if cmd.first =~ /\A__tar_with_owner__ -?([zjcvf]+)(.*)\z/
  29. opts = $1
  30. args = $2
  31. cmd[0] = "tar c --owner 0 --group 0 -#{opts.gsub('c', '')}#{args}"
  32. end
  33. orig_sh(*cmd, &block)
  34. end
  35. PKG_VERSION = "0.3.33"
  36. PKG_FILES = FileList[
  37. 'CHANGES',
  38. 'LICENSE',
  39. 'Rakefile',
  40. 'README',
  41. 'lib',
  42. 'lib/**/*'
  43. ].delete_if {|f| f.include?('.svn')}
  44. PKG_TEST_FILES = FileList['test', 'test/**/*'].delete_if {|f| f.include?('.svn')}
  45. RDOC_OPTIONS = %w[--exclude definitions --exclude indexes]
  46. RDOC_EXTRA_FILES = %w[README CHANGES]
  47. BUILD_TZ_CLASSES_DIR = 'lib/tzinfo.build_tz_classes'
  48. SPEC = Gem::Specification.new do |s|
  49. s.name = "tzinfo"
  50. s.version = PKG_VERSION
  51. s.author = "Philip Ross"
  52. s.email = "phil.ross@gmail.com"
  53. s.homepage = "http://tzinfo.rubyforge.org/"
  54. s.platform = Gem::Platform::RUBY
  55. s.summary = "Daylight-savings aware timezone library"
  56. s.description = "TZInfo is a Ruby library that uses the standard tz (Olson) database to provide daylight savings aware transformations between times in different time zones."
  57. s.files = PKG_FILES
  58. s.test_files = PKG_TEST_FILES
  59. s.require_path = "lib"
  60. s.has_rdoc = true
  61. s.extra_rdoc_files = RDOC_EXTRA_FILES
  62. s.rdoc_options = RDOC_OPTIONS
  63. s.rubyforge_project = "tzinfo"
  64. end
  65. package_task = Rake::GemPackageTask.new(SPEC) do |pkg|
  66. pkg.need_zip = true
  67. pkg.need_tar_gz = true
  68. pkg.tar_command = '__tar_with_owner__'
  69. end
  70. # Replace the Rake::PackageTask task that prepares the files to package with
  71. # a version that ensures the permissions are correct for the package.
  72. # Also just copy rather than link the files so that old versions are maintained.
  73. remove_task package_task.package_dir_path
  74. file package_task.package_dir_path => [package_task.package_dir] + package_task.package_files do
  75. mkdir_p package_task.package_dir_path rescue nil
  76. chmod(0755, package_task.package_dir_path)
  77. package_task.package_files.each do |fn|
  78. f = File.join(package_task.package_dir_path, fn)
  79. fdir = File.dirname(f)
  80. mkdir_p(fdir) if !File.exist?(fdir)
  81. if File.directory?(fn)
  82. mkdir_p(f)
  83. chmod(0755, f)
  84. else
  85. rm_f f
  86. cp(fn, f)
  87. chmod(0644, f)
  88. end
  89. end
  90. end
  91. # Replace the Rake::GemPackageTask task that builds the gem with a version that
  92. # changes to the copied package directory first. This allows the gem builder
  93. # to pick up the correct file permissions.
  94. remove_task "#{package_task.package_dir}/#{package_task.gem_file}"
  95. file "#{package_task.package_dir}/#{package_task.gem_file}" => [package_task.package_dir] + package_task.gem_spec.files do
  96. when_writing("Creating GEM") do
  97. chdir(package_task.package_dir_path) do
  98. Gem::Builder.new(package_task.gem_spec).build
  99. end
  100. verbose(true) do
  101. mv File.join(package_task.package_dir_path, package_task.gem_file), "#{package_task.package_dir}/#{package_task.gem_file}"
  102. end
  103. end
  104. end
  105. Rake::TestTask.new('test') do |t|
  106. # Force a particular timezone to be local (helps find issues when local
  107. # timezone isn't GMT). This won't work on Windows.
  108. ENV['TZ'] = 'America/Los_Angeles'
  109. t.libs << '.'
  110. t.pattern = 'test/tc_*.rb'
  111. t.verbose = true
  112. end
  113. Rake::RDocTask.new do |rdoc|
  114. rdoc.rdoc_dir = 'doc'
  115. rdoc.title = "TZInfo"
  116. rdoc.options << '--inline-source'
  117. rdoc.options.concat RDOC_OPTIONS
  118. rdoc.rdoc_files.include(*RDOC_EXTRA_FILES)
  119. rdoc.rdoc_files.include('lib')
  120. end
  121. task :build_tz_modules do
  122. require 'lib/tzinfo/tzdataparser'
  123. FileUtils.mkdir_p(BUILD_TZ_CLASSES_DIR)
  124. begin
  125. p = TZInfo::TZDataParser.new('../data', BUILD_TZ_CLASSES_DIR)
  126. p.execute
  127. ['indexes', 'definitions'].each {|dir|
  128. sync_svn("#{BUILD_TZ_CLASSES_DIR}/#{dir}", "lib/tzinfo/#{dir}")
  129. }
  130. ensure
  131. FileUtils.rm_rf(BUILD_TZ_CLASSES_DIR)
  132. end
  133. end
  134. def sync_svn(source_dir, target_dir)
  135. puts "SVN Sync from #{source_dir} to #{target_dir}"
  136. # Assumes a directory will never turn into a file and vice-versa
  137. # (files will all end in .rb, directories won't).
  138. # SVN wouldn't allow the change in a single commit anyway.
  139. source_entries, target_entries = [source_dir, target_dir].collect {|dir|
  140. Dir.entries(dir).delete_if {|entry| entry =~ /^\.(\.?|svn)$/}.sort
  141. }
  142. until source_entries.empty? || target_entries.empty?
  143. if source_entries.last == target_entries.last
  144. source_file = "#{source_dir}/#{source_entries.last}"
  145. target_file = "#{target_dir}/#{target_entries.last}"
  146. if File.directory?(source_file)
  147. sync_svn(source_file, target_file)
  148. else
  149. FileUtils.cp(source_file, target_file)
  150. end
  151. source_entries.pop
  152. target_entries.pop
  153. elsif source_entries.last < target_entries.last
  154. sync_svn_only_in_target(target_dir, target_entries)
  155. else
  156. sync_svn_only_in_source(source_dir, target_dir, source_entries)
  157. end
  158. end
  159. until target_entries.empty?
  160. sync_svn_only_in_target(target_dir, target_entries)
  161. end
  162. until source_entries.empty?
  163. sync_svn_only_in_source(source_dir, target_dir, source_entries)
  164. end
  165. end
  166. def sync_svn_only_in_target(target_dir, target_entries)
  167. target_file = "#{target_dir}/#{target_entries.last}"
  168. exec_svn "delete \"#{target_file}\""
  169. target_entries.pop
  170. end
  171. def sync_svn_only_in_source(source_dir, target_dir, source_entries)
  172. source_file = "#{source_dir}/#{source_entries.last}"
  173. target_file = "#{target_dir}/#{source_entries.last}"
  174. if File.directory?(source_file)
  175. Dir.mkdir(target_file)
  176. exec_svn "add \"#{target_file}\""
  177. sync_svn(source_file, target_file)
  178. else
  179. FileUtils.cp(source_file, target_file)
  180. exec_svn "add \"#{target_file}\""
  181. end
  182. source_entries.pop
  183. end
  184. def exec_svn(params)
  185. puts "svn #{params}"
  186. `svn #{params}`
  187. raise "SVN exited with status #$?" if $? != 0
  188. end
  189. task :build_tz_module do
  190. require 'lib/tzinfo/tzdataparser'
  191. p = TZInfo::TZDataParser.new('../data', 'lib/tzinfo')
  192. p.generate_countries = false
  193. p.only_zones = [ENV['zone']]
  194. p.execute
  195. end
  196. task :build_countries do
  197. require 'lib/tzinfo/tzdataparser'
  198. p = TZInfo::TZDataParser.new('../data', 'lib/tzinfo')
  199. p.generate_countries = true
  200. p.generate_zones = false
  201. p.execute
  202. end