dotsync 0.1.26 → 0.2.0
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/CHANGELOG.md +20 -0
- data/Gemfile.lock +1 -1
- data/exe/dotsync +5 -0
- data/lib/dotsync/actions/concerns/mappings_transfer.rb +34 -12
- data/lib/dotsync/actions/concerns/output_sections.rb +2 -1
- data/lib/dotsync/actions/pull_action.rb +1 -1
- data/lib/dotsync/actions/push_action.rb +1 -1
- data/lib/dotsync/loaders/pull_loader.rb +2 -0
- data/lib/dotsync/loaders/push_loader.rb +2 -0
- data/lib/dotsync/models/diff.rb +3 -2
- data/lib/dotsync/models/mapping.rb +10 -0
- data/lib/dotsync/utils/content_diff.rb +82 -0
- data/lib/dotsync/utils/directory_differ.rb +24 -8
- data/lib/dotsync/utils/parallel.rb +72 -0
- data/lib/dotsync/version.rb +1 -1
- data/lib/dotsync.rb +1 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 492eda1f730e490322f6ff7fe85fd3fb91a1bd337f191f13d9574d63a5a9a326
|
|
4
|
+
data.tar.gz: f797e4c6a06258d312c3264be88cda022cb02f8053ed31159de54ce585ef9e3a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0d9bd4948c5d7de46e30443ca19ae4fabfc8d0caf3410b2a5e8bb519c8dc27384e032c06db32bd2a9bad041f6642707e8223f4affad58aa540cde4e277663b77
|
|
7
|
+
data.tar.gz: f20438f023966222c67f1a5397dfa8110d0d1cf4985fe67a82f0f8cbe615a9b25bdb88db176db33f1a0bf5109dccb1c5cce4889d74ab259dbd8bdd6e1716c2cf
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## [0.2.0] - 2025-02-06
|
|
2
|
+
|
|
3
|
+
**New Features:**
|
|
4
|
+
- Add `--diff-content` CLI option to display git-like unified diff output for modified files
|
|
5
|
+
- Shows actual content changes without needing external tools like `nvim -d`
|
|
6
|
+
- Color-coded output: blue for additions, red for deletions, cyan for hunk headers
|
|
7
|
+
- Automatically skips binary files
|
|
8
|
+
- Works with both `push` and `pull` commands
|
|
9
|
+
|
|
10
|
+
**Performance Optimizations:**
|
|
11
|
+
- Add parallel processing for mapping operations
|
|
12
|
+
- New `Dotsync::Parallel` utility module with thread-pool based execution
|
|
13
|
+
- Diff computation runs in parallel across multiple mappings
|
|
14
|
+
- File transfers execute concurrently for independent mappings
|
|
15
|
+
- Thread-safe error collection and reporting
|
|
16
|
+
- Add directory pruning optimization
|
|
17
|
+
- New `should_prune_directory?` method for early-exit during traversal
|
|
18
|
+
- Skips entire directory subtrees that are ignored or outside inclusion lists
|
|
19
|
+
- Reduces filesystem operations for large excluded directories
|
|
20
|
+
|
|
1
21
|
## [0.1.26] - 2025-01-11
|
|
2
22
|
|
|
3
23
|
**Breaking Changes:**
|
data/Gemfile.lock
CHANGED
data/exe/dotsync
CHANGED
|
@@ -51,6 +51,7 @@ opt_parser = OptionParser.new do |opts|
|
|
|
51
51
|
--only-config Show only the config section
|
|
52
52
|
--only-mappings Show only the mappings section
|
|
53
53
|
-v, --verbose Force showing all available information
|
|
54
|
+
--diff-content Show git-like content diff for modified files
|
|
54
55
|
--trace Show full error backtraces (for debugging)
|
|
55
56
|
--version Show version number
|
|
56
57
|
-h, --help Show this help message
|
|
@@ -112,6 +113,10 @@ opt_parser = OptionParser.new do |opts|
|
|
|
112
113
|
options[:verbose] = true
|
|
113
114
|
end
|
|
114
115
|
|
|
116
|
+
opts.on("--diff-content", "Show git-like content diff for modified files") do
|
|
117
|
+
options[:diff_content] = true
|
|
118
|
+
end
|
|
119
|
+
|
|
115
120
|
opts.on("--trace", "Show full error backtraces (for debugging)") do
|
|
116
121
|
options[:trace] = true
|
|
117
122
|
end
|
|
@@ -62,7 +62,7 @@ module Dotsync
|
|
|
62
62
|
logger.log("")
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
-
def show_differences
|
|
65
|
+
def show_differences(diff_content: false)
|
|
66
66
|
info("Differences:", icon: :diff)
|
|
67
67
|
differs.flat_map(&:additions).sort.each do |path|
|
|
68
68
|
logger.log("#{Icons.diff_created}#{path}", color: Colors.diff_additions)
|
|
@@ -75,31 +75,45 @@ module Dotsync
|
|
|
75
75
|
end
|
|
76
76
|
logger.log(" No differences") unless has_differences?
|
|
77
77
|
logger.log("")
|
|
78
|
+
|
|
79
|
+
show_content_diffs if diff_content && has_modifications?
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def show_content_diffs
|
|
83
|
+
info("Content Differences:", icon: :diff)
|
|
84
|
+
modification_pairs.each do |pair|
|
|
85
|
+
Dotsync::ContentDiff.new(pair[:src], pair[:dest], logger).display
|
|
86
|
+
end
|
|
78
87
|
end
|
|
79
88
|
|
|
80
89
|
def transfer_mappings
|
|
81
|
-
|
|
90
|
+
errors = []
|
|
91
|
+
mutex = Mutex.new
|
|
92
|
+
|
|
93
|
+
Dotsync::Parallel.each(valid_mappings) do |mapping|
|
|
82
94
|
Dotsync::FileTransfer.new(mapping).transfer
|
|
83
95
|
rescue Dotsync::PermissionError => e
|
|
84
|
-
|
|
85
|
-
logger.info("Try: chmod +w <path> or check file permissions")
|
|
96
|
+
mutex.synchronize { errors << ["Permission denied: #{e.message}", "Try: chmod +w <path> or check file permissions"] }
|
|
86
97
|
rescue Dotsync::DiskFullError => e
|
|
87
|
-
|
|
88
|
-
logger.info("Free up disk space and try again")
|
|
98
|
+
mutex.synchronize { errors << ["Disk full: #{e.message}", "Free up disk space and try again"] }
|
|
89
99
|
rescue Dotsync::SymlinkError => e
|
|
90
|
-
|
|
91
|
-
logger.info("Check that symlink target exists and is accessible")
|
|
100
|
+
mutex.synchronize { errors << ["Symlink error: #{e.message}", "Check that symlink target exists and is accessible"] }
|
|
92
101
|
rescue Dotsync::TypeConflictError => e
|
|
93
|
-
|
|
94
|
-
logger.info("Cannot overwrite directory with file or vice versa")
|
|
102
|
+
mutex.synchronize { errors << ["Type conflict: #{e.message}", "Cannot overwrite directory with file or vice versa"] }
|
|
95
103
|
rescue Dotsync::FileTransferError => e
|
|
96
|
-
|
|
104
|
+
mutex.synchronize { errors << ["File transfer failed: #{e.message}", nil] }
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Report all errors after parallel execution
|
|
108
|
+
errors.each do |error_msg, info_msg|
|
|
109
|
+
logger.error(error_msg)
|
|
110
|
+
logger.info(info_msg) if info_msg
|
|
97
111
|
end
|
|
98
112
|
end
|
|
99
113
|
|
|
100
114
|
private
|
|
101
115
|
def differs
|
|
102
|
-
@differs ||=
|
|
116
|
+
@differs ||= Dotsync::Parallel.map(valid_mappings) do |mapping|
|
|
103
117
|
Dotsync::DirectoryDiffer.new(mapping).diff
|
|
104
118
|
end
|
|
105
119
|
end
|
|
@@ -108,6 +122,14 @@ module Dotsync
|
|
|
108
122
|
differs.any? { |differ| differ.any? }
|
|
109
123
|
end
|
|
110
124
|
|
|
125
|
+
def has_modifications?
|
|
126
|
+
differs.any? { |differ| differ.modifications.any? }
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def modification_pairs
|
|
130
|
+
differs.flat_map(&:modification_pairs)
|
|
131
|
+
end
|
|
132
|
+
|
|
111
133
|
def confirm_action
|
|
112
134
|
total_changes = differs.sum { |diff| diff.additions.size + diff.modifications.size + diff.removals.size }
|
|
113
135
|
logger.log("")
|
|
@@ -12,7 +12,8 @@ module Dotsync
|
|
|
12
12
|
mappings_legend: !(quiet || options[:no_legend] || options[:no_mappings] || options[:only_diff]),
|
|
13
13
|
mappings: !(quiet || options[:no_mappings] || options[:only_diff]),
|
|
14
14
|
differences_legend: !(quiet || options[:no_legend] || options[:no_diff_legend] || options[:no_diff] || options[:only_config] || options[:only_mappings]),
|
|
15
|
-
differences: !(quiet || options[:no_diff] || options[:only_mappings] || options[:only_config])
|
|
15
|
+
differences: !(quiet || options[:no_diff] || options[:only_mappings] || options[:only_config]),
|
|
16
|
+
diff_content: options[:diff_content] || false
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
if verbose
|
|
@@ -15,7 +15,7 @@ module Dotsync
|
|
|
15
15
|
show_mappings_legend if output_sections[:mappings_legend]
|
|
16
16
|
show_mappings if output_sections[:mappings]
|
|
17
17
|
show_differences_legend if has_differences? && output_sections[:differences_legend]
|
|
18
|
-
show_differences if output_sections[:differences]
|
|
18
|
+
show_differences(diff_content: output_sections[:diff_content]) if output_sections[:differences]
|
|
19
19
|
|
|
20
20
|
return unless options[:apply]
|
|
21
21
|
|
|
@@ -13,7 +13,7 @@ module Dotsync
|
|
|
13
13
|
show_mappings_legend if output_sections[:mappings_legend]
|
|
14
14
|
show_mappings if output_sections[:mappings]
|
|
15
15
|
show_differences_legend if has_differences? && output_sections[:differences_legend]
|
|
16
|
-
show_differences if output_sections[:differences]
|
|
16
|
+
show_differences(diff_content: output_sections[:diff_content]) if output_sections[:differences]
|
|
17
17
|
|
|
18
18
|
return unless options[:apply]
|
|
19
19
|
|
|
@@ -11,6 +11,8 @@ require "terminal-table"
|
|
|
11
11
|
require_relative "../utils/file_transfer"
|
|
12
12
|
require_relative "../utils/directory_differ"
|
|
13
13
|
require_relative "../utils/config_cache"
|
|
14
|
+
require_relative "../utils/content_diff"
|
|
15
|
+
require_relative "../utils/parallel"
|
|
14
16
|
|
|
15
17
|
# Models
|
|
16
18
|
require_relative "../models/mapping"
|
|
@@ -11,6 +11,8 @@ require "terminal-table"
|
|
|
11
11
|
require_relative "../utils/file_transfer"
|
|
12
12
|
require_relative "../utils/directory_differ"
|
|
13
13
|
require_relative "../utils/config_cache"
|
|
14
|
+
require_relative "../utils/content_diff"
|
|
15
|
+
require_relative "../utils/parallel"
|
|
14
16
|
|
|
15
17
|
# Models
|
|
16
18
|
require_relative "../models/mapping"
|
data/lib/dotsync/models/diff.rb
CHANGED
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
module Dotsync
|
|
4
4
|
# Represents the differences between two directories
|
|
5
5
|
class Diff
|
|
6
|
-
attr_reader :additions, :modifications, :removals
|
|
6
|
+
attr_reader :additions, :modifications, :removals, :modification_pairs
|
|
7
7
|
|
|
8
|
-
def initialize(additions: [], modifications: [], removals: [])
|
|
8
|
+
def initialize(additions: [], modifications: [], removals: [], modification_pairs: [])
|
|
9
9
|
@additions = additions
|
|
10
10
|
@modifications = modifications
|
|
11
11
|
@removals = removals
|
|
12
|
+
@modification_pairs = modification_pairs
|
|
12
13
|
end
|
|
13
14
|
|
|
14
15
|
def any?
|
|
@@ -140,6 +140,16 @@ module Dotsync
|
|
|
140
140
|
ignore?(path) || !include?(path)
|
|
141
141
|
end
|
|
142
142
|
|
|
143
|
+
# Returns true if a directory can be entirely skipped during destination walks.
|
|
144
|
+
# A directory should be pruned if:
|
|
145
|
+
# 1. It's ignored, OR
|
|
146
|
+
# 2. It has inclusions AND the path is neither included nor a parent of any inclusion
|
|
147
|
+
def should_prune_directory?(path)
|
|
148
|
+
return true if ignore?(path)
|
|
149
|
+
return false unless has_inclusions?
|
|
150
|
+
!bidirectional_include?(path)
|
|
151
|
+
end
|
|
152
|
+
|
|
143
153
|
private
|
|
144
154
|
def has_ignores?
|
|
145
155
|
@original_ignores.any?
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dotsync
|
|
4
|
+
class ContentDiff
|
|
5
|
+
COLORS = {
|
|
6
|
+
header: 103, # Purple for file headers
|
|
7
|
+
hunk: 36, # Cyan for @@ lines
|
|
8
|
+
addition: 34, # Blue for added lines (consistent with diff_additions)
|
|
9
|
+
deletion: 88, # Red for removed lines (consistent with diff_removals)
|
|
10
|
+
context: 240 # Gray for context lines
|
|
11
|
+
}.freeze
|
|
12
|
+
|
|
13
|
+
def initialize(src_path, dest_path, logger)
|
|
14
|
+
@src_path = src_path
|
|
15
|
+
@dest_path = dest_path
|
|
16
|
+
@logger = logger
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def display
|
|
20
|
+
return unless displayable?
|
|
21
|
+
|
|
22
|
+
diff_output = generate_diff
|
|
23
|
+
return if diff_output.empty?
|
|
24
|
+
|
|
25
|
+
display_header
|
|
26
|
+
colorize_and_display(diff_output)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
def displayable?
|
|
31
|
+
text_file?(@src_path) && text_file?(@dest_path)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def text_file?(path)
|
|
35
|
+
return false unless File.file?(path)
|
|
36
|
+
|
|
37
|
+
# Check if file appears to be text by reading first few bytes
|
|
38
|
+
begin
|
|
39
|
+
sample = File.read(path, 8192) || ""
|
|
40
|
+
# Binary files typically contain null bytes
|
|
41
|
+
!sample.include?("\x00")
|
|
42
|
+
rescue StandardError
|
|
43
|
+
false
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def generate_diff
|
|
48
|
+
# Use system diff with unified format
|
|
49
|
+
# diff returns exit code 1 when files differ, so we can't use backticks directly
|
|
50
|
+
output = `diff -u "#{@dest_path}" "#{@src_path}" 2>/dev/null`
|
|
51
|
+
output.lines.drop(2).join # Drop the first two header lines, we'll add our own
|
|
52
|
+
rescue StandardError
|
|
53
|
+
""
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def display_header
|
|
57
|
+
@logger.log("--- #{@dest_path}", color: COLORS[:header])
|
|
58
|
+
@logger.log("+++ #{@src_path}", color: COLORS[:header])
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def colorize_and_display(diff_output)
|
|
62
|
+
diff_output.each_line do |line|
|
|
63
|
+
color = line_color(line)
|
|
64
|
+
@logger.log(line.chomp, color: color)
|
|
65
|
+
end
|
|
66
|
+
@logger.log("")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def line_color(line)
|
|
70
|
+
case line[0]
|
|
71
|
+
when "+"
|
|
72
|
+
COLORS[:addition]
|
|
73
|
+
when "-"
|
|
74
|
+
COLORS[:deletion]
|
|
75
|
+
when "@"
|
|
76
|
+
COLORS[:hunk]
|
|
77
|
+
else
|
|
78
|
+
COLORS[:context]
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -31,6 +31,7 @@ module Dotsync
|
|
|
31
31
|
def diff_mapping_directories
|
|
32
32
|
additions = []
|
|
33
33
|
modifications = []
|
|
34
|
+
modification_pairs = []
|
|
34
35
|
removals = []
|
|
35
36
|
|
|
36
37
|
Find.find(mapping_src) do |src_path|
|
|
@@ -48,6 +49,7 @@ module Dotsync
|
|
|
48
49
|
elsif File.file?(src_path) && File.file?(dest_path)
|
|
49
50
|
if files_differ?(src_path, dest_path)
|
|
50
51
|
modifications << rel_path
|
|
52
|
+
modification_pairs << { rel_path: rel_path, src: src_path, dest: dest_path }
|
|
51
53
|
end
|
|
52
54
|
end
|
|
53
55
|
end
|
|
@@ -59,6 +61,12 @@ module Dotsync
|
|
|
59
61
|
|
|
60
62
|
src_path = File.join(mapping_src, rel_path)
|
|
61
63
|
|
|
64
|
+
# Prune entire directory trees that are outside the inclusion list or ignored
|
|
65
|
+
if File.directory?(dest_path) && @mapping.should_prune_directory?(src_path)
|
|
66
|
+
Find.prune
|
|
67
|
+
next
|
|
68
|
+
end
|
|
69
|
+
|
|
62
70
|
next if @mapping.skip?(src_path)
|
|
63
71
|
|
|
64
72
|
if !File.exist?(src_path)
|
|
@@ -67,21 +75,29 @@ module Dotsync
|
|
|
67
75
|
end
|
|
68
76
|
end
|
|
69
77
|
|
|
78
|
+
filtered_modifications = filter_ignores(modifications)
|
|
79
|
+
modification_pairs = modification_pairs.select { |pair| filtered_modifications.include?(pair[:rel_path]) }
|
|
80
|
+
|
|
70
81
|
additions = relative_to_absolute(filter_ignores(additions), mapping_original_dest)
|
|
71
|
-
modifications = relative_to_absolute(
|
|
82
|
+
modifications = relative_to_absolute(filtered_modifications, mapping_original_dest)
|
|
72
83
|
removals = relative_to_absolute(filter_ignores(removals), mapping_original_dest)
|
|
73
84
|
|
|
74
|
-
Dotsync::Diff.new(additions: additions, modifications: modifications, removals: removals)
|
|
85
|
+
Dotsync::Diff.new(additions: additions, modifications: modifications, removals: removals, modification_pairs: modification_pairs)
|
|
75
86
|
end
|
|
76
87
|
|
|
77
88
|
def diff_mapping_files
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
89
|
+
additions = []
|
|
90
|
+
modifications = []
|
|
91
|
+
modification_pairs = []
|
|
92
|
+
|
|
93
|
+
if @mapping.file_present_in_src_only?
|
|
94
|
+
additions << @mapping.original_dest
|
|
95
|
+
elsif @mapping.file_changed?
|
|
96
|
+
modifications << @mapping.original_dest
|
|
97
|
+
modification_pairs << { rel_path: File.basename(@mapping.original_dest), src: @mapping.src, dest: @mapping.dest }
|
|
84
98
|
end
|
|
99
|
+
|
|
100
|
+
Dotsync::Diff.new(additions: additions, modifications: modifications, modification_pairs: modification_pairs)
|
|
85
101
|
end
|
|
86
102
|
|
|
87
103
|
def filter_ignores(all_paths)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dotsync
|
|
4
|
+
# Simple thread-based parallel execution for independent operations.
|
|
5
|
+
# Uses a configurable thread pool to process items concurrently.
|
|
6
|
+
module Parallel
|
|
7
|
+
# Default number of threads (matches typical CPU core count)
|
|
8
|
+
DEFAULT_THREADS = 4
|
|
9
|
+
|
|
10
|
+
# Executes a block for each item in the collection using parallel threads.
|
|
11
|
+
# Returns results in the same order as the input collection.
|
|
12
|
+
#
|
|
13
|
+
# @param items [Array] Collection of items to process
|
|
14
|
+
# @param threads [Integer] Number of parallel threads (default: 4)
|
|
15
|
+
# @yield [item] Block to execute for each item
|
|
16
|
+
# @return [Array] Results in same order as input
|
|
17
|
+
#
|
|
18
|
+
# @example
|
|
19
|
+
# results = Dotsync::Parallel.map(urls, threads: 8) do |url|
|
|
20
|
+
# fetch(url)
|
|
21
|
+
# end
|
|
22
|
+
def self.map(items, threads: DEFAULT_THREADS, &block)
|
|
23
|
+
return [] if items.empty?
|
|
24
|
+
return items.map(&block) if items.size == 1
|
|
25
|
+
|
|
26
|
+
# Limit threads to item count
|
|
27
|
+
thread_count = [threads, items.size].min
|
|
28
|
+
|
|
29
|
+
# Create indexed work items
|
|
30
|
+
work_queue = Queue.new
|
|
31
|
+
items.each_with_index { |item, idx| work_queue << [idx, item] }
|
|
32
|
+
|
|
33
|
+
# Results array (pre-sized for thread safety with index assignment)
|
|
34
|
+
results = Array.new(items.size)
|
|
35
|
+
mutex = Mutex.new
|
|
36
|
+
errors = []
|
|
37
|
+
|
|
38
|
+
# Spawn worker threads
|
|
39
|
+
workers = thread_count.times.map do
|
|
40
|
+
Thread.new do
|
|
41
|
+
loop do
|
|
42
|
+
idx, item = work_queue.pop(true) rescue break
|
|
43
|
+
begin
|
|
44
|
+
results[idx] = yield(item)
|
|
45
|
+
rescue => e
|
|
46
|
+
mutex.synchronize { errors << e }
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Wait for completion
|
|
53
|
+
workers.each(&:join)
|
|
54
|
+
|
|
55
|
+
# Re-raise first error if any occurred
|
|
56
|
+
raise errors.first unless errors.empty?
|
|
57
|
+
|
|
58
|
+
results
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Executes a block for each item in parallel, ignoring return values.
|
|
62
|
+
# Useful for side-effect operations like file transfers.
|
|
63
|
+
#
|
|
64
|
+
# @param items [Array] Collection of items to process
|
|
65
|
+
# @param threads [Integer] Number of parallel threads (default: 4)
|
|
66
|
+
# @yield [item] Block to execute for each item
|
|
67
|
+
def self.each(items, threads: DEFAULT_THREADS, &block)
|
|
68
|
+
map(items, threads: threads, &block)
|
|
69
|
+
nil
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
data/lib/dotsync/version.rb
CHANGED
data/lib/dotsync.rb
CHANGED
|
@@ -31,6 +31,7 @@ require_relative "dotsync/utils/file_transfer"
|
|
|
31
31
|
require_relative "dotsync/utils/directory_differ"
|
|
32
32
|
require_relative "dotsync/utils/version_checker"
|
|
33
33
|
require_relative "dotsync/utils/config_cache"
|
|
34
|
+
require_relative "dotsync/utils/parallel"
|
|
34
35
|
|
|
35
36
|
# Models
|
|
36
37
|
require_relative "dotsync/models/mapping"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dotsync
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Sáenz
|
|
@@ -334,9 +334,11 @@ files:
|
|
|
334
334
|
- lib/dotsync/runner.rb
|
|
335
335
|
- lib/dotsync/tasks/actions.rake
|
|
336
336
|
- lib/dotsync/utils/config_cache.rb
|
|
337
|
+
- lib/dotsync/utils/content_diff.rb
|
|
337
338
|
- lib/dotsync/utils/directory_differ.rb
|
|
338
339
|
- lib/dotsync/utils/file_transfer.rb
|
|
339
340
|
- lib/dotsync/utils/logger.rb
|
|
341
|
+
- lib/dotsync/utils/parallel.rb
|
|
340
342
|
- lib/dotsync/utils/path_utils.rb
|
|
341
343
|
- lib/dotsync/utils/version_checker.rb
|
|
342
344
|
- lib/dotsync/version.rb
|