diff --git a/lib/tasks/add_new_year_to_questions.rake b/lib/tasks/add_new_year_to_questions.rake new file mode 100644 index 000000000..55f1abbf3 --- /dev/null +++ b/lib/tasks/add_new_year_to_questions.rake @@ -0,0 +1,55 @@ +require "pathname" + +desc "Add a new year to all lettings question number hashes and saves the new code. +Usage: bundle exec rake add_new_year_to_questions[new_year,log_type]. +Example: bundle exec rake add_new_year_to_questions[2027,lettings]. +This rake should only be run as part of local development at the start of new collection year creation. +Make sure your working tree is clean before running this, it will update each question file in place. +Note that this will only update questions with a QUESTION_NUMBER_FROM_YEAR hash set. +Some questions (such as any of the per person questions) which define custom question logic will need manual review. +Params: +- new_year: the year to add, e.g. 2025 +- log_type: the type of log to update. can be lettings or sales" +task :add_new_year_to_questions, %i[new_year log_type] => :environment do |_task, args| + new_year = args[:new_year].to_i + previous_year = new_year - 1 + + root = Pathname.new("app/models/form/#{args[:log_type]}/questions") + files = root.glob("*.rb") + + hash_re = /QUESTION_NUMBER_FROM_YEAR\s*=\s*\{([^}]*)}\.freeze/m + + changed = [] + + files.each do |path| + text = path.read + next unless text.include?("QUESTION_NUMBER_FROM_YEAR") + + match = hash_re.match(text) + next unless match + + body = match[1] + pairs = body.scan(/(\d+)\s*=>\s*(\d+)/) + next if pairs.empty? + + year_to_num = pairs.to_h { |y, n| [y.to_i, n.to_i] } + next if year_to_num.key?(new_year) + next unless year_to_num.key?(previous_year) + + year_to_num[new_year] = year_to_num[previous_year] + + items = year_to_num.keys.sort.map { |y| "#{y} => #{year_to_num[y]}" }.join(", ") + replacement = "QUESTION_NUMBER_FROM_YEAR = { #{items} }.freeze" + + new_text = text.sub(hash_re, replacement) + + next if new_text == text + + path.write(new_text) + changed << path + end + + puts "changed #{changed.length}" + changed.each { |p| puts p } +end +