dotsync 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.github/workflows/gem-push.yml +4 -0
 - data/.rubocop.yml +353 -0
 - data/CHANGELOG.md +19 -9
 - data/Gemfile +0 -7
 - data/Gemfile.lock +20 -1
 - data/README.md +1 -1
 - data/Rakefile +4 -2
 - data/dotsync.gemspec +8 -1
 - data/exe/console +1 -0
 - data/exe/dotsync +4 -4
 - data/lib/dotsync/actions/base_action.rb +2 -0
 - data/lib/dotsync/actions/concerns/mappings_transfer.rb +18 -1
 - data/lib/dotsync/actions/pull_action.rb +19 -15
 - data/lib/dotsync/actions/push_action.rb +10 -8
 - data/lib/dotsync/actions/watch_action.rb +2 -1
 - data/lib/dotsync/colors.rb +37 -0
 - data/lib/dotsync/{actions/config → config}/base_config.rb +2 -1
 - data/lib/dotsync/{actions/config → config}/pull_action_config.rb +3 -2
 - data/lib/dotsync/{actions/config → config}/push_action_config.rb +3 -2
 - data/lib/dotsync/{actions/config → config}/watch_action_config.rb +2 -2
 - data/lib/dotsync/{actions/config → config}/xdg_base_directory_spec.rb +2 -0
 - data/lib/dotsync/errors.rb +3 -0
 - data/lib/dotsync/icons.rb +3 -1
 - data/lib/dotsync/models/diff.rb +18 -0
 - data/lib/dotsync/{actions/config/mapping_entry.rb → models/mapping.rb} +25 -13
 - data/lib/dotsync/runner.rb +37 -32
 - data/lib/dotsync/tasks/actions.rake +3 -1
 - data/lib/dotsync/utils/directory_differ.rb +111 -0
 - data/lib/dotsync/utils/file_transfer.rb +57 -0
 - data/lib/dotsync/{logger.rb → utils/logger.rb} +2 -0
 - data/lib/dotsync/{path_utils.rb → utils/path_utils.rb} +4 -2
 - data/lib/dotsync/version.rb +3 -1
 - data/lib/dotsync.rb +30 -26
 - metadata +85 -11
 - data/lib/dotsync/file_transfer.rb +0 -49
 
| 
         @@ -1,22 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Dotsync
         
     | 
| 
       2 
4 
     | 
    
         
             
              class PushAction < BaseAction
         
     | 
| 
       3 
5 
     | 
    
         
             
                include MappingsTransfer
         
     | 
| 
       4 
6 
     | 
    
         | 
| 
       5 
7 
     | 
    
         
             
                def execute
         
     | 
| 
       6 
8 
     | 
    
         
             
                  show_config
         
     | 
| 
      
 9 
     | 
    
         
            +
                  show_changes
         
     | 
| 
       7 
10 
     | 
    
         
             
                  push_dotfiles
         
     | 
| 
       8 
11 
     | 
    
         
             
                end
         
     | 
| 
       9 
12 
     | 
    
         | 
| 
       10 
13 
     | 
    
         
             
                private
         
     | 
| 
      
 14 
     | 
    
         
            +
                  def show_config
         
     | 
| 
      
 15 
     | 
    
         
            +
                    show_mappings
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
       11 
17 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                end
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
                def push_dotfiles
         
     | 
| 
       17 
     | 
    
         
            -
                  transfer_mappings
         
     | 
| 
      
 18 
     | 
    
         
            +
                  def push_dotfiles
         
     | 
| 
      
 19 
     | 
    
         
            +
                    transfer_mappings
         
     | 
| 
       18 
20 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
      
 21 
     | 
    
         
            +
                    action("Dotfiles pushed", icon: :copy)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
       21 
23 
     | 
    
         
             
              end
         
     | 
| 
       22 
24 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Dotsync
         
     | 
| 
       2 
4 
     | 
    
         
             
              class WatchAction < BaseAction
         
     | 
| 
       3 
5 
     | 
    
         
             
                def_delegator :@config, :mappings
         
     | 
| 
         @@ -19,7 +21,6 @@ module Dotsync 
     | 
|
| 
       19 
21 
     | 
    
         
             
                end
         
     | 
| 
       20 
22 
     | 
    
         | 
| 
       21 
23 
     | 
    
         
             
                private
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
24 
     | 
    
         
             
                  def show_config
         
     | 
| 
       24 
25 
     | 
    
         
             
                    logger.info("Mappings:", icon: :config)
         
     | 
| 
       25 
26 
     | 
    
         
             
                    mappings.each { |mapping| logger.log("  #{mapping}") }
         
     | 
| 
         @@ -0,0 +1,37 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Dotsync
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Colors
         
     | 
| 
      
 5 
     | 
    
         
            +
                DEFAULT_DIFF_ADDITIONS = 34
         
     | 
