require "scaffolding" require "scaffolding/file_manipulator" namespace :bullet_train do namespace :api do desc "Bump the current version of application's API" task :bump_version do # Calculate new version. initializer_content = File.new("config/initializers/api.rb").readline previous_version = initializer_content.scan(/v\d+/).pop new_version_int = previous_version.scan(/\d+/).pop.to_i + 1 new_version = "v#{new_version_int}" # Update initializer. File.write("config/initializers/api.rb", initializer_content.gsub(previous_version, new_version)) [ "app/controllers/api/#{new_version}", "app/views/api/#{new_version}", "test/controllers/api/#{new_version}" ].each do |dir| Dir.mkdir(dir) end files_to_update = [ "config/routes/api/#{previous_version}.rb", Dir.glob("app/controllers/api/#{previous_version}/**/*.rb") + Dir.glob("app/views/api/#{previous_version}/**/*.json.jbuilder") + Dir.glob("test/controllers/api/#{previous_version}/**/*.rb") ].flatten files_to_update.each do |file_name| previous_file_contents = File.open(file_name).readlines new_file_name = file_name.gsub(previous_version, new_version) updated_file_contents = previous_file_contents.map do |line| if line.match?(previous_version) line.gsub(previous_version, new_version) else line.gsub("Api::#{previous_version.upcase}", "Api::#{new_version.upcase}") end end # We can't create new files unless each directory under #{api/previous_version} # has been created under the new api directory. For example, we have to create # the `projects` directory before we can create the file `api/v2/projects/pages.json.jbuilder.` new_version_dir, dir_hierarchy = new_file_name.split(/(?<=#{new_version})\//) if dir_hierarchy.present? && dir_hierarchy.match?("/") dir_hierarchy = dir_hierarchy.split("/") dir_hierarchy.inject(new_version_dir) do |base, child_dir_or_file| # Stop making new directories if the string has an extention like ".rb" break if child_dir_or_file.match?(/\./) new_hierarchy = "#{base}/#{child_dir_or_file}" Dir.mkdir(new_hierarchy) unless Dir.exist?(new_hierarchy) new_hierarchy end end Scaffolding::FileManipulator.write(new_file_name, updated_file_contents) end # Here we make sure config/api/#{new_version}.rb is called from within the main routes file. previous_file_contents = File.open("config/routes.rb").readlines updated_file_contents = previous_file_contents.map do |line| if line.match?("draw \"api/#{previous_version}\"") new_version_draw_line = line.gsub(previous_version, new_version) line + new_version_draw_line else line end end Scaffolding::FileManipulator.write("config/routes.rb", updated_file_contents) # Update application locale for each locale that exists. I18n.available_locales.each do |lang| file = "config/locales/#{lang}/application.#{lang}.yml" transformer = Scaffolding::Transformer.new("", "") if File.exist?(file) transformer.add_line_to_file( file, "#{new_version_int}: #{new_version.upcase}", Scaffolding::Transformer::RUBY_NEW_API_VERSION_HOOK, prepend: true ) end end puts "Finished bumping to #{new_version}" end end end