<commit_before>require "active_support"
require "active_support/core_ext"
require "fileutils"

module Wolfe
  class Cleanup
    attr_accessor :configuration

    BACKUP_FIRST_CUTOFF_DATE = Date.today - 5.years

    def initialize(configuration)
      @configuration = configuration
      validate_configuration
    end

    def start
      configuration.each do |name, config|
        puts "-----------------------------------------------------"
        puts "Cleaning up backups: #{name}"
        puts "-----------------------------------------------------"

        cleanup( config )
      end
    end

    private

      #
      # validation
      #

      def validate_configuration
        raise ArgumentError.new("Configuration must be hash.") unless configuration.is_a? Hash
        configuration.each do |name, config|
          raise ArgumentError.new("Configuration keys for #{name} missing.") unless configuration_keys.all? { |k| config.key?(k) }
          raise ArgumentError.new("Invalid timespan argument for #{name}")   unless config['one_per_day_timespan'] =~ timespan_regex
          raise ArgumentError.new("Invalid timespan argument for #{name}")   unless config['one_per_month_timespan'] =~ timespan_regex
          raise ArgumentError.new("Path for #{name} does not exist.")        unless Dir.exist?(config['path'])
        end
      end

      def configuration_keys
        ['path', 'filename', 'one_per_day_timespan', 'one_per_month_timespan']
      end

      def timespan_regex
        /^\d+\.(days?|weeks?|months?|years?)$/
      end

      #
      # cleanup
      #

      def cleanup( config )
        daily_date = Date.today - eval(config['one_per_day_timespan'])
        monthly_date = calculate_monthly_date_for_backup_to_keep(config['one_per_month_timespan'])
        keep_one = !one_per_month_timespan_starts_with_zero?(config['one_per_month_timespan'])

        if File.directory?(config['path'])
          clean_monthly(monthly_date, daily_date, config, keep_one)
          clean_yearly(monthly_date, config, keep_one) if keep_one
        else
          puts "Path '#{config['path']}' is not a directory."
        end
      end

      def calculate_monthly_date_for_backup_to_keep(one_per_month_timespan)
        timespan_digit = one_per_month_timespan.split('.')[0].to_i
        timespan_word = one_per_month_timespan.split('.')[1].to_sym

        if Date.today - timespan_digit.send(timespan_word) == Date.today
          BACKUP_FIRST_CUTOFF_DATE
        else
          Date.today - timespan_digit.send(timespan_word)
        end
      end

      def one_per_month_timespan_starts_with_zero?(timespan)
        timespan.first.to_i == 0 ? true : false
      end

      def clean_monthly(monthly_date, daily_date, config, keep_one)
        monthly_date.upto(daily_date) do |date|
          delete_monthly(config['path'], config['filename'], date, keep_one)
        end
      end

      def clean_yearly(monthly_date, config, keep_one)<commit_msg>the boolean expression returns a boolean result (no need to return 'true' or 'false' explicitly)<commit_after>require "active_support"
require "active_support/core_ext"
require "fileutils"

module Wolfe
  class Cleanup
    attr_accessor :configuration

    BACKUP_FIRST_CUTOFF_DATE = Date.today - 5.years

    def initialize(configuration)
      @configuration = configuration
      validate_configuration
    end

    def start
      configuration.each do |name, config|
        puts "-----------------------------------------------------"
        puts "Cleaning up backups: #{name}"
        puts "-----------------------------------------------------"

        cleanup( config )
      end
    end

    private

      #
      # validation
      #

      def validate_configuration
        raise ArgumentError.new("Configuration must be hash.") unless configuration.is_a? Hash
        configuration.each do |name, config|
          raise ArgumentError.new("Configuration keys for #{name} missing.") unless configuration_keys.all? { |k| config.key?(k) }
          raise ArgumentError.new("Invalid timespan argument for #{name}")   unless config['one_per_day_timespan'] =~ timespan_regex
          raise ArgumentError.new("Invalid timespan argument for #{name}")   unless config['one_per_month_timespan'] =~ timespan_regex
          raise ArgumentError.new("Path for #{name} does not exist.")        unless Dir.exist?(config['path'])
        end
      end

      def configuration_keys
        ['path', 'filename', 'one_per_day_timespan', 'one_per_month_timespan']
      end

      def timespan_regex
        /^\d+\.(days?|weeks?|months?|years?)$/
      end

      #
      # cleanup
      #

      def cleanup( config )
        daily_date = Date.today - eval(config['one_per_day_timespan'])
        monthly_date = calculate_monthly_date_for_backup_to_keep(config['one_per_month_timespan'])
        keep_one = !one_per_month_timespan_starts_with_zero?(config['one_per_month_timespan'])

        if File.directory?(config['path'])
          clean_monthly(monthly_date, daily_date, config, keep_one)
          clean_yearly(monthly_date, config, keep_one) if keep_one
        else
          puts "Path '#{config['path']}' is not a directory."
        end
      end

      def calculate_monthly_date_for_backup_to_keep(one_per_month_timespan)
        timespan_digit = one_per_month_timespan.split('.')[0].to_i
        timespan_word = one_per_month_timespan.split('.')[1].to_sym

        if Date.today - timespan_digit.send(timespan_word) == Date.today
          BACKUP_FIRST_CUTOFF_DATE
        else
          Date.today - timespan_digit.send(timespan_word)
        end
      end

      def one_per_month_timespan_starts_with_zero?(timespan)
        timespan.first.to_i == 0
      end

      def clean_monthly(monthly_date, daily_date, config, keep_one)
        monthly_date.upto(daily_date) do |date|
          delete_monthly(config['path'], config['filename'], date, keep_one)
        end
      end

      def clean_yearly(monthly_date, config, keep_one)
{'fraction_non_alphanumeric': 0.12669983416252073, 'fraction_numerical': 0.0013266998341625207, 'mean_word_length': 2.5372434017595307, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5483389', 'n_tokens_mistral': 1785, 'n_tokens_neox': 1736, 'n_words': 365}