| 
      
 6 
     | 
    
         
            +
                DEFAULT_DIFF_MODIFICATIONS = 36
         
     | 
| 
      
 7 
     | 
    
         
            +
                DEFAULT_DIFF_REMOVALS = 88
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                @custom_colors = {}
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def self.load_custom_colors(config)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @custom_colors = {
         
     | 
| 
      
 13 
     | 
    
         
            +
                    diff_additions: config.dig("colors", "diff_additions") || DEFAULT_FORCE,
         
     | 
| 
      
 14 
     | 
    
         
            +
                    diff_modifications: config.dig("colors", "diff_modifications") || DEFAULT_IGNORE,
         
     | 
| 
      
 15 
     | 
    
         
            +
                    diff_removals: config.dig("colors", "diff_removals") || DEFAULT_INVALID
         
     | 
| 
      
 16 
     | 
    
         
            +
                  }
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                def self.diff_additions
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @custom_colors[:additions] || DEFAULT_DIFF_ADDITIONS
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                def self.diff_modifications
         
     | 
| 
      
 24 
     | 
    
         
            +
                  @custom_colors[:modifications] || DEFAULT_DIFF_MODIFICATIONS
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                def self.diff_removals
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @custom_colors[:removals] || DEFAULT_DIFF_REMOVALS
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                MAPPINGS = {
         
     | 
| 
      
 32 
     | 
    
         
            +
                  diff_additions: -> { diff_additions },
         
     | 
| 
      
 33 
     | 
    
         
            +
                  diff_modifications: -> { diff_modifications },
         
     | 
| 
      
 34 
     | 
    
         
            +
                  diff_removals: -> { diff_removals }
         
     | 
| 
      
 35 
     | 
    
         
            +
                }
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Dotsync
         
     | 
| 
       2 
4 
     | 
    
         
             
              # BaseConfig serves as an abstract class to define the structure
         
     | 
| 
       3 
5 
     | 
    
         
             
              # and validation rules for configuration files in the Dotsync system.
         
     | 
| 
         @@ -15,7 +17,6 @@ module Dotsync 
     | 
|
| 
       15 
17 
     | 
    
         
             
                end
         
     | 
| 
       16 
18 
     | 
    
         | 
| 
       17 
19 
     | 
    
         
             
                private
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
20 
     | 
    
         
             
                  # Validates the configuration file.
         
     | 
| 
       20 
21 
     | 
    
         
             
                  #
         
     | 
| 
       21 
22 
     | 
    
         
             
                  # @raise [NotImplementedError] if not implemented by a subclass.
         
     | 
| 
         @@ -1,10 +1,12 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Dotsync
         
     | 
| 
       2 
4 
     | 
    
         
             
              class PullActionConfig < BaseConfig
         
     | 
| 
       3 
5 
     | 
    
         
             
                include XDGBaseDirectorySpec
         
     | 
| 
       4 
6 
     | 
    
         | 
| 
       5 
7 
     | 
    
         
             
                def mappings
         
     | 
| 
       6 
8 
     | 
    
         
             
                  mappings_list = section["mappings"]
         
     | 
