<commit_before>class Shrine
  module Plugins
    module KeepFiles
      def self.configure(uploader, destroyed: nil, replaced: nil, cached: nil)
        uploader.opts[:keep_files] = []
        uploader.opts[:keep_files] << :destroyed if destroyed
        uploader.opts[:keep_files] << :replaced if replaced
        uploader.opts[:keep_files] << :cached if cached
      end

      module ClassMethods
        def keep?(type)
          opts[:keep_files].include?(type)
        end

        def delete(io, context)
          case context[:phase]
          when :promote then super unless keep?(:cached)
          when :replace then super unless keep?(:replaced)
          when :destroy then super unless keep?(:destroyed)
          else
            super
          end
        end
      end
    end

    register_plugin(:keep_files, KeepFiles)
  end
end<commit_msg>Document keep_files plugin<commit_after>class Shrine
  module Plugins
    # The keep_files plugin allows you to prevent files from being deleted.
    #
    #     plugin :keep_files
    #
    # This functionality is useful when implementing soft deletes, or when
    # implementing some kind of [event store] where you need to track history.
    # The plugin accepts the following options:
    #
    # :destroyed
    # :  If set to `true`, destroying the record won't delete the associated
    #    attachment.
    #
    # :replaced
    # :  If set to `true`, uploading a new attachment won't delete the old one.
    #
    # :cached
    # :  If set to `true`, cached files that are uploaded to store won't be
    #    deleted.
    #
    # [event store]: http://docs.geteventstore.com/introduction/event-sourcing-basics/
    module KeepFiles
      def self.configure(uploader, destroyed: nil, replaced: nil, cached: nil)
        uploader.opts[:keep_files] = []
        uploader.opts[:keep_files] << :destroyed if destroyed
        uploader.opts[:keep_files] << :replaced if replaced
        uploader.opts[:keep_files] << :cached if cached
      end

      module ClassMethods
        def keep?(type)
          opts[:keep_files].include?(type)
        end

        # We hook to the generic deleting, and check the appropriate phases.
        def delete(io, context)
          case context[:phase]
          when :promote then super unless keep?(:cached)
          when :replace then super unless keep?(:replaced)
          when :destroy then super unless keep?(:destroyed)
          else
            super
          end
        end
      end
    end

    register_plugin(:keep_files, KeepFiles)
  end
end
{'fraction_non_alphanumeric': 0.08349590323839251, 'fraction_numerical': 0.0, 'mean_word_length': 2.321243523316062, 'pattern_counts': {'":': 0, '<': 15, '<?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': '7036648', 'n_tokens_mistral': 707, 'n_tokens_neox': 690, 'n_words': 232}