knife-essentials 0.8.3 → 0.8.4
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/chef/knife/diff_essentials.rb +2 -2
- data/lib/chef/knife/download_essentials.rb +5 -1
- data/lib/chef/knife/list_essentials.rb +2 -1
- data/lib/chef/knife/upload_essentials.rb +5 -1
- data/lib/chef_fs/command_line.rb +94 -63
- data/lib/chef_fs/file_system.rb +113 -93
- data/lib/chef_fs/file_system/base_fs_object.rb +91 -37
- data/lib/chef_fs/file_system/chef_repository_file_system_cookbooks_dir.rb +14 -1
- data/lib/chef_fs/file_system/chef_server_root_dir.rb +2 -1
- data/lib/chef_fs/file_system/cookbook_file.rb +7 -1
- data/lib/chef_fs/file_system/cookbooks_dir.rb +13 -6
- data/lib/chef_fs/file_system/environments_dir.rb +59 -0
- data/lib/chef_fs/file_system/multiplexed_dir.rb +1 -1
- data/lib/chef_fs/file_system/nodes_dir.rb +1 -0
- data/lib/chef_fs/file_system/operation_not_allowed_error.rb +29 -0
- data/lib/chef_fs/file_system/operation_skipped_error.rb +29 -0
- data/lib/chef_fs/knife.rb +29 -21
- data/lib/chef_fs/version.rb +1 -1
- data/spec/chef_fs/diff_spec.rb +30 -30
- data/spec/chef_fs/file_system/cookbooks_dir_spec.rb +5 -1
- data/spec/integration/chef_repo_path_spec.rb +705 -0
- data/spec/integration/chef_repository_file_system_spec.rb +82 -713
- data/spec/integration/chefignore_spec.rb +258 -0
- data/spec/integration/diff_spec.rb +151 -0
- data/spec/integration/download_spec.rb +403 -0
- data/spec/integration/list_spec.rb +21 -21
- data/spec/integration/upload_spec.rb +407 -0
- data/spec/support/integration_helper.rb +9 -4
- data/spec/support/knife_support.rb +14 -2
- metadata +12 -3
@@ -37,8 +37,8 @@ class Chef
|
|
37
37
|
|
38
38
|
# Get the matches (recursively)
|
39
39
|
patterns.each do |pattern|
|
40
|
-
ChefFS::CommandLine.
|
41
|
-
|
40
|
+
ChefFS::CommandLine.diff_print(pattern, chef_fs, local_fs, config[:recurse] ? nil : 1, output_mode, proc { |entry| format_path(entry.path) } ) do |diff|
|
41
|
+
stdout.print diff
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
@@ -42,8 +42,12 @@ class Chef
|
|
42
42
|
exit 1
|
43
43
|
end
|
44
44
|
|
45
|
+
error = false
|
45
46
|
pattern_args.each do |pattern|
|
46
|
-
ChefFS::FileSystem.copy_to(pattern, chef_fs, local_fs, config[:recurse] ? nil : 1, config, ui)
|
47
|
+
error ||= ChefFS::FileSystem.copy_to(pattern, chef_fs, local_fs, config[:recurse] ? nil : 1, config, ui, proc { |entry| format_path(entry.path) })
|
48
|
+
end
|
49
|
+
if error
|
50
|
+
exit 1
|
47
51
|
end
|
48
52
|
end
|
49
53
|
end
|
@@ -6,7 +6,7 @@ class Chef
|
|
6
6
|
remove_const(:List) if const_defined?(:List) && List.name == 'Chef::Knife::List' # override Chef's version
|
7
7
|
class List < ::ChefFS::Knife
|
8
8
|
ChefFS = ::ChefFS
|
9
|
-
banner "knife list [-
|
9
|
+
banner "knife list [-dfR1p] [PATTERN1 ... PATTERNn]"
|
10
10
|
|
11
11
|
common_options
|
12
12
|
|
@@ -23,6 +23,7 @@ class Chef
|
|
23
23
|
:boolean => true,
|
24
24
|
:description => "List local directory instead of remote"
|
25
25
|
option :flat,
|
26
|
+
:short => '-f',
|
26
27
|
:long => '--flat',
|
27
28
|
:boolean => true,
|
28
29
|
:description => "Show a list of filenames rather than the prettified ls-like output normally produced"
|
@@ -42,8 +42,12 @@ class Chef
|
|
42
42
|
exit 1
|
43
43
|
end
|
44
44
|
|
45
|
+
error = false
|
45
46
|
pattern_args.each do |pattern|
|
46
|
-
ChefFS::FileSystem.copy_to(pattern, local_fs, chef_fs, config[:recurse] ? nil : 1, config, ui)
|
47
|
+
error ||= ChefFS::FileSystem.copy_to(pattern, local_fs, chef_fs, config[:recurse] ? nil : 1, config, ui, proc { |entry| format_path(entry.path) })
|
48
|
+
end
|
49
|
+
if error
|
50
|
+
exit 1
|
47
51
|
end
|
48
52
|
end
|
49
53
|
end
|
data/lib/chef_fs/command_line.rb
CHANGED
@@ -20,10 +20,85 @@ require 'chef_fs/file_system'
|
|
20
20
|
|
21
21
|
module ChefFS
|
22
22
|
module CommandLine
|
23
|
-
|
23
|
+
|
24
|
+
def self.diff_print(pattern, a_root, b_root, recurse_depth, output_mode, format_path = nil)
|
25
|
+
if format_path.nil?
|
26
|
+
format_path = proc { |entry| entry.path_for_printing }
|
27
|
+
end
|
28
|
+
|
29
|
+
get_content = (output_mode != :name_only && output_mode != :name_status)
|
30
|
+
diff(pattern, a_root, b_root, recurse_depth, get_content) do |type, old_entry, new_entry, old_value, new_value|
|
31
|
+
old_path = format_path.call(old_entry)
|
32
|
+
new_path = format_path.call(new_entry)
|
33
|
+
|
34
|
+
if get_content && old_value && new_value
|
35
|
+
result = ''
|
36
|
+
result << "diff --knife #{old_path} #{new_path}\n"
|
37
|
+
if old_value == :none
|
38
|
+
result << "new file\n"
|
39
|
+
old_path = "/dev/null"
|
40
|
+
old_value = ''
|
41
|
+
end
|
42
|
+
if new_value == :none
|
43
|
+
result << "deleted file\n"
|
44
|
+
new_path = "/dev/null"
|
45
|
+
new_value = ''
|
46
|
+
end
|
47
|
+
result << diff_text(old_path, new_path, old_value, new_value)
|
48
|
+
yield result
|
49
|
+
else
|
50
|
+
case type
|
51
|
+
when :common_subdirectories
|
52
|
+
if output_mode != :name_only && output_mode != :name_status
|
53
|
+
yield "Common subdirectories: #{new_path}\n"
|
54
|
+
end
|
55
|
+
when :directory_to_file
|
56
|
+
if output_mode == :name_only
|
57
|
+
yield "#{new_path}\n"
|
58
|
+
elsif output_mode == :name_status
|
59
|
+
yield "T\t#{new_path}\n"
|
60
|
+
else
|
61
|
+
yield "File #{old_path} is a directory while file #{new_path} is a regular file\n"
|
62
|
+
end
|
63
|
+
when :file_to_directory
|
64
|
+
if output_mode == :name_only
|
65
|
+
yield "#{new_path}\n"
|
66
|
+
elsif output_mode == :name_status
|
67
|
+
yield "T\t#{new_path}\n"
|
68
|
+
else
|
69
|
+
yield "File #{old_path} is a regular file while file #{new_path} is a directory\n"
|
70
|
+
end
|
71
|
+
when :deleted
|
72
|
+
if output_mode == :name_only
|
73
|
+
yield "#{new_path}\n"
|
74
|
+
elsif output_mode == :name_status
|
75
|
+
yield "D\t#{new_path}\n"
|
76
|
+
else
|
77
|
+
yield "Only in #{format_path.call(old_entry.parent)}: #{old_entry.name}\n"
|
78
|
+
end
|
79
|
+
when :added
|
80
|
+
if output_mode == :name_only
|
81
|
+
yield "#{new_path}\n"
|
82
|
+
elsif output_mode == :name_status
|
83
|
+
yield "A\t#{new_path}\n"
|
84
|
+
else
|
85
|
+
yield "Only in #{format_path.call(new_entry.parent)}: #{new_entry.name}\n"
|
86
|
+
end
|
87
|
+
when :modified
|
88
|
+
if output_mode == :name_only
|
89
|
+
yield "#{new_path}\n"
|
90
|
+
elsif output_mode == :name_status
|
91
|
+
yield "M\t#{new_path}\n"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.diff(pattern, a_root, b_root, recurse_depth, get_content)
|
24
99
|
found_result = false
|
25
100
|
ChefFS::FileSystem.list_pairs(pattern, a_root, b_root) do |a, b|
|
26
|
-
existed = diff_entries(a, b, recurse_depth,
|
101
|
+
existed = diff_entries(a, b, recurse_depth, get_content) do |diff|
|
27
102
|
yield diff
|
28
103
|
end
|
29
104
|
found_result = true if existed
|
@@ -34,18 +109,16 @@ module ChefFS
|
|
34
109
|
end
|
35
110
|
|
36
111
|
# Diff two known entries (could be files or dirs)
|
37
|
-
def self.diff_entries(old_entry, new_entry, recurse_depth,
|
112
|
+
def self.diff_entries(old_entry, new_entry, recurse_depth, get_content)
|
38
113
|
# If both are directories
|
39
114
|
if old_entry.dir?
|
40
115
|
if new_entry.dir?
|
41
116
|
if recurse_depth == 0
|
42
|
-
|
43
|
-
yield "Common subdirectories: #{old_entry.path}\n"
|
44
|
-
end
|
117
|
+
yield [ :common_subdirectories, old_entry, new_entry ]
|
45
118
|
else
|
46
119
|
ChefFS::FileSystem.child_pairs(old_entry, new_entry).each do |old_child,new_child|
|
47
120
|
diff_entries(old_child, new_child,
|
48
|
-
recurse_depth ? recurse_depth - 1 : nil,
|
121
|
+
recurse_depth ? recurse_depth - 1 : nil, get_content) do |diff|
|
49
122
|
yield diff
|
50
123
|
end
|
51
124
|
end
|
@@ -53,45 +126,21 @@ module ChefFS
|
|
53
126
|
|
54
127
|
# If old is a directory and new is a file
|
55
128
|
elsif new_entry.exists?
|
56
|
-
|
57
|
-
yield "#{new_entry.path_for_printing}\n"
|
58
|
-
elsif output_mode == :name_status
|
59
|
-
yield "T\t#{new_entry.path_for_printing}\n"
|
60
|
-
else
|
61
|
-
yield "File #{new_entry.path_for_printing} is a directory while file #{new_entry.path_for_printing} is a regular file\n"
|
62
|
-
end
|
129
|
+
yield [ :directory_to_file, old_entry, new_entry ]
|
63
130
|
|
64
131
|
# If old is a directory and new does not exist
|
65
132
|
elsif new_entry.parent.can_have_child?(old_entry.name, old_entry.dir?)
|
66
|
-
|
67
|
-
yield "#{new_entry.path_for_printing}\n"
|
68
|
-
elsif output_mode == :name_status
|
69
|
-
yield "D\t#{new_entry.path_for_printing}\n"
|
70
|
-
else
|
71
|
-
yield "Only in #{old_entry.parent.path_for_printing}: #{old_entry.name}\n"
|
72
|
-
end
|
133
|
+
yield [ :deleted, old_entry, new_entry ]
|
73
134
|
end
|
74
135
|
|
75
136
|
# If new is a directory and old is a file
|
76
137
|
elsif new_entry.dir?
|
77
138
|
if old_entry.exists?
|
78
|
-
|
79
|
-
yield "#{new_entry.path_for_printing}\n"
|
80
|
-
elsif output_mode == :name_status
|
81
|
-
yield "T\t#{new_entry.path_for_printing}\n"
|
82
|
-
else
|
83
|
-
yield "File #{old_entry.path_for_printing} is a regular file while file #{old_entry.path_for_printing} is a directory\n"
|
84
|
-
end
|
139
|
+
yield [ :file_to_directory, old_entry, new_entry ]
|
85
140
|
|
86
141
|
# If new is a directory and old does not exist
|
87
142
|
elsif old_entry.parent.can_have_child?(new_entry.name, new_entry.dir?)
|
88
|
-
|
89
|
-
yield "#{new_entry.path_for_printing}\n"
|
90
|
-
elsif output_mode == :name_status
|
91
|
-
yield "A\t#{new_entry.path_for_printing}\n"
|
92
|
-
else
|
93
|
-
yield "Only in #{new_entry.parent.path_for_printing}: #{new_entry.name}\n"
|
94
|
-
end
|
143
|
+
yield [ :added, old_entry, new_entry ]
|
95
144
|
end
|
96
145
|
|
97
146
|
# Neither is a directory, so they are diffable with file diff
|
@@ -107,6 +156,7 @@ module ChefFS
|
|
107
156
|
else
|
108
157
|
old_exists = true
|
109
158
|
end
|
159
|
+
|
110
160
|
if new_value == :none
|
111
161
|
new_exists = false
|
112
162
|
elsif new_value.nil?
|
@@ -124,18 +174,8 @@ module ChefFS
|
|
124
174
|
return true
|
125
175
|
end
|
126
176
|
|
127
|
-
if
|
128
|
-
|
129
|
-
elsif output_mode == :name_status
|
130
|
-
if old_value == :none || (old_value == nil && !old_entry.exists?)
|
131
|
-
yield "A\t#{new_entry.path_for_printing}\n"
|
132
|
-
elsif new_value == :none
|
133
|
-
yield "D\t#{new_entry.path_for_printing}\n"
|
134
|
-
else
|
135
|
-
yield "M\t#{new_entry.path_for_printing}\n"
|
136
|
-
end
|
137
|
-
else
|
138
|
-
# If we haven't read the values yet, get them now.
|
177
|
+
if get_content
|
178
|
+
# If we haven't read the values yet, get them now so that they can be diffed
|
139
179
|
begin
|
140
180
|
old_value = old_entry.read if old_value.nil?
|
141
181
|
rescue ChefFS::FileSystem::NotFoundError
|
@@ -146,23 +186,14 @@ module ChefFS
|
|
146
186
|
rescue ChefFS::FileSystem::NotFoundError
|
147
187
|
new_value = :none
|
148
188
|
end
|
189
|
+
end
|
149
190
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
old_path = "/dev/null"
|
157
|
-
old_value = ''
|
158
|
-
end
|
159
|
-
if new_value == :none
|
160
|
-
result << "deleted file\n"
|
161
|
-
new_path = "/dev/null"
|
162
|
-
new_value = ''
|
163
|
-
end
|
164
|
-
result << diff_text(old_path, new_path, old_value, new_value)
|
165
|
-
yield result
|
191
|
+
if old_value == :none || (old_value == nil && !old_entry.exists?)
|
192
|
+
yield [ :added, old_entry, new_entry, old_value, new_value ]
|
193
|
+
elsif new_value == :none
|
194
|
+
yield [ :deleted, old_entry, new_entry, old_value, new_value ]
|
195
|
+
else
|
196
|
+
yield [ :modified, old_entry, new_entry, old_value, new_value ]
|
166
197
|
end
|
167
198
|
end
|
168
199
|
end
|
data/lib/chef_fs/file_system.rb
CHANGED
@@ -17,6 +17,8 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
require 'chef_fs/path_utils'
|
20
|
+
require 'chef_fs/file_system/operation_skipped_error'
|
21
|
+
require 'chef_fs/file_system/operation_not_allowed_error'
|
20
22
|
|
21
23
|
module ChefFS
|
22
24
|
module FileSystem
|
@@ -112,16 +114,20 @@ module ChefFS
|
|
112
114
|
# puts message
|
113
115
|
# end
|
114
116
|
#
|
115
|
-
def self.copy_to(pattern, src_root, dest_root, recurse_depth, options, ui)
|
117
|
+
def self.copy_to(pattern, src_root, dest_root, recurse_depth, options, ui, format_path)
|
116
118
|
found_result = false
|
119
|
+
error = false
|
117
120
|
list_pairs(pattern, src_root, dest_root) do |src, dest|
|
118
121
|
found_result = true
|
119
|
-
new_dest_parent = get_or_create_parent(dest, options, ui)
|
120
|
-
copy_entries(src, dest, new_dest_parent, recurse_depth, options, ui)
|
122
|
+
new_dest_parent = get_or_create_parent(dest, options, ui, format_path)
|
123
|
+
child_error = copy_entries(src, dest, new_dest_parent, recurse_depth, options, ui, format_path)
|
124
|
+
error ||= child_error
|
121
125
|
end
|
122
126
|
if !found_result && pattern.exact_path
|
123
127
|
ui.error "#{pattern}: No such file or directory on remote or local"
|
128
|
+
error = true
|
124
129
|
end
|
130
|
+
error
|
125
131
|
end
|
126
132
|
|
127
133
|
# Yield entries for children that are in either +a_root+ or +b_root+, with
|
@@ -215,7 +221,7 @@ module ChefFS
|
|
215
221
|
private
|
216
222
|
|
217
223
|
# Copy two entries (could be files or dirs)
|
218
|
-
def self.copy_entries(src_entry, dest_entry, new_dest_parent, recurse_depth, options, ui)
|
224
|
+
def self.copy_entries(src_entry, dest_entry, new_dest_parent, recurse_depth, options, ui, format_path)
|
219
225
|
# A NOTE about this algorithm:
|
220
226
|
# There are cases where this algorithm does too many network requests.
|
221
227
|
# knife upload with a specific filename will first check if the file
|
@@ -227,126 +233,140 @@ module ChefFS
|
|
227
233
|
# exist.
|
228
234
|
# Will need to decide how that works with checksums, though.
|
229
235
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
+
error = false
|
237
|
+
begin
|
238
|
+
dest_path = format_path.call(dest_entry)
|
239
|
+
src_path = format_path.call(src_entry)
|
240
|
+
if !src_entry.exists?
|
241
|
+
if options[:purge]
|
242
|
+
# If we would not have uploaded it, we will not purge it.
|
243
|
+
if src_entry.parent.can_have_child?(dest_entry.name, dest_entry.dir?)
|
244
|
+
if options[:dry_run]
|
245
|
+
ui.output "Would delete #{dest_path}"
|
246
|
+
else
|
247
|
+
dest_entry.delete(true)
|
248
|
+
ui.output "Deleted extra entry #{dest_path} (purge is on)"
|
249
|
+
end
|
236
250
|
else
|
237
|
-
|
238
|
-
ui.output "Deleted extra entry #{dest_entry.path_for_printing} (purge is on)"
|
251
|
+
Chef::Log.info("Not deleting extra entry #{dest_path} (purge is off)")
|
239
252
|
end
|
240
|
-
else
|
241
|
-
Chef::Log.info("Not deleting extra entry #{dest_entry.path_for_printing} (purge is off)")
|
242
253
|
end
|
243
|
-
end
|
244
254
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
255
|
+
elsif !dest_entry.exists?
|
256
|
+
if new_dest_parent.can_have_child?(src_entry.name, src_entry.dir?)
|
257
|
+
# If the entry can do a copy directly from filesystem, do that.
|
258
|
+
if new_dest_parent.respond_to?(:create_child_from)
|
259
|
+
if options[:dry_run]
|
260
|
+
ui.output "Would create #{dest_path}"
|
261
|
+
else
|
262
|
+
new_dest_parent.create_child_from(src_entry)
|
263
|
+
ui.output "Created #{dest_path}"
|
264
|
+
end
|
265
|
+
return
|
254
266
|
end
|
255
|
-
return
|
256
|
-
end
|
257
267
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
268
|
+
if src_entry.dir?
|
269
|
+
if options[:dry_run]
|
270
|
+
ui.output "Would create #{dest_path}"
|
271
|
+
new_dest_dir = new_dest_parent.child(src_entry.name)
|
272
|
+
else
|
273
|
+
new_dest_dir = new_dest_parent.create_child(src_entry.name, nil)
|
274
|
+
ui.output "Created #{dest_path}"
|
275
|
+
end
|
276
|
+
# Directory creation is recursive.
|
277
|
+
if recurse_depth != 0
|
278
|
+
src_entry.children.each do |src_child|
|
279
|
+
new_dest_child = new_dest_dir.child(src_child.name)
|
280
|
+
child_error = copy_entries(src_child, new_dest_child, new_dest_dir, recurse_depth ? recurse_depth - 1 : recurse_depth, options, ui, format_path)
|
281
|
+
error ||= child_error
|
282
|
+
end
|
271
283
|
end
|
272
|
-
end
|
273
|
-
else
|
274
|
-
if options[:dry_run]
|
275
|
-
ui.output "Would create #{dest_entry.path_for_printing}"
|
276
284
|
else
|
277
|
-
|
278
|
-
|
285
|
+
if options[:dry_run]
|
286
|
+
ui.output "Would create #{dest_path}"
|
287
|
+
else
|
288
|
+
new_dest_parent.create_child(src_entry.name, src_entry.read)
|
289
|
+
ui.output "Created #{dest_path}"
|
290
|
+
end
|
279
291
|
end
|
280
292
|
end
|
281
|
-
end
|
282
|
-
|
283
|
-
else
|
284
|
-
# Both exist.
|
285
293
|
|
286
|
-
|
287
|
-
|
288
|
-
if options[:force] || compare(src_entry, dest_entry)[0] == false
|
289
|
-
if options[:dry_run]
|
290
|
-
ui.output "Would update #{dest_entry.path_for_printing}"
|
291
|
-
else
|
292
|
-
dest_entry.copy_from(src_entry)
|
293
|
-
ui.output "Updated #{dest_entry.path_for_printing}"
|
294
|
-
end
|
295
|
-
end
|
296
|
-
return
|
297
|
-
end
|
294
|
+
else
|
295
|
+
# Both exist.
|
298
296
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
297
|
+
# If the entry can do a copy directly, do that.
|
298
|
+
if dest_entry.respond_to?(:copy_from)
|
299
|
+
if options[:force] || compare(src_entry, dest_entry)[0] == false
|
300
|
+
if options[:dry_run]
|
301
|
+
ui.output "Would update #{dest_path}"
|
302
|
+
else
|
303
|
+
dest_entry.copy_from(src_entry)
|
304
|
+
ui.output "Updated #{dest_path}"
|
306
305
|
end
|
307
306
|
end
|
308
|
-
else
|
309
|
-
# If they are different types.
|
310
|
-
ui.error("File #{dest_entry.path_for_printing} is a directory while file #{dest_entry.path_for_printing} is a regular file\n")
|
311
307
|
return
|
312
308
|
end
|
313
|
-
else
|
314
|
-
if dest_entry.dir?
|
315
|
-
ui.error("File #{dest_entry.path_for_printing} is a directory while file #{dest_entry.path_for_printing} is a regular file\n")
|
316
|
-
return
|
317
|
-
else
|
318
309
|
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
310
|
+
# If they are different types, log an error.
|
311
|
+
if src_entry.dir?
|
312
|
+
if dest_entry.dir?
|
313
|
+
# If both are directories, recurse into their children
|
314
|
+
if recurse_depth != 0
|
315
|
+
child_pairs(src_entry, dest_entry).each do |src_child, dest_child|
|
316
|
+
child_error = copy_entries(src_child, dest_child, dest_entry, recurse_depth ? recurse_depth - 1 : recurse_depth, options, ui, format_path)
|
317
|
+
error ||= child_error
|
318
|
+
end
|
319
|
+
end
|
323
320
|
else
|
324
|
-
|
325
|
-
|
321
|
+
# If they are different types.
|
322
|
+
ui.error("File #{src_path} is a directory while file #{dest_path} is a regular file\n")
|
323
|
+
return
|
326
324
|
end
|
327
|
-
|
328
|
-
|
329
|
-
|
325
|
+
else
|
326
|
+
if dest_entry.dir?
|
327
|
+
ui.error("File #{src_path} is a directory while file #{dest_path} is a regular file\n")
|
328
|
+
return
|
329
|
+
else
|
330
|
+
|
331
|
+
# Both are files! Copy them unless we're sure they are the same.
|
332
|
+
if options[:force]
|
333
|
+
should_copy = true
|
334
|
+
src_value = nil
|
330
335
|
else
|
331
|
-
src_value = src_entry
|
332
|
-
|
333
|
-
|
336
|
+
are_same, src_value, dest_value = compare(src_entry, dest_entry)
|
337
|
+
should_copy = !are_same
|
338
|
+
end
|
339
|
+
if should_copy
|
340
|
+
if options[:dry_run]
|
341
|
+
ui.output "Would update #{dest_path}"
|
342
|
+
else
|
343
|
+
src_value = src_entry.read if src_value.nil?
|
344
|
+
dest_entry.write(src_value)
|
345
|
+
ui.output "Updated #{dest_path}"
|
346
|
+
end
|
334
347
|
end
|
335
348
|
end
|
336
349
|
end
|
337
350
|
end
|
351
|
+
rescue OperationSkippedError
|
352
|
+
# If it was simply skipped, a warning has already been printed.
|
353
|
+
rescue OperationNotAllowedError => e
|
354
|
+
ui.error e.message
|
355
|
+
error = true
|
338
356
|
end
|
357
|
+
error
|
339
358
|
end
|
340
359
|
|
341
|
-
def self.get_or_create_parent(entry, options, ui)
|
360
|
+
def self.get_or_create_parent(entry, options, ui, format_path)
|
342
361
|
parent = entry.parent
|
343
362
|
if parent && !parent.exists?
|
344
|
-
|
363
|
+
parent_path = format_path.call(parent)
|
364
|
+
parent_parent = get_or_create_parent(entry.parent, options, ui, format_path)
|
345
365
|
if options[:dry_run]
|
346
|
-
ui.output "Would create #{
|
366
|
+
ui.output "Would create #{parent_path}"
|
347
367
|
else
|
348
|
-
parent = parent_parent.create_child(parent.name,
|
349
|
-
ui.output "Created #{
|
368
|
+
parent = parent_parent.create_child(parent.name, nil)
|
369
|
+
ui.output "Created #{parent_path}"
|
350
370
|
end
|
351
371
|
end
|
352
372
|
return parent
|