| 
       7 
     | 
    
         
            -
                  Array(mappings_list).map { |mapping| Dotsync:: 
     | 
| 
      
 9 
     | 
    
         
            +
                  Array(mappings_list).map { |mapping| Dotsync::Mapping.new(mapping) }
         
     | 
| 
       8 
10 
     | 
    
         
             
                end
         
     | 
| 
       9 
11 
     | 
    
         | 
| 
       10 
12 
     | 
    
         
             
                def backups_root
         
     | 
| 
         @@ -12,7 +14,6 @@ module Dotsync 
     | 
|
| 
       12 
14 
     | 
    
         
             
                end
         
     | 
| 
       13 
15 
     | 
    
         | 
| 
       14 
16 
     | 
    
         
             
                private
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
17 
     | 
    
         
             
                  SECTION_NAME = "pull"
         
     | 
| 
       17 
18 
     | 
    
         | 
| 
       18 
19 
     | 
    
         
             
                  def section_name
         
     | 
| 
         @@ -1,12 +1,13 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Dotsync
         
     | 
| 
       2 
4 
     | 
    
         
             
              class PushActionConfig < BaseConfig
         
     | 
| 
       3 
5 
     | 
    
         
             
                def mappings
         
     | 
| 
       4 
6 
     | 
    
         
             
                  mappings_list = section["mappings"]
         
     | 
| 
       5 
     | 
    
         
            -
                  Array(mappings_list).map { |mapping| Dotsync:: 
     | 
| 
      
 7 
     | 
    
         
            +
                  Array(mappings_list).map { |mapping| Dotsync::Mapping.new(mapping) }
         
     | 
| 
       6 
8 
     | 
    
         
             
                end
         
     | 
| 
       7 
9 
     | 
    
         | 
| 
       8 
10 
     | 
    
         
             
                private
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
11 
     | 
    
         
             
                  SECTION_NAME = "push"
         
     | 
| 
       11 
12 
     | 
    
         | 
| 
       12 
13 
     | 
    
         
             
                  def section_name
         
     | 
    
        data/lib/dotsync/errors.rb
    CHANGED
    
    
    
        data/lib/dotsync/icons.rb
    CHANGED
    
    | 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Dotsync
         
     | 
| 
       2 
4 
     | 
    
         
             
              module Icons
         
     | 
| 
       3 
5 
     | 
    
         
             
                # Log level icons
         
     | 
| 
         @@ -7,7 +9,7 @@ module Dotsync 
     | 
|
| 
       7 
9 
     | 
    
         
             
                # Configuration icon
         
     | 
| 
       8 
10 
     | 
    
         
             
                CONFIG = " "
         
     | 
| 
       9 
11 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                # Default  
     | 
| 
      
 12 
     | 
    
         
            +
                # Default Mapping icons
         
     | 
| 
       11 
13 
     | 
    
         
             
                DEFAULT_FORCE = " "
         
     | 
| 
       12 
14 
     | 
    
         
             
                DEFAULT_IGNORE = " "
         
     | 
| 
       13 
15 
     | 
    
         
             
                DEFAULT_INVALID = " "
         
     | 
| 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Dotsync
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Represents the differences between two directories
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Diff
         
     | 
| 
      
 6 
     | 
    
         
            +
                attr_reader :additions, :modifications, :removals
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def initialize(additions: [], modifications: [], removals: [])
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @additions = additions
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @modifications = modifications
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @removals = removals
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                def empty?
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @additions.empty? && @modifications.empty? && @removals.empty?
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,14 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Dotsync
         
     | 
| 
       2 
     | 
    
         
            -
              class  
     | 
| 
      
 4 
     | 
    
         
            +
              class Mapping
         
     | 
| 
       3 
5 
     | 
    
         
             
                include Dotsync::PathUtils
         
     | 
| 
       4 
6 
     | 
    
         | 
| 
       5 
7 
     | 
    
         
             
                attr_reader :original_src, :original_dest, :original_ignores
         
     | 
| 
       6 
8 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
                def initialize( 
     | 
| 
       8 
     | 
    
         
            -
                  @original_src =  
     | 
| 
       9 
     | 
    
         
            -
                  @original_dest =  
     | 
| 
       10 
     | 
    
         
            -
                  @original_ignores = Array( 
     | 
| 
       11 
     | 
    
         
            -
                  @force =  
     | 
| 
      
 9 
     | 
    
         
            +
                def initialize(attributes)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @original_src = attributes["src"]
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @original_dest = attributes["dest"]
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @original_ignores = Array(attributes["ignore"])
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @force = attributes["force"] || false
         
     | 
| 
       12 
14 
     | 
    
         | 
| 
       13 
15 
     | 
    
         
             
                  @sanitized_src = sanitize_path(@original_src)
         
     | 
| 
       14 
16 
     | 
    
         
             
                  @sanitized_dest = sanitize_path(@original_dest)
         
     | 
| 
         @@ -32,7 +34,19 @@ module Dotsync 
     | 
|
| 
       32 
34 
     | 
    
         
             
                end
         
     | 
| 
       33 
35 
     | 
    
         | 
| 
       34 
36 
     | 
    
         
             
                def valid?
         
     | 
| 
       35 
     | 
    
         
            -
                  File. 
     | 
| 
      
 37 
     | 
    
         
            +
                  (File.file?(src) && File.file?(dest)) ||
         
     | 
| 
      
 38 
     | 
    
         
            +
                  (File.directory?(src) && File.directory?(dest)) ||
         
     | 
| 
      
 39 
     | 
    
         
            +
                  (File.file?(src) && !File.exist?(dest) && File.directory?(File.dirname(dest)))
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                def backup_possible?
         
     | 
| 
      
 43 
     | 
    
         
            +
                  valid? && File.exist?(dest)
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                def backup_basename
         
     | 
| 
      
 47 
     | 
    
         
            +
                  return unless valid?
         
     | 
| 
      
 48 
     | 
    
         
            +
                  return File.dirname(dest) unless File.exist?(dest)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  File.basename(dest)
         
     | 
| 
       36 
50 
     | 
    
         
             
                end
         
     | 
| 
       37 
51 
     | 
    
         | 
| 
       38 
52 
     | 
    
         
             
                def to_s
         
     | 
| 
         @@ -52,7 +66,7 @@ module Dotsync 
     | 
|
| 
       52 
66 
     | 
    
         
             
                    path
         
     | 
| 
       53 
67 
     | 
    
         
             
                  end
         
     | 
| 
       54 
68 
     | 
    
         | 
| 
       55 
     | 
    
         
            -
                  Dotsync:: 
     | 
| 
      
 69 
     | 
    
         
            +
                  Dotsync::Mapping.new(
         
     | 
| 
       56 
70 
     | 
    
         
             
                    "src" => File.join(@original_src, relative_path),
         
     | 
| 
       57 
71 
     | 
    
         
             
                    "dest" => File.join(@original_dest, relative_path),
         
     | 
| 
       58 
72 
     | 
    
         
             
                    "force" => @force,
         
     | 
| 
         @@ -61,10 +75,8 @@ module Dotsync 
     | 
|
| 
       61 
75 
     | 
    
         
             
                end
         
     | 
| 
       62 
76 
     | 
    
         | 
| 
       63 
77 
     | 
    
         
             
                private
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                   
     | 
| 
       67 
     | 
    
         
            -
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
                  def ignores?
         
     | 
| 
      
 79 
     | 
    
         
            +
                    @original_ignores.any?
         
     | 
| 
      
 80 
     | 
    
         
            +
                  end
         
     | 
| 
       68 
81 
     | 
    
         
             
              end
         
     | 
| 
       69 
82 
     | 
    
         
             
            end
         
     | 
| 
       70 
     | 
    
         
            -
             
     | 
    
        data/lib/dotsync/runner.rb
    CHANGED
    
    | 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Dotsync
         
     | 
| 
       2 
4 
     | 
    
         
             
              class Runner
         
     | 
| 
       3 
5 
     | 
    
         
             
                def initialize(logger: nil)
         
     | 
| 
         @@ -15,7 +17,11 @@ module Dotsync 
     | 
|
| 
       15 
17 
     | 
    
         
             
                      config_class = Dotsync.const_get("#{camelize(action_name.to_s)}ActionConfig")
         
     | 
| 
       16 
18 
     | 
    
         | 
| 
       17 
19 
     | 
    
         
             
                      config = config_class.new(Dotsync.config_path)
         
     | 
| 
      
 20 
     | 
    
         
            +
                      Dotsync::Icons.load_custom_icons(config)
         
     | 
| 
      
 21 
     | 
    
         
            +
                      Dotsync::Colors.load_custom_colors(config)
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
       18 
23 
     | 
    
         
             
                      action = action_class.new(config, @logger)
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
       19 
25 
     | 
    
         
             
                      action.execute
         
     | 
| 
       20 
26 
     | 
    
         
             
                    rescue ConfigError => e
         
     | 
| 
       21 
27 
     | 
    
         
             
                      @logger.error("[#{action_name}] config error:")
         
     | 
| 
         @@ -32,42 +38,41 @@ module Dotsync 
     | 
|
| 
       32 
38 
     | 
    
         
             
                end
         
     | 
| 
       33 
39 
     | 
    
         | 
| 
       34 
40 
     | 
    
         
             
                private
         
     | 
| 
      
 41 
     | 
    
         
            +
                  def setup_config
         
     | 
| 
      
 42 
     | 
    
         
            +
                    require "toml-rb"
         
     | 
| 
      
 43 
     | 
    
         
            +
                    require "fileutils"
         
     | 
| 
       35 
44 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
                  require 'fileutils'
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                  config_path = File.expand_path(Dotsync.config_path)
         
     | 
| 
       41 
     | 
    
         
            -
                  FileUtils.mkdir_p(File.dirname(config_path))
         
     | 
| 
      
 45 
     | 
    
         
            +
                    config_path = File.expand_path(Dotsync.config_path)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    FileUtils.mkdir_p(File.dirname(config_path))
         
     | 
| 
       42 
47 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
      
 48 
     | 
    
         
            +
                    example_mappings = {
         
     | 
| 
      
 49 
     | 
    
         
            +
                      "pull" => {
         
     | 
| 
      
 50 
     | 
    
         
            +
                        "mappings" => [
         
     | 
| 
      
 51 
     | 
    
         
            +
                          { "src" => "$DOTFILES_DIR/config/", "dest" => "$XDG_CONFIG_HOME", "force" => false },
         
     | 
| 
      
 52 
     | 
    
         
            +
                          { "src" => "$DOTFILES_DIR/home/.zshenv", "dest" => "$HOME" }
         
     | 
| 
      
 53 
     | 
    
         
            +
                        ],
         
     | 
| 
      
 54 
     | 
    
         
            +
                      },
         
     | 
| 
      
 55 
     | 
    
         
            +
                      "push" => {
         
     | 
| 
      
 56 
     | 
    
         
            +
                        "mappings" => [
         
     | 
| 
      
 57 
     | 
    
         
            +
                          { "src" => "$HOME/.zshenv", "dest" => "$DOTFILES_DIR/home/.zshenv" },
         
     | 
| 
      
 58 
     | 
    
         
            +
                          { "src" => "$XDG_CONFIG_HOME/alacritty", "dest" => "$DOTFILES_DIR/config/alacritty" }
         
     | 
| 
      
 59 
     | 
    
         
            +
                        ]
         
     | 
| 
      
 60 
     | 
    
         
            +
                      },
         
     | 
| 
      
 61 
     | 
    
         
            +
                      "watch" => {
         
     | 
| 
      
 62 
     | 
    
         
            +
                        "mappings" => [
         
     | 
| 
      
 63 
     | 
    
         
            +
                          { "src" => "$HOME/.zshenv", "dest" => "$DOTFILES_DIR/home/.zshenv" },
         
     | 
| 
      
 64 
     | 
    
         
            +
                          { "src" => "$XDG_CONFIG_HOME/alacritty", "dest" => "$DOTFILES_DIR/config/alacritty" }
         
     | 
| 
      
 65 
     | 
    
         
            +
                        ]
         
     | 
| 
      
 66 
     | 
    
         
            +
                      }
         
     | 
| 
       61 
67 
     | 
    
         
             
                    }
         
     | 
| 
       62 
     | 
    
         
            -
                  }
         
     | 
| 
       63 
68 
     | 
    
         | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
      
 69 
     | 
    
         
            +
                    File.write(config_path, TomlRB.dump(example_mappings))
         
     | 
| 
      
 70 
     | 
    
         
            +
                    @logger.info("Configuration file created at #{config_path}")
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
       67 
72 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
      
 73 
     | 
    
         
            +
                  # Utility to convert 'pull' to 'Pull', 'sync' to 'Sync', etc.
         
     | 
| 
      
 74 
     | 
    
         
            +
                  def camelize(str)
         
     | 
| 
      
 75 
     | 
    
         
            +
                    str.split("_").map(&:capitalize).join
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end
         
     | 
| 
       72 
77 
     | 
    
         
             
              end
         
     | 
| 
       73 
78 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,111 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Dotsync
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Usage:
         
     | 
| 
      
 5 
     | 
    
         
            +
              # differ = DirectoryDiffer.new("/path/to/src", "/path/to/dest")
         
     | 
| 
      
 6 
     | 
    
         
            +
              # differences = differ.diff
         
     | 
| 
      
 7 
     | 
    
         
            +
              class DirectoryDiffer
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_reader :src, :dest
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                # Initializes a new DirectoryDiffer.
         
     | 
| 
      
 11 
     | 
    
         
            +
                #
         
     | 
| 
      
 12 
     | 
    
         
            +
                # @param mapping [Dotsync::Mapping] the mapping object containing source, destination, force, and ignore details
         
     | 
| 
      
 13 
     | 
    
         
            +
                # @option mapping [String] :src the source directory path
         
     | 
| 
      
 14 
     | 
    
         
            +
                # @option mapping [String] :dest the destination directory path
         
     | 
| 
      
 15 
     | 
    
         
            +
                # @option mapping [Boolean] :force? optional flag to force actions
         
     | 
| 
      
 16 
     | 
    
         
            +
                # @option mapping [Array<String>] :ignores optional list of files/directories to ignore
         
     | 
| 
      
 17 
     | 
    
         
            +
                def initialize(mapping)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @src = mapping.src
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @dest = mapping.dest
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @force = mapping.force?
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @ignores = mapping.original_ignores || []
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def diff
         
     | 
| 
      
 25 
     | 
    
         
            +
                  additions = []
         
     | 
| 
      
 26 
     | 
    
         
            +
                  modifications = []
         
     | 
| 
      
 27 
     | 
    
         
            +
                  removals = []
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  Find.find(src) do |src_path|
         
     | 
| 
      
 30 
     | 
    
         
            +
                    rel_path = src_path.sub(/^#{Regexp.escape(src)}\/?/, "")
         
     | 
| 
      
 31 
     | 
    
         
            +
                    next if rel_path.empty?
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                    dest_path = File.join(dest, rel_path)
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                    if !File.exist?(dest_path)
         
     | 
| 
      
 36 
     | 
    
         
            +
                      additions << rel_path
         
     | 
| 
      
 37 
     | 
    
         
            +
                    elsif File.file?(src_path) && File.file?(dest_path)
         
     | 
| 
      
 38 
     | 
    
         
            +
                      if File.size(src_path) != File.size(dest_path)
         
     | 
| 
      
 39 
     | 
    
         
            +
                        modifications << rel_path
         
     | 
| 
      
 40 
     | 
    
         
            +
                      end
         
     | 
| 
      
 41 
     | 
    
         
            +
                    end
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  if @force
         
     | 
| 
      
 45 
     | 
    
         
            +
                    Find.find(dest) do |dest_path|
         
     | 
| 
      
 46 
     | 
    
         
            +
                      rel_path = dest_path.sub(/^#{Regexp.escape(dest)}\/?/, "")
         
     | 
| 
      
 47 
     | 
    
         
            +
                      next if rel_path.empty?
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                      src_path = File.join(src, rel_path)
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                      if !File.exist?(src_path)
         
     | 
| 
      
 52 
     | 
    
         
            +
                        removals << rel_path
         
     | 
| 
      
 53 
     | 
    
         
            +
                      end
         
     | 
| 
      
 54 
     | 
    
         
            +
                    end
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  if @ignores.any?
         
     | 
| 
      
 58 
     | 
    
         
            +
                    additions = filter_paths(additions, @ignores)
         
     | 
| 
      
 59 
     | 
    
         
            +
                    modifications = filter_paths(modifications, @ignores)
         
     | 
| 
      
 60 
     | 
    
         
            +
                    removals = filter_paths(removals, @ignores)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                  Dotsync::Diff.new(additions: additions, modifications: modifications, removals: removals)
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                private
         
     | 
| 
      
 67 
     | 
    
         
            +
                  def collect_src_diffs
         
     | 
| 
      
 68 
     | 
    
         
            +
                    diffs = []
         
     | 
| 
      
 69 
     | 
    
         
            +
                    Find.find(src) do |src_path|
         
     | 
| 
      
 70 
     | 
    
         
            +
                      rel_path = src_path.sub(/^#{Regexp.escape(src)}\/?/, "")
         
     | 
| 
      
 71 
     | 
    
         
            +
                      next if rel_path.empty?
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                      dest_path = File.join(dest, rel_path)
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                      if !File.exist?(dest_path)
         
     | 
| 
      
 76 
     | 
    
         
            +
                        diffs << rel_path
         
     | 
| 
      
 77 
     | 
    
         
            +
                      elsif File.directory?(src_path) && !File.directory?(dest_path)
         
     | 
| 
      
 78 
     | 
    
         
            +
                        diffs << rel_path
         
     | 
| 
      
 79 
     | 
    
         
            +
                      elsif File.file?(src_path) && !File.file?(dest_path)
         
     | 
| 
      
 80 
     | 
    
         
            +
                        diffs << rel_path
         
     | 
| 
      
 81 
     | 
    
         
            +
                      elsif File.file?(src_path) && File.file?(dest_path)
         
     | 
| 
      
 82 
     | 
    
         
            +
                        if File.size(src_path) != File.size(dest_path)
         
     | 
| 
      
 83 
     | 
    
         
            +
                          diffs << rel_path
         
     | 
| 
      
 84 
     | 
    
         
            +
                        end
         
     | 
| 
      
 85 
     | 
    
         
            +
                      end
         
     | 
| 
      
 86 
     | 
    
         
            +
                    end
         
     | 
| 
      
 87 
     | 
    
         
            +
                    diffs
         
     | 
| 
      
 88 
     | 
    
         
            +
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                  def collect_dest_diffs
         
     | 
| 
      
 91 
     | 
    
         
            +
                    diffs = []
         
     | 
| 
      
 92 
     | 
    
         
            +
                    Find.find(dest) do |dest_path|
         
     | 
| 
      
 93 
     | 
    
         
            +
                      rel_path = dest_path.sub(/^#{Regexp.escape(dest)}\/?/, "")
         
     | 
| 
      
 94 
     | 
    
         
            +
                      next if rel_path.empty?
         
     | 
| 
      
 95 
     | 
    
         
            +
                      src_path = File.join(src, rel_path)
         
     | 
| 
      
 96 
     | 
    
         
            +
                      if !File.exist?(src_path)
         
     | 
| 
      
 97 
     | 
    
         
            +
                        diffs << rel_path
         
     | 
| 
      
 98 
     | 
    
         
            +
                      end
         
     | 
| 
      
 99 
     | 
    
         
            +
                    end
         
     | 
| 
      
 100 
     | 
    
         
            +
                    diffs
         
     | 
| 
      
 101 
     | 
    
         
            +
                  end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                  def filter_paths(all_paths, ignore_paths)
         
     | 
| 
      
 104 
     | 
    
         
            +
                    all_paths.reject do |path|
         
     | 
| 
      
 105 
     | 
    
         
            +
                      ignore_paths.any? do |ignore|
         
     | 
| 
      
 106 
     | 
    
         
            +
                        path == ignore || path.start_with?("#{ignore}/")
         
     | 
| 
      
 107 
     | 
    
         
            +
                      end
         
     | 
| 
      
 108 
     | 
    
         
            +
                    end
         
     | 
| 
      
 109 
     | 
    
         
            +
                  end
         
     | 
| 
      
 110 
     | 
    
         
            +
              end
         
     | 
| 
      
 111 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,57 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Dotsync
         
     | 
| 
      
 4 
     | 
    
         
            +
              class FileTransfer
         
     | 
| 
      
 5 
     | 
    
         
            +
                attr_reader :ignores
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                # Initializes a new FileTransfer instance
         
     | 
| 
      
 8 
     | 
    
         
            +
                #
         
     | 
| 
      
 9 
     | 
    
         
            +
                # @param mapping [Dotsync::Mapping] the mapping object containing source, destination, force, and ignore details
         
     | 
| 
      
 10 
     | 
    
         
            +
                # @option mapping [String] :src the source directory path
         
     | 
| 
      
 11 
     | 
    
         
            +
                # @option mapping [String] :dest the destination directory path
         
     | 
| 
      
 12 
     | 
    
         
            +
                # @option mapping [Boolean] :force? optional flag to force actions
         
     | 
| 
      
 13 
     | 
    
         
            +
                # @option mapping [Array<String>] :ignores optional list of files/directories to ignore
         
     | 
| 
      
 14 
     | 
    
         
            +
                def initialize(mapping)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @src = mapping.src
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @dest = mapping.dest
         
     | 
| 
      
 17 
     | 
    
         
            +
                  @force = mapping.force?
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @ignores = mapping.ignores || []
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def transfer
         
     | 
| 
      
 22 
     | 
    
         
            +
                  if File.file?(@src)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    transfer_file(@src, @dest)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  else
         
     | 
| 
      
 25 
     | 
    
         
            +
                    FileUtils.rm_rf(Dir.glob(File.join(@dest, "*"))) if @force
         
     | 
| 
      
 26 
     | 
    
         
            +
                    transfer_folder(@src, @dest)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                private
         
     | 
| 
      
 31 
     | 
    
         
            +
                  def transfer_file(file_src, file_dest)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    FileUtils.mkdir_p(File.dirname(file_dest))
         
     | 
| 
      
 33 
     | 
    
         
            +
                    FileUtils.cp(file_src, file_dest)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  def transfer_folder(folder_src, folder_dest)
         
     | 
| 
      
 37 
     | 
    
         
            +
                    FileUtils.mkdir_p(folder_dest)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    Dir.glob("#{folder_src}/*", File::FNM_DOTMATCH).each do |path|
         
     | 
| 
      
 39 
     | 
    
         
            +
                      next if [".", ".."].include?(File.basename(path))
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                      full_path = File.expand_path(path)
         
     | 
| 
      
 42 
     | 
    
         
            +
                      next if ignore?(full_path)
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                      target = File.join(folder_dest, File.basename(path))
         
     | 
| 
      
 45 
     | 
    
         
            +
                      if File.file?(full_path)
         
     | 
| 
      
 46 
     | 
    
         
            +
                        FileUtils.cp(full_path, target)
         
     | 
| 
      
 47 
     | 
    
         
            +
                      else
         
     | 
| 
      
 48 
     | 
    
         
            +
                        transfer_folder(full_path, target)
         
     | 
| 
      
 49 
     | 
    
         
            +
                      end
         
     | 
| 
      
 50 
     | 
    
         
            +
                    end
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  def ignore?(path)
         
     | 
| 
      
 54 
     | 
    
         
            +
                    @ignores.any? { |ignore| path.start_with?(ignore) }
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
              end
         
     | 
| 
      
 57 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Dotsync
         
     | 
| 
       2 
4 
     | 
    
         
             
              module PathUtils
         
     | 
| 
       3 
5 
     | 
    
         
             
                ENV_VARS_COLOR = 104
         
     | 
| 
         @@ -15,8 +17,8 @@ module Dotsync 
     | 
|
| 
       15 
17 
     | 
    
         
             
                # @param [String] path The input path to translate
         
     | 
| 
       16 
18 
     | 
    
         
             
                # @return [String] The translated path
         
     | 
| 
       17 
19 
     | 
    
         
             
                def translate_tmp_path(path)
         
     | 
| 
       18 
     | 
    
         
            -
                  if path.start_with?( 
     | 
| 
       19 
     | 
    
         
            -
                    path.sub( 
     | 
| 
      
 20 
     | 
    
         
            +
                  if path.start_with?("/tmp") && RUBY_PLATFORM.include?("darwin")
         
     | 
| 
      
 21 
     | 
    
         
            +
                    path.sub("/tmp", "/private/tmp")
         
     | 
| 
       20 
22 
     | 
    
         
             
                  else
         
     | 
| 
       21 
23 
     | 
    
         
             
                    path
         
     | 
| 
       22 
24 
     | 
    
         
             
                  end
         
     | 
    
        data/lib/dotsync/version.rb
    CHANGED
    
    
    
        data/lib/dotsync.rb
    CHANGED
    
    | 
         @@ -1,29 +1,32 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            # Libs dependencies
         
     | 
| 
       2 
     | 
    
         
            -
            require  
     | 
| 
       3 
     | 
    
         
            -
            require  
     | 
| 
       4 
     | 
    
         
            -
            require  
     | 
| 
       5 
     | 
    
         
            -
            require  
     | 
| 
       6 
     | 
    
         
            -
            require  
     | 
| 
       7 
     | 
    
         
            -
            require  
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            # Errors
         
     | 
| 
       10 
     | 
    
         
            -
            require_relative "dotsync/errors"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "fileutils"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "listen"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "toml-rb"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require "logger"
         
     | 
| 
      
 8 
     | 
    
         
            +
            require "forwardable" # Ruby standard library
         
     | 
| 
      
 9 
     | 
    
         
            +
            require "ostruct"
         
     | 
| 
      
 10 
     | 
    
         
            +
            require "find"
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
            # Utils
         
     | 
| 
       13 
     | 
    
         
            -
            require_relative  
     | 
| 
       14 
     | 
    
         
            -
            require_relative  
     | 
| 
       15 
     | 
    
         
            -
            require_relative  
     | 
| 
       16 
     | 
    
         
            -
            require_relative  
     | 
| 
      
 13 
     | 
    
         
            +
            require_relative "dotsync/utils/logger"
         
     | 
| 
      
 14 
     | 
    
         
            +
            require_relative "dotsync/utils/file_transfer"
         
     | 
| 
      
 15 
     | 
    
         
            +
            require_relative "dotsync/utils/directory_differ"
         
     | 
| 
      
 16 
     | 
    
         
            +
            require_relative "dotsync/utils/path_utils"
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            # Models
         
     | 
| 
      
 19 
     | 
    
         
            +
            require_relative "dotsync/models/mapping"
         
     | 
| 
      
 20 
     | 
    
         
            +
            require_relative "dotsync/models/diff"
         
     | 
| 
       17 
21 
     | 
    
         | 
| 
       18 
22 
     | 
    
         
             
            # Config
         
     | 
| 
       19 
     | 
    
         
            -
            require_relative "dotsync/ 
     | 
| 
       20 
     | 
    
         
            -
            require_relative "dotsync/ 
     | 
| 
       21 
     | 
    
         
            -
            require_relative "dotsync/ 
     | 
| 
       22 
     | 
    
         
            -
            require_relative "dotsync/ 
     | 
| 
       23 
     | 
    
         
            -
            require_relative "dotsync/ 
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
            # Concerns
         
     | 
| 
      
 23 
     | 
    
         
            +
            require_relative "dotsync/config/xdg_base_directory_spec"
         
     | 
| 
      
 24 
     | 
    
         
            +
            require_relative "dotsync/config/base_config"
         
     | 
| 
      
 25 
     | 
    
         
            +
            require_relative "dotsync/config/pull_action_config"
         
     | 
| 
      
 26 
     | 
    
         
            +
            require_relative "dotsync/config/push_action_config"
         
     | 
| 
      
 27 
     | 
    
         
            +
            require_relative "dotsync/config/watch_action_config"
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            # Actions Concerns
         
     | 
| 
       27 
30 
     | 
    
         
             
            require_relative "dotsync/actions/concerns/mappings_transfer"
         
     | 
| 
       28 
31 
     | 
    
         | 
| 
       29 
32 
     | 
    
         
             
            # Actions
         
     | 
| 
         @@ -32,18 +35,19 @@ require_relative "dotsync/actions/pull_action" 
     | 
|
| 
       32 
35 
     | 
    
         
             
            require_relative "dotsync/actions/push_action"
         
     | 
| 
       33 
36 
     | 
    
         
             
            require_relative "dotsync/actions/watch_action"
         
     | 
| 
       34 
37 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
      
 38 
     | 
    
         
            +
            # Base classes
         
     | 
| 
      
 39 
     | 
    
         
            +
            require_relative "dotsync/errors"
         
     | 
| 
      
 40 
     | 
    
         
            +
            require_relative "dotsync/icons"
         
     | 
| 
      
 41 
     | 
    
         
            +
            require_relative "dotsync/colors"
         
     | 
| 
      
 42 
     | 
    
         
            +
            require_relative "dotsync/runner"
         
     | 
| 
       37 
43 
     | 
    
         
             
            require_relative "dotsync/version"
         
     | 
| 
       38 
44 
     | 
    
         | 
| 
       39 
45 
     | 
    
         
             
            module Dotsync
         
     | 
| 
       40 
     | 
    
         
            -
              class Error < StandardError; end
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
46 
     | 
    
         
             
              class << self
         
     | 
| 
       43 
47 
     | 
    
         
             
                attr_writer :config_path
         
     | 
| 
       44 
48 
     | 
    
         | 
| 
       45 
49 
     | 
    
         
             
                def config_path
         
     | 
| 
       46 
     | 
    
         
            -
                  @config_path ||= ENV[ 
     | 
| 
      
 50 
     | 
    
         
            +
                  @config_path ||= ENV["DOTSYNC_CONFIG"] || "~/.config/dotsync.toml"
         
     | 
| 
       47 
51 
     | 
    
         
             
                end
         
     | 
| 
       48 
52 
     | 
    
         
             
              end
         
     | 
| 
       49 
53 
     | 
    
         
             
            end
         
     |