<commit_before>require "backto/version"
require "backto/config"
require "backto/scanner"
require "fileutils"

module Backto

  class Execute

    def initialize(config)
      config = Config.new(config) unless config.is_a? Config
      @config = config
      @back_files = {}
      @scanner = Scanner.new(from_path, @config[:exclude_patterns], @config[:link_directory])
    end

    def run
      @scanner.each do |path, is_dir, is_recursive|
        if is_dir && is_recursive
          mkdirs to_path(path), verbose: @config[:verbose]
        else
          args = [
            from_path(path),
            to_path(path),
            {
              verbose: @config[:verbose],
              force: @config[:force],
            }
          ]
          if @config[:hardlink] && !is_dir
            hardlink *args
          else
            softlink *args
          end
        end
      end
      clean_link
    end

    def hardlink(source, target, opts)
      begin
        FileUtils.ln source, target, opts
      rescue Errno::EEXIST
        raise unless hardlink? target, source
      end
      notify(source, target, 'hardlink')
    end

    def softlink(source, target, opts)
      unless softlink? target, source
        if File.directory?(target) && File.directory?(source)
          FileUtils.rm_r target, opts if opts[:force]
          FileUtils.ln_s source, File.dirname(target), opts
        else
          FileUtils.ln_s source, target, opts
        end
      end
      notify(source, target, 'softlink')
    end

    def mkdirs(path, opts = {})
      FileUtils.mkdir_p path, opts unless File.exist? path
    end

    def from_path(path='.')
      File.expand_path File.join(@config[:from], path)
    end

    def to_path(path='.')<commit_msg> 使用 Path 类获取原路径和目标路径<commit_after>require "backto/version"
require "backto/config"
require "backto/scanner"
require "fileutils"

module Backto

  class Path

    def initialize(config, path)
      @config = config
      @path = path
    end

    def target
      File.expand_path File.join(@config[:to], @path)
    end

    def source
      File.expand_path File.join(@config[:from], @path)
    end

  end

  class Execute

    def initialize(config)
      config = Config.new(config) unless config.is_a? Config
      @config = config
      @back_files = {}
      @scanner = Scanner.new(from_path, @config[:exclude_patterns], @config[:link_directory])
    end

    def run
      link_opts = {verbose: @config[:verbose], force: @config[:force]}
      @scanner.each do |path, is_dir, is_recursive|
        path = Path.new(@config, path)
        if is_dir && is_recursive
          mkdirs path.target, verbose: @config[:verbose]
        else
          @config[:hardlink] && !is_dir ? hardlink(path, link_opts) : softlink(path, link_opts)
        end
      end
      clean_link
    end

    def hardlink(path, opts)
      begin
        FileUtils.ln path.source, path.target, opts
      rescue Errno::EEXIST
        raise unless hardlink? path.target, path.source
      end
      notify(path.source, path.target, 'hardlink')
    end

    def softlink(path, opts)
      unless softlink? path.target, path.source
        if File.directory?(path.target) && File.directory?(path.source)
          FileUtils.rm_r path.target, opts if opts[:force]
          FileUtils.ln_s path.source, File.dirname(path.target), opts
        else
          FileUtils.ln_s path.source, path.target, opts
        end
      end
      notify(path.source, path.target, 'softlink')
    end

    def mkdirs(path, opts = {})
      FileUtils.mkdir_p path, opts unless File.exist? path
    end

    def from_path(path='.')
      File.expand_path File.join(@config[:from], path)
    end

    def to_path(path='.')
{'fraction_non_alphanumeric': 0.10557341907824223, 'fraction_numerical': 0.0, 'mean_word_length': 2.2860915492957745, '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': '5164856', 'n_tokens_mistral': 1170, 'n_tokens_neox': 1145, 'n_words': 285}