knife-essentials 0.9.8 → 1.0.0.beta1
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.
- data/lib/chef/knife/delete_essentials.rb +3 -3
- data/lib/chef/knife/deps_essentials.rb +1 -1
- data/lib/chef/knife/edit_essentials.rb +1 -1
- data/lib/chef/knife/list_essentials.rb +23 -17
- data/lib/chef/knife/show_essentials.rb +14 -7
- data/lib/chef/knife/xargs_essentials.rb +1 -1
- data/lib/chef_fs/command_line.rb +100 -84
- data/lib/chef_fs/file_system.rb +77 -35
- data/lib/chef_fs/file_system/chef_server_root_dir.rb +7 -7
- data/lib/chef_fs/file_system/cookbook_dir.rb +1 -1
- data/lib/chef_fs/file_system/rest_list_entry.rb +2 -0
- data/lib/chef_fs/knife.rb +24 -4
- data/lib/chef_fs/parallelizer.rb +127 -0
- data/lib/chef_fs/raw_request.rb +8 -4
- data/lib/chef_fs/version.rb +1 -1
- data/spec/integration/chef_repo_path_spec.rb +76 -1
- data/spec/integration/delete_spec.rb +256 -13
- data/spec/integration/deps_spec.rb +20 -20
- data/spec/integration/diff_spec.rb +47 -120
- data/spec/integration/download_spec.rb +92 -237
- data/spec/integration/list_spec.rb +114 -0
- data/spec/integration/redirection_spec.rb +49 -0
- data/spec/integration/upload_spec.rb +120 -305
- data/spec/support/file_system_support.rb +1 -1
- data/spec/support/knife_support.rb +4 -0
- metadata +7 -5
@@ -38,7 +38,7 @@ class Chef
|
|
38
38
|
error = false
|
39
39
|
if config[:remote_only]
|
40
40
|
pattern_args.each do |pattern|
|
41
|
-
ChefFS::FileSystem.list(chef_fs, pattern) do |result|
|
41
|
+
ChefFS::FileSystem.list(chef_fs, pattern).each do |result|
|
42
42
|
if delete_result(result)
|
43
43
|
error = true
|
44
44
|
end
|
@@ -46,7 +46,7 @@ class Chef
|
|
46
46
|
end
|
47
47
|
elsif config[:local_only]
|
48
48
|
pattern_args.each do |pattern|
|
49
|
-
ChefFS::FileSystem.list(local_fs, pattern) do |result|
|
49
|
+
ChefFS::FileSystem.list(local_fs, pattern).each do |result|
|
50
50
|
if delete_result(result)
|
51
51
|
error = true
|
52
52
|
end
|
@@ -54,7 +54,7 @@ class Chef
|
|
54
54
|
end
|
55
55
|
else
|
56
56
|
pattern_args.each do |pattern|
|
57
|
-
ChefFS::FileSystem.list_pairs(pattern, chef_fs, local_fs) do |chef_result, local_result|
|
57
|
+
ChefFS::FileSystem.list_pairs(pattern, chef_fs, local_fs).each do |chef_result, local_result|
|
58
58
|
if delete_result(chef_result, local_result)
|
59
59
|
error = true
|
60
60
|
end
|
@@ -36,7 +36,7 @@ class Chef
|
|
36
36
|
@root = config[:remote] ? chef_fs : local_fs
|
37
37
|
dependencies = {}
|
38
38
|
pattern_args.each do |pattern|
|
39
|
-
ChefFS::FileSystem.list(@root, pattern) do |entry|
|
39
|
+
ChefFS::FileSystem.list(@root, pattern).each do |entry|
|
40
40
|
if config[:tree]
|
41
41
|
print_dependencies_tree(entry, dependencies)
|
42
42
|
else
|
@@ -20,7 +20,7 @@ class Chef
|
|
20
20
|
# Get the matches (recursively)
|
21
21
|
error = false
|
22
22
|
pattern_args.each do |pattern|
|
23
|
-
ChefFS::FileSystem.list(config[:local] ? local_fs : chef_fs, pattern) do |result|
|
23
|
+
ChefFS::FileSystem.list(config[:local] ? local_fs : chef_fs, pattern).each do |result|
|
24
24
|
if result.dir?
|
25
25
|
ui.error "#{format_path(result)}: is a directory" if pattern.exact_path
|
26
26
|
error = true
|
@@ -43,21 +43,28 @@ class Chef
|
|
43
43
|
patterns = name_args.length == 0 ? [""] : name_args
|
44
44
|
|
45
45
|
# Get the matches (recursively)
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
dir_results += add_dir_result(result)
|
52
|
-
elsif result.exists?
|
53
|
-
results << result
|
54
|
-
elsif pattern.exact_path
|
55
|
-
ui.error "#{format_path(result)}: No such file or directory"
|
56
|
-
self.exit_code = 1
|
57
|
-
end
|
46
|
+
all_results = parallelize(pattern_args_from(patterns), :flatten => true) do |pattern|
|
47
|
+
pattern_results = ChefFS::FileSystem.list(config[:local] ? local_fs : chef_fs, pattern)
|
48
|
+
if pattern_results.first && !pattern_results.first.exists? && pattern.exact_path
|
49
|
+
ui.error "#{format_path(pattern_results.first)}: No such file or directory"
|
50
|
+
self.exit_code = 1
|
58
51
|
end
|
52
|
+
pattern_results
|
59
53
|
end
|
60
54
|
|
55
|
+
# Process directories
|
56
|
+
if !config[:bare_directories]
|
57
|
+
dir_results = parallelize(all_results.select { |result| result.dir? }, :flatten => true) do |result|
|
58
|
+
add_dir_result(result)
|
59
|
+
end.to_a
|
60
|
+
else
|
61
|
+
dir_results = []
|
62
|
+
end
|
63
|
+
|
64
|
+
# Process all other results
|
65
|
+
results = all_results.select { |result| result.exists? && (!result.dir? || config[:bare_directories]) }.to_a
|
66
|
+
|
67
|
+
# Flatten out directory results if necessary
|
61
68
|
if config[:flat]
|
62
69
|
dir_results.each do |result, children|
|
63
70
|
results += children
|
@@ -65,9 +72,11 @@ class Chef
|
|
65
72
|
dir_results = []
|
66
73
|
end
|
67
74
|
|
75
|
+
# Sort by path for happy output
|
68
76
|
results = results.sort_by { |result| result.path }
|
69
77
|
dir_results = dir_results.sort_by { |result| result[0].path }
|
70
78
|
|
79
|
+
# Print!
|
71
80
|
if results.length == 0 && dir_results.length == 1
|
72
81
|
results = dir_results[0][1]
|
73
82
|
dir_results = []
|
@@ -98,11 +107,8 @@ class Chef
|
|
98
107
|
|
99
108
|
result = [ [ result, children ] ]
|
100
109
|
if config[:recursive]
|
101
|
-
children.
|
102
|
-
|
103
|
-
result += add_dir_result(child)
|
104
|
-
end
|
105
|
-
end
|
110
|
+
child_dirs = children.select { |child| child.dir? }
|
111
|
+
result += parallelize(child_dirs, :flatten => true) { |child| add_dir_result(child) }.to_a
|
106
112
|
end
|
107
113
|
result
|
108
114
|
end
|
@@ -19,26 +19,33 @@ class Chef
|
|
19
19
|
def run
|
20
20
|
# Get the matches (recursively)
|
21
21
|
error = false
|
22
|
-
pattern_args
|
23
|
-
ChefFS::FileSystem.list(config[:local] ? local_fs : chef_fs, pattern) do |
|
24
|
-
if
|
25
|
-
ui.error "#{format_path(
|
22
|
+
entry_values = parallelize(pattern_args, :flatten => true) do |pattern|
|
23
|
+
parallelize(ChefFS::FileSystem.list(config[:local] ? local_fs : chef_fs, pattern)) do |entry|
|
24
|
+
if entry.dir?
|
25
|
+
ui.error "#{format_path(entry)}: is a directory" if pattern.exact_path
|
26
26
|
error = true
|
27
|
+
nil
|
27
28
|
else
|
28
29
|
begin
|
29
|
-
|
30
|
-
output "#{format_path(result)}:"
|
31
|
-
output(format_for_display(value))
|
30
|
+
[entry, entry.read]
|
32
31
|
rescue ChefFS::FileSystem::OperationNotAllowedError => e
|
33
32
|
ui.error "#{format_path(e.entry)}: #{e.reason}."
|
34
33
|
error = true
|
34
|
+
nil
|
35
35
|
rescue ChefFS::FileSystem::NotFoundError => e
|
36
36
|
ui.error "#{format_path(e.entry)}: No such file or directory"
|
37
37
|
error = true
|
38
|
+
nil
|
38
39
|
end
|
39
40
|
end
|
40
41
|
end
|
41
42
|
end
|
43
|
+
entry_values.each do |entry, value|
|
44
|
+
if entry
|
45
|
+
output "#{format_path(entry)}:"
|
46
|
+
output(format_for_display(value))
|
47
|
+
end
|
48
|
+
end
|
42
49
|
if error
|
43
50
|
exit 1
|
44
51
|
end
|
@@ -74,7 +74,7 @@ class Chef
|
|
74
74
|
# Get the matches (recursively)
|
75
75
|
files = []
|
76
76
|
pattern_args_from(get_patterns).each do |pattern|
|
77
|
-
ChefFS::FileSystem.list(config[:local] ? local_fs : chef_fs, pattern) do |result|
|
77
|
+
ChefFS::FileSystem.list(config[:local] ? local_fs : chef_fs, pattern).each do |result|
|
78
78
|
if result.dir?
|
79
79
|
# TODO option to include directories
|
80
80
|
ui.warn "#{format_path(result)}: is a directory. Will not run #{command} on it."
|
data/lib/chef_fs/command_line.rb
CHANGED
@@ -30,7 +30,7 @@ module ChefFS
|
|
30
30
|
|
31
31
|
get_content = (output_mode != :name_only && output_mode != :name_status)
|
32
32
|
found_match = false
|
33
|
-
diff(pattern, a_root, b_root, recurse_depth, get_content) do |type, old_entry, new_entry, old_value, new_value, error|
|
33
|
+
diff(pattern, a_root, b_root, recurse_depth, get_content).each do |type, old_entry, new_entry, old_value, new_value, error|
|
34
34
|
found_match = true unless type == :both_nonexistent
|
35
35
|
old_path = format_path.call(old_entry)
|
36
36
|
new_path = format_path.call(new_entry)
|
@@ -124,112 +124,128 @@ module ChefFS
|
|
124
124
|
error
|
125
125
|
end
|
126
126
|
|
127
|
-
def self.diff(pattern,
|
128
|
-
ChefFS::FileSystem.list_pairs(pattern,
|
129
|
-
diff_entries(
|
130
|
-
yield diff
|
131
|
-
end
|
127
|
+
def self.diff(pattern, old_root, new_root, recurse_depth, get_content)
|
128
|
+
ChefFS::Parallelizer.parallelize(ChefFS::FileSystem.list_pairs(pattern, old_root, new_root), :flatten => true) do |old_entry, new_entry|
|
129
|
+
diff_entries(old_entry, new_entry, recurse_depth, get_content)
|
132
130
|
end
|
133
131
|
end
|
134
132
|
|
135
133
|
# Diff two known entries (could be files or dirs)
|
136
134
|
def self.diff_entries(old_entry, new_entry, recurse_depth, get_content)
|
137
|
-
|
138
|
-
|
139
|
-
if
|
140
|
-
if
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
ChefFS::
|
145
|
-
diff_entries(old_child, new_child,
|
146
|
-
recurse_depth ? recurse_depth - 1 : nil, get_content) do |diff|
|
147
|
-
yield diff
|
148
|
-
end
|
149
|
-
end
|
135
|
+
# If both are directories
|
136
|
+
if old_entry.dir?
|
137
|
+
if new_entry.dir?
|
138
|
+
if recurse_depth == 0
|
139
|
+
return [ [ :common_subdirectories, old_entry, new_entry ] ]
|
140
|
+
else
|
141
|
+
return ChefFS::Parallelizer.parallelize(ChefFS::FileSystem.child_pairs(old_entry, new_entry), :flatten => true) do |old_child, new_child|
|
142
|
+
ChefFS::CommandLine.diff_entries(old_child, new_child, recurse_depth ? recurse_depth - 1 : nil, get_content)
|
150
143
|
end
|
144
|
+
end
|
151
145
|
|
152
146
|
# If old is a directory and new is a file
|
153
|
-
|
154
|
-
|
147
|
+
elsif new_entry.exists?
|
148
|
+
return [ [ :directory_to_file, old_entry, new_entry ] ]
|
155
149
|
|
156
150
|
# If old is a directory and new does not exist
|
157
|
-
|
158
|
-
|
159
|
-
end
|
151
|
+
elsif new_entry.parent.can_have_child?(old_entry.name, old_entry.dir?)
|
152
|
+
return [ [ :deleted, old_entry, new_entry ] ]
|
160
153
|
|
161
|
-
# If new
|
162
|
-
|
163
|
-
|
164
|
-
|
154
|
+
# If the new entry does not and *cannot* exist, report that.
|
155
|
+
else
|
156
|
+
return [ [ :new_cannot_upload, old_entry, new_entry ] ]
|
157
|
+
end
|
158
|
+
|
159
|
+
# If new is a directory and old is a file
|
160
|
+
elsif new_entry.dir?
|
161
|
+
if old_entry.exists?
|
162
|
+
return [ [ :file_to_directory, old_entry, new_entry ] ]
|
165
163
|
|
166
164
|
# If new is a directory and old does not exist
|
167
|
-
|
168
|
-
|
169
|
-
end
|
165
|
+
elsif old_entry.parent.can_have_child?(new_entry.name, new_entry.dir?)
|
166
|
+
return [ [ :added, old_entry, new_entry ] ]
|
170
167
|
|
171
|
-
#
|
168
|
+
# If the new entry does not and *cannot* exist, report that.
|
172
169
|
else
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
170
|
+
return [ [ :old_cannot_upload, old_entry, new_entry ] ]
|
171
|
+
end
|
172
|
+
|
173
|
+
# Neither is a directory, so they are diffable with file diff
|
174
|
+
else
|
175
|
+
are_same, old_value, new_value = ChefFS::FileSystem.compare(old_entry, new_entry)
|
176
|
+
if are_same
|
177
|
+
if old_value == :none
|
178
|
+
return [ [ :both_nonexistent, old_entry, new_entry ] ]
|
180
179
|
else
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
180
|
+
return [ [ :same, old_entry, new_entry ] ]
|
181
|
+
end
|
182
|
+
else
|
183
|
+
if old_value == :none
|
184
|
+
old_exists = false
|
185
|
+
elsif old_value.nil?
|
186
|
+
old_exists = old_entry.exists?
|
187
|
+
else
|
188
|
+
old_exists = true
|
189
|
+
end
|
188
190
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
191
|
+
if new_value == :none
|
192
|
+
new_exists = false
|
193
|
+
elsif new_value.nil?
|
194
|
+
new_exists = new_entry.exists?
|
195
|
+
else
|
196
|
+
new_exists = true
|
197
|
+
end
|
196
198
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
return
|
206
|
-
end
|
199
|
+
# If one of the files doesn't exist, we only want to print the diff if the
|
200
|
+
# other file *could be uploaded/downloaded*.
|
201
|
+
if !old_exists && !old_entry.parent.can_have_child?(new_entry.name, new_entry.dir?)
|
202
|
+
return [ [ :old_cannot_upload, old_entry, new_entry ] ]
|
203
|
+
end
|
204
|
+
if !new_exists && !new_entry.parent.can_have_child?(old_entry.name, old_entry.dir?)
|
205
|
+
return [ [ :new_cannot_upload, old_entry, new_entry ] ]
|
206
|
+
end
|
207
207
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
end
|
215
|
-
begin
|
216
|
-
new_value = new_entry.read if new_value.nil?
|
217
|
-
rescue ChefFS::FileSystem::NotFoundError
|
218
|
-
new_value = :none
|
219
|
-
end
|
208
|
+
if get_content
|
209
|
+
# If we haven't read the values yet, get them now so that they can be diffed
|
210
|
+
begin
|
211
|
+
old_value = old_entry.read if old_value.nil?
|
212
|
+
rescue ChefFS::FileSystem::NotFoundError
|
213
|
+
old_value = :none
|
220
214
|
end
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
yield [ :deleted, old_entry, new_entry, old_value, new_value ]
|
226
|
-
else
|
227
|
-
yield [ :modified, old_entry, new_entry, old_value, new_value ]
|
215
|
+
begin
|
216
|
+
new_value = new_entry.read if new_value.nil?
|
217
|
+
rescue ChefFS::FileSystem::NotFoundError
|
218
|
+
new_value = :none
|
228
219
|
end
|
229
220
|
end
|
221
|
+
|
222
|
+
if old_value == :none || (old_value == nil && !old_entry.exists?)
|
223
|
+
return [ [ :added, old_entry, new_entry, old_value, new_value ] ]
|
224
|
+
elsif new_value == :none
|
225
|
+
return [ [ :deleted, old_entry, new_entry, old_value, new_value ] ]
|
226
|
+
else
|
227
|
+
return [ [ :modified, old_entry, new_entry, old_value, new_value ] ]
|
228
|
+
end
|
230
229
|
end
|
231
|
-
|
232
|
-
|
230
|
+
end
|
231
|
+
rescue ChefFS::FileSystem::FileSystemError => e
|
232
|
+
return [ [ :error, old_entry, new_entry, nil, nil, e ] ]
|
233
|
+
end
|
234
|
+
|
235
|
+
class Differ
|
236
|
+
def initialize(old_entry, new_entry, recurse_depth, get_content)
|
237
|
+
@old_entry = old_entry
|
238
|
+
@new_entry = new_entry
|
239
|
+
@recurse_depth = recurse_depth
|
240
|
+
@get_content = get_content
|
241
|
+
end
|
242
|
+
|
243
|
+
attr_reader :old_entry
|
244
|
+
attr_reader :new_entry
|
245
|
+
attr_reader :recurse_depth
|
246
|
+
attr_reader :get_content
|
247
|
+
|
248
|
+
def each
|
233
249
|
end
|
234
250
|
end
|
235
251
|
|
data/lib/chef_fs/file_system.rb
CHANGED
@@ -20,39 +20,59 @@ require 'chef_fs/path_utils'
|
|
20
20
|
require 'chef_fs/file_system/default_environment_cannot_be_modified_error'
|
21
21
|
require 'chef_fs/file_system/operation_failed_error'
|
22
22
|
require 'chef_fs/file_system/operation_not_allowed_error'
|
23
|
+
require 'chef_fs/parallelizer'
|
23
24
|
|
24
25
|
module ChefFS
|
25
26
|
module FileSystem
|
26
|
-
#
|
27
|
+
# Returns a list of all things under (and including) this entry that match the
|
27
28
|
# given pattern.
|
28
29
|
#
|
29
30
|
# ==== Attributes
|
30
31
|
#
|
31
|
-
# * +
|
32
|
+
# * +root+ - Entry to start listing under
|
32
33
|
# * +pattern+ - ChefFS::FilePattern to match children under
|
33
34
|
#
|
34
|
-
def self.list(
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
def self.list(root, pattern)
|
36
|
+
Lister.new(root, pattern)
|
37
|
+
end
|
38
|
+
|
39
|
+
class Lister
|
40
|
+
include Enumerable
|
41
|
+
|
42
|
+
def initialize(root, pattern)
|
43
|
+
@root = root
|
44
|
+
@pattern = pattern
|
38
45
|
end
|
39
46
|
|
40
|
-
|
41
|
-
|
42
|
-
exact_child_name = pattern.exact_child_name_under(entry.path)
|
47
|
+
attr_reader :root
|
48
|
+
attr_reader :pattern
|
43
49
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
50
|
+
def each(&block)
|
51
|
+
list_from(root, &block)
|
52
|
+
end
|
53
|
+
|
54
|
+
def list_from(entry, &block)
|
55
|
+
# Include self in results if it matches
|
56
|
+
if pattern.match?(entry.path)
|
57
|
+
block.call(entry)
|
58
|
+
end
|
59
|
+
|
60
|
+
if pattern.could_match_children?(entry.path)
|
61
|
+
# If it's possible that our children could match, descend in and add matches.
|
62
|
+
exact_child_name = pattern.exact_child_name_under(entry.path)
|
63
|
+
|
64
|
+
# If we've got an exact name, don't bother listing children; just grab the
|
65
|
+
# child with the given name.
|
66
|
+
if exact_child_name
|
67
|
+
exact_child = entry.child(exact_child_name)
|
68
|
+
if exact_child
|
69
|
+
list_from(exact_child, &block)
|
70
|
+
end
|
51
71
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
72
|
+
# Otherwise, go through all children and find any matches
|
73
|
+
elsif entry.dir?
|
74
|
+
results = Parallelizer::parallelize(entry.children, :flatten => true) { |child| ChefFS::FileSystem.list(child, pattern) }
|
75
|
+
results.each(&block)
|
56
76
|
end
|
57
77
|
end
|
58
78
|
end
|
@@ -118,7 +138,7 @@ module ChefFS
|
|
118
138
|
def self.copy_to(pattern, src_root, dest_root, recurse_depth, options, ui, format_path)
|
119
139
|
found_result = false
|
120
140
|
error = false
|
121
|
-
list_pairs(pattern, src_root, dest_root) do |src, dest|
|
141
|
+
parallel_do(list_pairs(pattern, src_root, dest_root)) do |src, dest|
|
122
142
|
found_result = true
|
123
143
|
new_dest_parent = get_or_create_parent(dest, options, ui, format_path)
|
124
144
|
child_error = copy_entries(src, dest, new_dest_parent, recurse_depth, options, ui, format_path)
|
@@ -142,26 +162,44 @@ module ChefFS
|
|
142
162
|
#
|
143
163
|
# ==== Example
|
144
164
|
#
|
145
|
-
# ChefFS::FileSystem.list_pairs(FilePattern.new('**x.txt', a_root, b_root)) do |a, b|
|
165
|
+
# ChefFS::FileSystem.list_pairs(FilePattern.new('**x.txt', a_root, b_root)).each do |a, b|
|
146
166
|
# ...
|
147
167
|
# end
|
148
168
|
#
|
149
169
|
def self.list_pairs(pattern, a_root, b_root)
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
170
|
+
PairLister.new(pattern, a_root, b_root)
|
171
|
+
end
|
172
|
+
|
173
|
+
class PairLister
|
174
|
+
include Enumerable
|
175
|
+
|
176
|
+
def initialize(pattern, a_root, b_root)
|
177
|
+
@pattern = pattern
|
178
|
+
@a_root = a_root
|
179
|
+
@b_root = b_root
|
156
180
|
end
|
157
181
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
182
|
+
attr_reader :pattern
|
183
|
+
attr_reader :a_root
|
184
|
+
attr_reader :b_root
|
185
|
+
|
186
|
+
def each
|
187
|
+
# Make sure everything on the server is also on the filesystem, and diff
|
188
|
+
found_paths = Set.new
|
189
|
+
ChefFS::FileSystem.list(a_root, pattern).each do |a|
|
190
|
+
found_paths << a.path
|
191
|
+
b = ChefFS::FileSystem.resolve_path(b_root, a.path)
|
163
192
|
yield [ a, b ]
|
164
193
|
end
|
194
|
+
|
195
|
+
# Check the outer regex pattern to see if it matches anything on the
|
196
|
+
# filesystem that isn't on the server
|
197
|
+
ChefFS::FileSystem.list(b_root, pattern).each do |b|
|
198
|
+
if !found_paths.include?(b.path)
|
199
|
+
a = ChefFS::FileSystem.resolve_path(a_root, b.path)
|
200
|
+
yield [ a, b ]
|
201
|
+
end
|
202
|
+
end
|
165
203
|
end
|
166
204
|
end
|
167
205
|
|
@@ -204,6 +242,7 @@ module ChefFS
|
|
204
242
|
are_same, b_value, a_value = b.compare_to(a)
|
205
243
|
end
|
206
244
|
if are_same.nil?
|
245
|
+
# TODO these reads can be parallelized
|
207
246
|
begin
|
208
247
|
a_value = a.read if a_value.nil?
|
209
248
|
rescue ChefFS::FileSystem::NotFoundError
|
@@ -276,7 +315,7 @@ module ChefFS
|
|
276
315
|
end
|
277
316
|
# Directory creation is recursive.
|
278
317
|
if recurse_depth != 0
|
279
|
-
src_entry.children
|
318
|
+
parallel_do(src_entry.children) do |src_child|
|
280
319
|
new_dest_child = new_dest_dir.child(src_child.name)
|
281
320
|
child_error = copy_entries(src_child, new_dest_child, new_dest_dir, recurse_depth ? recurse_depth - 1 : recurse_depth, options, ui, format_path)
|
282
321
|
error ||= child_error
|
@@ -313,7 +352,7 @@ module ChefFS
|
|
313
352
|
if dest_entry.dir?
|
314
353
|
# If both are directories, recurse into their children
|
315
354
|
if recurse_depth != 0
|
316
|
-
child_pairs(src_entry, dest_entry)
|
355
|
+
parallel_do(child_pairs(src_entry, dest_entry)) do |src_child, dest_child|
|
317
356
|
child_error = copy_entries(src_child, dest_child, dest_entry, recurse_depth ? recurse_depth - 1 : recurse_depth, options, ui, format_path)
|
318
357
|
error ||= child_error
|
319
358
|
end
|
@@ -376,5 +415,8 @@ module ChefFS
|
|
376
415
|
return parent
|
377
416
|
end
|
378
417
|
|
418
|
+
def self.parallel_do(enum, options = {}, &block)
|
419
|
+
ChefFS::Parallelizer.parallelize(enum, options, &block).to_a
|
420
|
+
end
|
379
421
|
end
|
380
422
|
end
|