<commit_before>module Teeplate
  abstract class FileTree
    DIFF = `which diff`.strip
    GIT = `which git`.strip
    PROMPT = "overwrite(o)/keep(k)/diff(d)/overwrite all(a)/keep all(n) ? "

    macro directory(dir)
      {{ run(__DIR__ + "/file_tree/macros/directory", dir.id) }}
    end

    class Rendering
      class Entry
        alias Sliceable = Bytes | MemoryIO

        @rendering : Rendering
        @local_path : String
        @sliceable : Sliceable

        def initialize(@rendering, @local_path, @sliceable)
        end

        @slice : Slice(UInt8)?
        def slice
          @slice ||= @sliceable.to_slice
        end

        @out_path : String?
        def out_path
          @out_path ||= File.join(@rendering.out_dir, @local_path).tap do |path|
            Dir.mkdir_p path.split("/")[0..-2].join("/")
          end
        end

        def render
          return if File.exists?(out_path) && !overwrites?
          File.open(out_path, "w") do |f|
            f.write slice
          end
        end

        def overwrites?
          return false unless changed?
          return true if @rendering.forces? || @rendering.overwrite_all?
          !@rendering.keep_all? && @rendering.interactive? && confirm_overwriting
        end

        def changed?
          return true if File.size(out_path) != slice.size
          File.open(out_path) do |f|
            (0...(slice.size)).each do |i|
              return true if f.read_byte != slice[i]
            end
          end
          false
        end

        def confirm_overwriting
          STDOUT.puts "#{@local_path} already exists..."
          loop do
            STDOUT.print PROMPT
            STDOUT.flush
            case input = ::STDIN.gets.to_s.strip.downcase
            when "o"
              return true
            when "k"
              return false
            when "d"
              diff
            when "a"
              @rendering.overwrite_all!
              return true
            when "n"
              @rendering.keep_all!<commit_msg>always overwrite if forced<commit_after>module Teeplate
  abstract class FileTree
    DIFF = `which diff`.strip
    GIT = `which git`.strip
    PROMPT = "overwrite(o)/keep(k)/diff(d)/overwrite all(a)/keep all(n) ? "

    macro directory(dir)
      {{ run(__DIR__ + "/file_tree/macros/directory", dir.id) }}
    end

    class Rendering
      class Entry
        alias Sliceable = Bytes | MemoryIO

        @rendering : Rendering
        @local_path : String
        @sliceable : Sliceable

        def initialize(@rendering, @local_path, @sliceable)
        end

        @slice : Slice(UInt8)?
        def slice
          @slice ||= @sliceable.to_slice
        end

        @out_path : String?
        def out_path
          @out_path ||= File.join(@rendering.out_dir, @local_path).tap do |path|
            Dir.mkdir_p path.split("/")[0..-2].join("/")
          end
        end

        def render
          return if File.exists?(out_path) && !overwrites?
          File.open(out_path, "w") do |f|
            f.write slice
          end
        end

        def overwrites?
          return true if @rendering.forces? || @rendering.overwrite_all?
          return false unless changed?
          !@rendering.keep_all? && @rendering.interactive? && confirm_overwriting
        end

        def changed?
          return true if File.size(out_path) != slice.size
          File.open(out_path) do |f|
            (0...(slice.size)).each do |i|
              return true if f.read_byte != slice[i]
            end
          end
          false
        end

        def confirm_overwriting
          STDOUT.puts "#{@local_path} already exists..."
          loop do
            STDOUT.print PROMPT
            STDOUT.flush
            case input = ::STDIN.gets.to_s.strip.downcase
            when "o"
              return true
            when "k"
              return false
            when "d"
              diff
            when "a"
              @rendering.overwrite_all!
              return true
            when "n"
              @rendering.keep_all!
{'fraction_non_alphanumeric': 0.10104954845008543, 'fraction_numerical': 0.001952648279228704, 'mean_word_length': 1.526510480887793, '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': '7082996', 'n_tokens_mistral': 1227, 'n_tokens_neox': 1185, 'n_words': 290}