knife-essentials 0.1
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/LICENSE +201 -0
- data/README.rdoc +114 -0
- data/Rakefile +24 -0
- data/lib/chef/knife/diff.rb +28 -0
- data/lib/chef/knife/list.rb +107 -0
- data/lib/chef/knife/show.rb +30 -0
- data/lib/chef_fs.rb +9 -0
- data/lib/chef_fs/command_line.rb +91 -0
- data/lib/chef_fs/diff.rb +158 -0
- data/lib/chef_fs/file_pattern.rb +292 -0
- data/lib/chef_fs/file_system.rb +69 -0
- data/lib/chef_fs/file_system/base_fs_dir.rb +23 -0
- data/lib/chef_fs/file_system/base_fs_object.rb +52 -0
- data/lib/chef_fs/file_system/chef_server_root_dir.rb +48 -0
- data/lib/chef_fs/file_system/cookbook_dir.rb +80 -0
- data/lib/chef_fs/file_system/cookbook_file.rb +32 -0
- data/lib/chef_fs/file_system/cookbook_subdir.rb +25 -0
- data/lib/chef_fs/file_system/cookbooks_dir.rb +21 -0
- data/lib/chef_fs/file_system/data_bag_dir.rb +22 -0
- data/lib/chef_fs/file_system/data_bags_dir.rb +23 -0
- data/lib/chef_fs/file_system/file_system_entry.rb +36 -0
- data/lib/chef_fs/file_system/file_system_root_dir.rb +11 -0
- data/lib/chef_fs/file_system/nonexistent_fs_object.rb +23 -0
- data/lib/chef_fs/file_system/not_found_exception.rb +12 -0
- data/lib/chef_fs/file_system/rest_list_dir.rb +42 -0
- data/lib/chef_fs/file_system/rest_list_entry.rb +72 -0
- data/lib/chef_fs/knife.rb +47 -0
- data/lib/chef_fs/path_utils.rb +43 -0
- data/lib/chef_fs/version.rb +4 -0
- data/spec/chef_fs/diff_spec.rb +263 -0
- data/spec/chef_fs/file_pattern_spec.rb +507 -0
- data/spec/chef_fs/file_system_spec.rb +117 -0
- data/spec/support/file_system_support.rb +108 -0
- metadata +79 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'chef_fs/file_system/base_fs_object'
|
2
|
+
|
3
|
+
module ChefFS
|
4
|
+
module FileSystem
|
5
|
+
class NonexistentFSObject < BaseFSObject
|
6
|
+
def initialize(name, parent)
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def exists?
|
11
|
+
false
|
12
|
+
end
|
13
|
+
|
14
|
+
def child(name)
|
15
|
+
NonexistentFSObject.new(name, self)
|
16
|
+
end
|
17
|
+
|
18
|
+
def read
|
19
|
+
raise ChefFS::FileSystem::NotFoundException, "Nonexistent object"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module ChefFS
|
2
|
+
module FileSystem
|
3
|
+
class NotFoundException < Exception
|
4
|
+
def initialize(other_exception)
|
5
|
+
super(other_exception.respond_to?(:message) ? other_exception.message : message)
|
6
|
+
@exception = other_exception
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :exception
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'chef_fs/file_system/base_fs_dir'
|
2
|
+
require 'chef_fs/file_system/rest_list_entry'
|
3
|
+
|
4
|
+
# TODO: take environment into account
|
5
|
+
|
6
|
+
module ChefFS
|
7
|
+
module FileSystem
|
8
|
+
class RestListDir < BaseFSDir
|
9
|
+
def initialize(name, parent, api_path = nil)
|
10
|
+
super(name, parent)
|
11
|
+
@api_path = api_path || (parent.api_path == "" ? name : "#{parent.api_path}/#{name}")
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :api_path
|
15
|
+
|
16
|
+
def child(name)
|
17
|
+
result = @children.select { |child| child.name == name }.first if @children
|
18
|
+
result || RestListEntry.new(name, self)
|
19
|
+
end
|
20
|
+
|
21
|
+
def children
|
22
|
+
begin
|
23
|
+
@children ||= rest.get_rest(api_path).keys.map { |key| RestListEntry.new("#{key}.json", self, true) }
|
24
|
+
rescue Net::HTTPServerException
|
25
|
+
if $!.response.code == "404"
|
26
|
+
raise ChefFS::FileSystem::NotFoundException, $!
|
27
|
+
else
|
28
|
+
raise
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def environment
|
34
|
+
parent.environment
|
35
|
+
end
|
36
|
+
|
37
|
+
def rest
|
38
|
+
parent.rest
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'chef_fs/file_system/base_fs_object'
|
2
|
+
require 'chef_fs/file_system/not_found_exception'
|
3
|
+
# TODO: these are needed for rest.get_rest() to work. This seems strange.
|
4
|
+
require 'chef/role'
|
5
|
+
require 'chef/node'
|
6
|
+
|
7
|
+
# TODO: take environment into account
|
8
|
+
module ChefFS
|
9
|
+
module FileSystem
|
10
|
+
class RestListEntry < BaseFSObject
|
11
|
+
def initialize(name, parent, exists = nil)
|
12
|
+
super(name, parent)
|
13
|
+
@exists = exists
|
14
|
+
end
|
15
|
+
|
16
|
+
def api_path
|
17
|
+
if name.length < 5 && name[-5,5] != ".json"
|
18
|
+
raise "Invalid name #{name}: must include .json"
|
19
|
+
end
|
20
|
+
api_child_name = name[0,name.length-5]
|
21
|
+
environment ? "#{parent.api_path}/#{api_child_name}/environments/#{environment}" : "#{parent.api_path}/#{api_child_name}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def environment
|
25
|
+
parent.environment
|
26
|
+
end
|
27
|
+
|
28
|
+
def exists?
|
29
|
+
if @exists.nil?
|
30
|
+
@exists = parent.children.any? { |child| child.name == name }
|
31
|
+
end
|
32
|
+
@exists
|
33
|
+
end
|
34
|
+
|
35
|
+
def delete
|
36
|
+
begin
|
37
|
+
rest.delete_rest(api_path)
|
38
|
+
rescue Net::HTTPServerException
|
39
|
+
if $!.response.code == "404"
|
40
|
+
raise ChefFS::FileSystem::NotFoundException, $!
|
41
|
+
else
|
42
|
+
raise
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def read
|
48
|
+
begin
|
49
|
+
Chef::JSONCompat.to_json_pretty(rest.get_rest(api_path).to_hash)
|
50
|
+
rescue Net::HTTPServerException
|
51
|
+
if $!.response.code == "404"
|
52
|
+
raise ChefFS::FileSystem::NotFoundException, $!
|
53
|
+
else
|
54
|
+
raise
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def rest
|
60
|
+
parent.rest
|
61
|
+
end
|
62
|
+
|
63
|
+
def content_type
|
64
|
+
:json
|
65
|
+
end
|
66
|
+
|
67
|
+
def write(contents)
|
68
|
+
rest.put_rest(api_path, contents)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'chef_fs/file_system/chef_server_root_dir'
|
2
|
+
require 'chef_fs/file_system/file_system_root_dir'
|
3
|
+
require 'chef_fs/file_pattern'
|
4
|
+
require 'chef_fs/path_utils'
|
5
|
+
require 'chef/config'
|
6
|
+
|
7
|
+
module ChefFS
|
8
|
+
class Knife < Chef::Knife
|
9
|
+
def base_path
|
10
|
+
@base_path ||= "/" + ChefFS::PathUtils::relative_to(File.absolute_path(Dir.pwd), chef_repo)
|
11
|
+
end
|
12
|
+
|
13
|
+
def chef_fs
|
14
|
+
@chef_fs ||= ChefFS::FileSystem::ChefServerRootDir.new("remote", Chef::Config)
|
15
|
+
end
|
16
|
+
|
17
|
+
def chef_repo
|
18
|
+
@chef_repo ||= File.absolute_path(File.join(Chef::Config.cookbook_path, ".."))
|
19
|
+
end
|
20
|
+
|
21
|
+
def format_path(path)
|
22
|
+
if path[0,base_path.length] == base_path
|
23
|
+
if path == base_path
|
24
|
+
return "."
|
25
|
+
elsif path[base_path.length] == "/"
|
26
|
+
return path[base_path.length + 1, path.length - base_path.length - 1]
|
27
|
+
elsif base_path == "/" && path[0] == "/"
|
28
|
+
return path[1, path.length - 1]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
path
|
32
|
+
end
|
33
|
+
|
34
|
+
def local_fs
|
35
|
+
@local_fs ||= ChefFS::FileSystem::FileSystemRootDir.new(chef_repo)
|
36
|
+
end
|
37
|
+
|
38
|
+
def pattern_args
|
39
|
+
@pattern_args ||= pattern_args_from(name_args)
|
40
|
+
end
|
41
|
+
|
42
|
+
def pattern_args_from(args)
|
43
|
+
args.map { |arg| ChefFS::FilePattern::relative_to(base_path, arg) }.to_a
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'chef_fs'
|
2
|
+
|
3
|
+
module ChefFS
|
4
|
+
class PathUtils
|
5
|
+
|
6
|
+
# If you are in 'source', this is what you would have to type to reach 'dest'
|
7
|
+
# relative_to('/a/b/c/d/e', '/a/b/x/y') == '../../c/d/e'
|
8
|
+
# relative_to('/a/b', '/a/b') == ''
|
9
|
+
def self.relative_to(dest, source)
|
10
|
+
# Skip past the common parts
|
11
|
+
source_parts = ChefFS::PathUtils.split(source)
|
12
|
+
dest_parts = ChefFS::PathUtils.split(dest)
|
13
|
+
i = 0
|
14
|
+
until i >= source_parts.length || i >= dest_parts.length || source_parts[i] != source_parts[i]
|
15
|
+
i+=1
|
16
|
+
end
|
17
|
+
# dot-dot up from 'source' to the common ancestor, then
|
18
|
+
# descend to 'dest' from the common ancestor
|
19
|
+
ChefFS::PathUtils.join(*(['..']*(source_parts.length-i) + dest_parts[i,dest.length-i]))
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.join(*parts)
|
23
|
+
return "" if parts.length == 0
|
24
|
+
# Determine if it started with a slash
|
25
|
+
absolute = parts[0].length == 0 || parts[0].length > 0 && parts[0][0] =~ /^#{regexp_path_separator}/
|
26
|
+
# Remove leading and trailing slashes from each part so that the join will work (and the slash at the end will go away)
|
27
|
+
parts = parts.map { |part| part.gsub(/^\/|\/$/, "") }
|
28
|
+
# Don't join empty bits
|
29
|
+
result = parts.select { |part| part != "" }.join("/")
|
30
|
+
# Put the / back on
|
31
|
+
absolute ? "/#{result}" : result
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.split(path)
|
35
|
+
path.split(Regexp.new(regexp_path_separator))
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.regexp_path_separator
|
39
|
+
ChefFS::windows? ? '[/\\]' : '/'
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,263 @@
|
|
1
|
+
require 'support/file_system_support'
|
2
|
+
require 'chef_fs/diff'
|
3
|
+
require 'chef_fs/file_pattern'
|
4
|
+
require 'chef_fs/command_line'
|
5
|
+
|
6
|
+
describe ChefFS::Diff do
|
7
|
+
include FileSystemSupport
|
8
|
+
|
9
|
+
context 'with two filesystems with all types of difference' do
|
10
|
+
let(:a) {
|
11
|
+
memory_fs('a', {
|
12
|
+
:both_dirs => {
|
13
|
+
:sub_both_dirs => { :subsub => nil },
|
14
|
+
:sub_both_files => nil,
|
15
|
+
:sub_both_files_different => "a\n",
|
16
|
+
:sub_both_dirs_empty => {},
|
17
|
+
:sub_a_only_dir => { :subsub => nil },
|
18
|
+
:sub_a_only_file => nil,
|
19
|
+
:sub_dir_in_a_file_in_b => {},
|
20
|
+
:sub_file_in_a_dir_in_b => nil
|
21
|
+
},
|
22
|
+
:both_files => nil,
|
23
|
+
:both_files_different => "a\n",
|
24
|
+
:both_dirs_empty => {},
|
25
|
+
:a_only_dir => { :subsub => nil },
|
26
|
+
:a_only_file => nil,
|
27
|
+
:dir_in_a_file_in_b => {},
|
28
|
+
:file_in_a_dir_in_b => nil
|
29
|
+
})
|
30
|
+
}
|
31
|
+
let(:b) {
|
32
|
+
memory_fs('b', {
|
33
|
+
:both_dirs => {
|
34
|
+
:sub_both_dirs => { :subsub => nil },
|
35
|
+
:sub_both_files => nil,
|
36
|
+
:sub_both_files_different => "b\n",
|
37
|
+
:sub_both_dirs_empty => {},
|
38
|
+
:sub_b_only_dir => { :subsub => nil },
|
39
|
+
:sub_b_only_file => nil,
|
40
|
+
:sub_dir_in_a_file_in_b => nil,
|
41
|
+
:sub_file_in_a_dir_in_b => {}
|
42
|
+
},
|
43
|
+
:both_files => nil,
|
44
|
+
:both_files_different => "b\n",
|
45
|
+
:both_dirs_empty => {},
|
46
|
+
:b_only_dir => { :subsub => nil },
|
47
|
+
:b_only_file => nil,
|
48
|
+
:dir_in_a_file_in_b => nil,
|
49
|
+
:file_in_a_dir_in_b => {}
|
50
|
+
})
|
51
|
+
}
|
52
|
+
it 'diffable_leaves' do
|
53
|
+
diffable_leaves_should_yield_paths(a, b, nil,
|
54
|
+
%w(
|
55
|
+
/both_dirs/sub_both_dirs/subsub
|
56
|
+
/both_dirs/sub_both_files
|
57
|
+
/both_dirs/sub_both_files_different
|
58
|
+
/both_dirs/sub_both_dirs_empty
|
59
|
+
/both_dirs/sub_a_only_dir
|
60
|
+
/both_dirs/sub_a_only_file
|
61
|
+
/both_dirs/sub_b_only_dir
|
62
|
+
/both_dirs/sub_b_only_file
|
63
|
+
/both_dirs/sub_dir_in_a_file_in_b
|
64
|
+
/both_dirs/sub_file_in_a_dir_in_b
|
65
|
+
/both_files
|
66
|
+
/both_files_different
|
67
|
+
/both_dirs_empty
|
68
|
+
/a_only_dir
|
69
|
+
/a_only_file
|
70
|
+
/b_only_dir
|
71
|
+
/b_only_file
|
72
|
+
/dir_in_a_file_in_b
|
73
|
+
/file_in_a_dir_in_b
|
74
|
+
))
|
75
|
+
end
|
76
|
+
it 'diffable_leaves_from_pattern(/**file*)' do
|
77
|
+
diffable_leaves_from_pattern_should_yield_paths(pattern('/**file*'), a, b, nil,
|
78
|
+
%w(
|
79
|
+
/both_dirs/sub_both_files
|
80
|
+
/both_dirs/sub_both_files_different
|
81
|
+
/both_dirs/sub_a_only_file
|
82
|
+
/both_dirs/sub_b_only_file
|
83
|
+
/both_dirs/sub_dir_in_a_file_in_b
|
84
|
+
/both_dirs/sub_file_in_a_dir_in_b
|
85
|
+
/both_files
|
86
|
+
/both_files_different
|
87
|
+
/a_only_file
|
88
|
+
/b_only_file
|
89
|
+
/dir_in_a_file_in_b
|
90
|
+
/file_in_a_dir_in_b
|
91
|
+
))
|
92
|
+
end
|
93
|
+
it 'diffable_leaves_from_pattern(/*dir*)' do
|
94
|
+
diffable_leaves_from_pattern_should_yield_paths(pattern('/*dir*'), a, b, nil,
|
95
|
+
%w(
|
96
|
+
/both_dirs/sub_both_dirs/subsub
|
97
|
+
/both_dirs/sub_both_files
|
98
|
+
/both_dirs/sub_both_files_different
|
99
|
+
/both_dirs/sub_both_dirs_empty
|
100
|
+
/both_dirs/sub_a_only_dir
|
101
|
+
/both_dirs/sub_a_only_file
|
102
|
+
/both_dirs/sub_b_only_dir
|
103
|
+
/both_dirs/sub_b_only_file
|
104
|
+
/both_dirs/sub_dir_in_a_file_in_b
|
105
|
+
/both_dirs/sub_file_in_a_dir_in_b
|
106
|
+
/both_dirs_empty
|
107
|
+
/a_only_dir
|
108
|
+
/b_only_dir
|
109
|
+
/dir_in_a_file_in_b
|
110
|
+
/file_in_a_dir_in_b
|
111
|
+
))
|
112
|
+
end
|
113
|
+
it 'ChefFS::CommandLine.diff(/)' do
|
114
|
+
results = []
|
115
|
+
ChefFS::CommandLine.diff(pattern('/'), a, b, nil) do |diff|
|
116
|
+
results << diff.gsub(/\s+\d\d\d\d-\d\d-\d\d\s\d?\d:\d\d:\d\d\.\d{9} -\d\d\d\d/, ' DATE')
|
117
|
+
end
|
118
|
+
results.should =~ [
|
119
|
+
'diff --knife a/both_dirs/sub_both_files_different b/both_dirs/sub_both_files_different
|
120
|
+
--- a/both_dirs/sub_both_files_different DATE
|
121
|
+
+++ b/both_dirs/sub_both_files_different DATE
|
122
|
+
@@ -1 +1 @@
|
123
|
+
-a
|
124
|
+
+b
|
125
|
+
','Common subdirectories: /both_dirs/sub_both_dirs_empty
|
126
|
+
','Only in a/both_dirs: sub_a_only_dir
|
127
|
+
','diff --knife a/both_dirs/sub_a_only_file b/both_dirs/sub_a_only_file
|
128
|
+
deleted file
|
129
|
+
--- a/both_dirs/sub_a_only_file DATE
|
130
|
+
+++ /dev/null DATE
|
131
|
+
@@ -1 +0,0 @@
|
132
|
+
-sub_a_only_file
|
133
|
+
','File b/both_dirs/sub_dir_in_a_file_in_b is a directory while file b/both_dirs/sub_dir_in_a_file_in_b is a regular file
|
134
|
+
','File a/both_dirs/sub_file_in_a_dir_in_b is a regular file while file a/both_dirs/sub_file_in_a_dir_in_b is a directory
|
135
|
+
','Only in b/both_dirs: sub_b_only_dir
|
136
|
+
','diff --knife a/both_dirs/sub_b_only_file b/both_dirs/sub_b_only_file
|
137
|
+
new file
|
138
|
+
--- /dev/null DATE
|
139
|
+
+++ b/both_dirs/sub_b_only_file DATE
|
140
|
+
@@ -0,0 +1 @@
|
141
|
+
+sub_b_only_file
|
142
|
+
','diff --knife a/both_files_different b/both_files_different
|
143
|
+
--- a/both_files_different DATE
|
144
|
+
+++ b/both_files_different DATE
|
145
|
+
@@ -1 +1 @@
|
146
|
+
-a
|
147
|
+
+b
|
148
|
+
','Common subdirectories: /both_dirs_empty
|
149
|
+
','Only in a: a_only_dir
|
150
|
+
','diff --knife a/a_only_file b/a_only_file
|
151
|
+
deleted file
|
152
|
+
--- a/a_only_file DATE
|
153
|
+
+++ /dev/null DATE
|
154
|
+
@@ -1 +0,0 @@
|
155
|
+
-a_only_file
|
156
|
+
','File b/dir_in_a_file_in_b is a directory while file b/dir_in_a_file_in_b is a regular file
|
157
|
+
','File a/file_in_a_dir_in_b is a regular file while file a/file_in_a_dir_in_b is a directory
|
158
|
+
','Only in b: b_only_dir
|
159
|
+
','diff --knife a/b_only_file b/b_only_file
|
160
|
+
new file
|
161
|
+
--- /dev/null DATE
|
162
|
+
+++ b/b_only_file DATE
|
163
|
+
@@ -0,0 +1 @@
|
164
|
+
+b_only_file
|
165
|
+
' ]
|
166
|
+
end
|
167
|
+
it 'ChefFS::CommandLine.diff(/both_dirs)' do
|
168
|
+
results = []
|
169
|
+
ChefFS::CommandLine.diff(pattern('/both_dirs'), a, b, nil) do |diff|
|
170
|
+
results << diff.gsub(/\s+\d\d\d\d-\d\d-\d\d\s\d?\d:\d\d:\d\d\.\d{9} -\d\d\d\d/, ' DATE')
|
171
|
+
end
|
172
|
+
results.should =~ [
|
173
|
+
'diff --knife a/both_dirs/sub_both_files_different b/both_dirs/sub_both_files_different
|
174
|
+
--- a/both_dirs/sub_both_files_different DATE
|
175
|
+
+++ b/both_dirs/sub_both_files_different DATE
|
176
|
+
@@ -1 +1 @@
|
177
|
+
-a
|
178
|
+
+b
|
179
|
+
','Common subdirectories: /both_dirs/sub_both_dirs_empty
|
180
|
+
','Only in a/both_dirs: sub_a_only_dir
|
181
|
+
','diff --knife a/both_dirs/sub_a_only_file b/both_dirs/sub_a_only_file
|
182
|
+
deleted file
|
183
|
+
--- a/both_dirs/sub_a_only_file DATE
|
184
|
+
+++ /dev/null DATE
|
185
|
+
@@ -1 +0,0 @@
|
186
|
+
-sub_a_only_file
|
187
|
+
','File b/both_dirs/sub_dir_in_a_file_in_b is a directory while file b/both_dirs/sub_dir_in_a_file_in_b is a regular file
|
188
|
+
','File a/both_dirs/sub_file_in_a_dir_in_b is a regular file while file a/both_dirs/sub_file_in_a_dir_in_b is a directory
|
189
|
+
','Only in b/both_dirs: sub_b_only_dir
|
190
|
+
','diff --knife a/both_dirs/sub_b_only_file b/both_dirs/sub_b_only_file
|
191
|
+
new file
|
192
|
+
--- /dev/null DATE
|
193
|
+
+++ b/both_dirs/sub_b_only_file DATE
|
194
|
+
@@ -0,0 +1 @@
|
195
|
+
+sub_b_only_file
|
196
|
+
' ]
|
197
|
+
end
|
198
|
+
it 'ChefFS::CommandLine.diff(/) with depth 1' do
|
199
|
+
results = []
|
200
|
+
ChefFS::CommandLine.diff(pattern('/'), a, b, 1) do |diff|
|
201
|
+
results << diff.gsub(/\s+\d\d\d\d-\d\d-\d\d\s\d?\d:\d\d:\d\d\.\d{9} -\d\d\d\d/, ' DATE')
|
202
|
+
end
|
203
|
+
results.should =~ [
|
204
|
+
'Common subdirectories: /both_dirs
|
205
|
+
','diff --knife a/both_files_different b/both_files_different
|
206
|
+
--- a/both_files_different DATE
|
207
|
+
+++ b/both_files_different DATE
|
208
|
+
@@ -1 +1 @@
|
209
|
+
-a
|
210
|
+
+b
|
211
|
+
','Common subdirectories: /both_dirs_empty
|
212
|
+
','Only in a: a_only_dir
|
213
|
+
','diff --knife a/a_only_file b/a_only_file
|
214
|
+
deleted file
|
215
|
+
--- a/a_only_file DATE
|
216
|
+
+++ /dev/null DATE
|
217
|
+
@@ -1 +0,0 @@
|
218
|
+
-a_only_file
|
219
|
+
','File b/dir_in_a_file_in_b is a directory while file b/dir_in_a_file_in_b is a regular file
|
220
|
+
','File a/file_in_a_dir_in_b is a regular file while file a/file_in_a_dir_in_b is a directory
|
221
|
+
','Only in b: b_only_dir
|
222
|
+
','diff --knife a/b_only_file b/b_only_file
|
223
|
+
new file
|
224
|
+
--- /dev/null DATE
|
225
|
+
+++ b/b_only_file DATE
|
226
|
+
@@ -0,0 +1 @@
|
227
|
+
+b_only_file
|
228
|
+
' ]
|
229
|
+
end
|
230
|
+
it 'ChefFS::CommandLine.diff(/*_*) with depth 0' do
|
231
|
+
results = []
|
232
|
+
ChefFS::CommandLine.diff(pattern('/*_*'), a, b, 0) do |diff|
|
233
|
+
results << diff.gsub(/\s+\d\d\d\d-\d\d-\d\d\s\d?\d:\d\d:\d\d\.\d{9} -\d\d\d\d/, ' DATE')
|
234
|
+
end
|
235
|
+
results.should =~ [
|
236
|
+
'Common subdirectories: /both_dirs
|
237
|
+
','diff --knife a/both_files_different b/both_files_different
|
238
|
+
--- a/both_files_different DATE
|
239
|
+
+++ b/both_files_different DATE
|
240
|
+
@@ -1 +1 @@
|
241
|
+
-a
|
242
|
+
+b
|
243
|
+
','Common subdirectories: /both_dirs_empty
|
244
|
+
','Only in a: a_only_dir
|
245
|
+
','diff --knife a/a_only_file b/a_only_file
|
246
|
+
deleted file
|
247
|
+
--- a/a_only_file DATE
|
248
|
+
+++ /dev/null DATE
|
249
|
+
@@ -1 +0,0 @@
|
250
|
+
-a_only_file
|
251
|
+
','File b/dir_in_a_file_in_b is a directory while file b/dir_in_a_file_in_b is a regular file
|
252
|
+
','File a/file_in_a_dir_in_b is a regular file while file a/file_in_a_dir_in_b is a directory
|
253
|
+
','Only in b: b_only_dir
|
254
|
+
','diff --knife a/b_only_file b/b_only_file
|
255
|
+
new file
|
256
|
+
--- /dev/null DATE
|
257
|
+
+++ b/b_only_file DATE
|
258
|
+
@@ -0,0 +1 @@
|
259
|
+
+b_only_file
|
260
|
+
' ]
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|