knife-essentials 1.3.2 → 1.4

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.
@@ -0,0 +1,83 @@
1
+ #
2
+ # Author:: John Keiser (<jkeiser@opscode.com>)
3
+ # Copyright:: Copyright (c) 2013 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef_fs/file_system/chef_repository_file_system_cookbook_entry'
20
+ require 'chef_fs/file_system/cookbook_dir'
21
+ require 'chef/cookbook/chefignore'
22
+ require 'chef/cookbook/cookbook_version_loader'
23
+
24
+ module ChefFS
25
+ module FileSystem
26
+ class ChefRepositoryFileSystemCookbookDir < ChefRepositoryFileSystemCookbookEntry
27
+ def initialize(name, parent, file_path = nil)
28
+ super(name, parent, file_path)
29
+ end
30
+
31
+ def chef_object
32
+ begin
33
+ loader = Chef::Cookbook::CookbookVersionLoader.new(file_path, parent.chefignore)
34
+ # We need the canonical cookbook name if we are using versioned cookbooks, but we don't
35
+ # want to spend a lot of time adding code to the main Chef libraries
36
+ if Chef::Config[:versioned_cookbooks]
37
+ _canonical_name = canonical_cookbook_name(File.basename(file_path))
38
+ fail "When versioned_cookbooks mode is on, cookbook #{file_path} must match format <cookbook_name>-x.y.z" unless _canonical_name
39
+
40
+ # KLUDGE: We shouldn't have to use instance_variable_set
41
+ loader.instance_variable_set(:@cookbook_name, _canonical_name)
42
+ end
43
+
44
+ loader.load_cookbooks
45
+ return loader.cookbook_version
46
+ rescue
47
+ Chef::Log.error("Could not read #{path_for_printing} into a Chef object: #{$!}")
48
+ end
49
+ nil
50
+ end
51
+
52
+ def children
53
+ Dir.entries(file_path).sort.
54
+ select { |child_name| can_have_child?(child_name, File.directory?(File.join(file_path, child_name))) }.
55
+ map do |child_name|
56
+ segment_info = CookbookDir::COOKBOOK_SEGMENT_INFO[child_name.to_sym] || {}
57
+ ChefRepositoryFileSystemCookbookEntry.new(child_name, self, nil, segment_info[:ruby_only], segment_info[:recursive])
58
+ end.
59
+ select { |entry| !(entry.dir? && entry.children.size == 0) }
60
+ end
61
+
62
+ def can_have_child?(name, is_dir)
63
+ if is_dir
64
+ # Only the given directories will be uploaded.
65
+ return CookbookDir::COOKBOOK_SEGMENT_INFO.keys.include?(name.to_sym) && name != 'root_files'
66
+ end
67
+
68
+ super(name, is_dir)
69
+ end
70
+
71
+ # Exposed as a class method so that it can be used elsewhere
72
+ def self.canonical_cookbook_name(entry_name)
73
+ name_match = ChefFS::FileSystem::CookbookDir::VALID_VERSIONED_COOKBOOK_NAME.match(entry_name)
74
+ return nil if name_match.nil?
75
+ return name_match[1]
76
+ end
77
+
78
+ def canonical_cookbook_name(entry_name)
79
+ self.class.canonical_cookbook_name(entry_name)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,69 @@
1
+ #
2
+ # Author:: John Keiser (<jkeiser@opscode.com>)
3
+ # Copyright:: Copyright (c) 2013 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef_fs/file_system/chef_repository_file_system_entry'
20
+ require 'chef_fs/file_system/chef_repository_file_system_cookbooks_dir'
21
+
22
+ module ChefFS
23
+ module FileSystem
24
+ class ChefRepositoryFileSystemCookbookEntry < ChefRepositoryFileSystemEntry
25
+ def initialize(name, parent, file_path = nil, ruby_only = false, recursive = false)
26
+ super(name, parent, file_path)
27
+ @ruby_only = ruby_only
28
+ @recursive = recursive
29
+ end
30
+
31
+ attr_reader :ruby_only
32
+ attr_reader :recursive
33
+
34
+ def children
35
+ Dir.entries(file_path).sort.
36
+ select { |child_name| can_have_child?(child_name, File.directory?(File.join(file_path, child_name))) }.
37
+ map { |child_name| ChefRepositoryFileSystemCookbookEntry.new(child_name, self, nil, ruby_only, recursive) }.
38
+ select { |entry| !(entry.dir? && entry.children.size == 0) }
39
+ end
40
+
41
+ def can_have_child?(name, is_dir)
42
+ if is_dir
43
+ return recursive && name != '.' && name != '..'
44
+ elsif ruby_only
45
+ return false if name[-3..-1] != '.rb'
46
+ end
47
+
48
+ # Check chefignore
49
+ ignorer = parent
50
+ begin
51
+ if ignorer.is_a?(ChefRepositoryFileSystemCookbooksDir)
52
+ # Grab the path from entry to child
53
+ path_to_child = name
54
+ child = self
55
+ while child.parent != ignorer
56
+ path_to_child = PathUtils.join(child.name, path_to_child)
57
+ child = child.parent
58
+ end
59
+ # Check whether that relative path is ignored
60
+ return !ignorer.chefignore || !ignorer.chefignore.ignored?(path_to_child)
61
+ end
62
+ ignorer = ignorer.parent
63
+ end while ignorer
64
+
65
+ true
66
+ end
67
+ end
68
+ end
69
+ end
@@ -17,6 +17,7 @@
17
17
  #
18
18
 
19
19
  require 'chef_fs/file_system/chef_repository_file_system_entry'
20
+ require 'chef_fs/file_system/chef_repository_file_system_cookbook_dir'
20
21
  require 'chef/cookbook/chefignore'
21
22
 
22
23
  module ChefFS
@@ -34,20 +35,23 @@ module ChefFS
34
35
 
35
36
  attr_reader :chefignore
36
37
 
37
- def ignore_empty_directories?
38
- true
38
+ def children
39
+ Dir.entries(file_path).sort.
40
+ select { |child_name| can_have_child?(child_name, File.directory?(File.join(file_path, child_name))) }.
41
+ map { |child_name| ChefRepositoryFileSystemCookbookDir.new(child_name, self) }.
42
+ select do |entry|
43
+ # empty cookbooks and cookbook directories are ignored
44
+ if entry.children.size == 0
45
+ Chef::Log.warn("Cookbook '#{entry.name}' is empty or entirely chefignored at #{entry.path_for_printing}")
46
+ false
47
+ else
48
+ true
49
+ end
50
+ end
39
51
  end
40
52
 
41
- def ignored?(entry)
42
- return true if !entry.dir?
43
- return true if entry.name.start_with?('.')
44
-
45
- result = super(entry)
46
-
47
- if result
48
- Chef::Log.warn("Cookbook '#{entry.name}' is empty or entirely chefignored at #{entry.path_for_printing}")
49
- end
50
- result
53
+ def can_have_child?(name, is_dir)
54
+ is_dir && !name.start_with?('.')
51
55
  end
52
56
  end
53
57
  end
@@ -26,9 +26,8 @@ module ChefFS
26
26
  super(name, parent, path, ChefFS::DataHandler::DataBagItemDataHandler.new)
27
27
  end
28
28
 
29
- def ignored?(entry)
30
- return true if entry.dir? && entry.name.start_with?('.')
31
- super(entry)
29
+ def can_have_child?(name, is_dir)
30
+ is_dir && !name.start_with?('.')
32
31
  end
33
32
  end
34
33
  end
@@ -18,7 +18,6 @@
18
18
  #
19
19
 
20
20
  require 'chef_fs/file_system/file_system_entry'
21
- require 'chef/cookbook/cookbook_version_loader'
22
21
 
23
22
  module ChefFS
24
23
  module FileSystem
@@ -30,38 +29,12 @@ module ChefFS
30
29
  @data_handler = data_handler
31
30
  end
32
31
 
33
- def chefignore
34
- nil
35
- end
36
-
37
- def ignore_empty_directories?
38
- parent.ignore_empty_directories?
39
- end
40
-
41
32
  def data_handler
42
33
  @data_handler || parent.data_handler
43
34
  end
44
35
 
45
36
  def chef_object
46
37
  begin
47
- if parent.path == '/cookbooks'
48
- loader = Chef::Cookbook::CookbookVersionLoader.new(file_path, parent.chefignore)
49
- # We need the canonical cookbook name if we are using versioned cookbooks, but we don't
50
- # want to spend a lot of time adding code to the main Chef libraries
51
- if Chef::Config[:versioned_cookbooks]
52
-
53
- _canonical_name = canonical_cookbook_name(File.basename(file_path))
54
- fail "When versioned_cookbooks mode is on, cookbook #{file_path} must match format <cookbook_name>-x.y.z" unless _canonical_name
55
-
56
- # KLUDGE: We shouldn't have to use instance_variable_set
57
- loader.instance_variable_set(:@cookbook_name, _canonical_name)
58
- end
59
-
60
- loader.load_cookbooks
61
- return loader.cookbook_version
62
- end
63
-
64
- # Otherwise, inflate the file using the chosen JSON class (if any)
65
38
  return data_handler.chef_object(JSON.parse(read, :create_additions => false))
66
39
  rescue
67
40
  Chef::Log.error("Could not read #{path_for_printing} into a Chef object: #{$!}")
@@ -69,49 +42,15 @@ module ChefFS
69
42
  nil
70
43
  end
71
44
 
72
- # Exposed as a class method so that it can be used elsewhere
73
- def self.canonical_cookbook_name(entry_name)
74
- name_match = ChefFS::FileSystem::CookbookDir::VALID_VERSIONED_COOKBOOK_NAME.match(entry_name)
75
- return nil if name_match.nil?
76
- return name_match[1]
77
- end
78
-
79
- def canonical_cookbook_name(entry_name)
80
- self.class.canonical_cookbook_name(entry_name)
45
+ def can_have_child?(name, is_dir)
46
+ !is_dir && name[-5..-1] == '.json'
81
47
  end
82
48
 
83
49
  def children
50
+ # Except cookbooks and data bag dirs, all things must be json files
84
51
  Dir.entries(file_path).sort.
85
- select { |entry| entry != '.' && entry != '..' }.
86
- map { |entry| ChefRepositoryFileSystemEntry.new(entry, self) }.
87
- select { |entry| !ignored?(entry) }
88
- end
89
-
90
- private
91
-
92
- def ignored?(child_entry)
93
- if child_entry.dir?
94
- # empty cookbooks and cookbook directories are ignored
95
- if ignore_empty_directories? && child_entry.children.size == 0
96
- return true
97
- end
98
- else
99
- ignorer = parent
100
- begin
101
- if ignorer.chefignore
102
- # Grab the path from entry to child
103
- path_to_child = child_entry.name
104
- child = self
105
- while child.parent != ignorer
106
- path_to_child = PathUtils.join(child.name, path_to_child)
107
- child = child.parent
108
- end
109
- # Check whether that relative path is ignored
110
- return ignorer.chefignore.ignored?(path_to_child)
111
- end
112
- ignorer = ignorer.parent
113
- end while ignorer
114
- end
52
+ select { |child_name| can_have_child?(child_name, File.directory?(File.join(file_path, child_name))) }.
53
+ map { |child_name| ChefRepositoryFileSystemEntry.new(child_name, self) }
115
54
  end
116
55
 
117
56
  end
@@ -55,14 +55,6 @@ module ChefFS
55
55
  make_child_entry(name)
56
56
  end
57
57
 
58
- def ignore_empty_directories?
59
- false
60
- end
61
-
62
- def chefignore
63
- nil
64
- end
65
-
66
58
  def json_class
67
59
  nil
68
60
  end
@@ -21,6 +21,7 @@ require 'chef_fs/file_system/cookbook_dir'
21
21
  require 'chef_fs/raw_request'
22
22
  require 'chef_fs/file_system/operation_failed_error'
23
23
  require 'chef_fs/file_system/cookbook_frozen_error'
24
+ require 'chef_fs/file_system/chef_repository_file_system_cookbook_dir'
24
25
 
25
26
  require 'tmpdir'
26
27
 
@@ -84,7 +85,7 @@ module ChefFS
84
85
  # to make this work. So instead, we make a temporary cookbook
85
86
  # symlinking back to real cookbook, and upload the proxy.
86
87
  def upload_versioned_cookbook(other, options)
87
- cookbook_name = ChefFS::FileSystem::ChefRepositoryFileSystemEntry.canonical_cookbook_name(other.name)
88
+ cookbook_name = ChefFS::FileSystem::ChefRepositoryFileSystemCookbookDir.canonical_cookbook_name(other.name)
88
89
 
89
90
  Dir.mktmpdir do |temp_cookbooks_path|
90
91
  proxy_cookbook_path = "#{temp_cookbooks_path}/#{cookbook_name}"
@@ -1,3 +1,3 @@
1
1
  module ChefFS
2
- VERSION = "1.3.2"
2
+ VERSION = "1.4"
3
3
  end
@@ -223,9 +223,11 @@ EOM
223
223
  directory 'clients/blah.json'
224
224
  file 'clients2/blah.json', {}
225
225
  it 'knife show /clients/blah.json succeeds' do
226
- pending "don't count directories in clients" do
227
- knife('show --local /clients/blah.json').should_succeed ''
228
- end
226
+ knife('show --local /clients/blah.json').should_succeed <<EOM
227
+ /clients/blah.json:
228
+ {
229
+ }
230
+ EOM
229
231
  end
230
232
  end
231
233
 
@@ -278,16 +280,14 @@ EOM
278
280
  file 'data_bags/blah', ''
279
281
  file 'data_bags2/blah/item.json', ''
280
282
  it 'knife list -Rfp data_bags shows files in blah' do
281
- pending "Don't count files as data bags" do
282
- knife('list --local -Rfp /data_bags').should_succeed <<EOM
283
+ knife('list --local -Rfp /data_bags').should_succeed <<EOM
283
284
  /data_bags/bag/
284
285
  /data_bags/bag/item.json
285
286
  /data_bags/bag2/
286
287
  /data_bags/bag2/item2.json
287
288
  /data_bags/blah/
288
- /data_bags/blah/item1.json
289
+ /data_bags/blah/item.json
289
290
  EOM
290
- end
291
291
  end
292
292
  end
293
293
 
@@ -310,9 +310,11 @@ EOM
310
310
  directory 'environments/blah.json'
311
311
  file 'environments2/blah.json', {}
312
312
  it 'knife show /environments/blah.json succeeds' do
313
- pending "don't count directories in environments" do
314
- knife('show --local /environments/blah.json').should_succeed ''
315
- end
313
+ knife('show --local /environments/blah.json').should_succeed <<EOM
314
+ /environments/blah.json:
315
+ {
316
+ }
317
+ EOM
316
318
  end
317
319
  end
318
320
 
@@ -320,9 +322,11 @@ EOM
320
322
  directory 'nodes/blah.json'
321
323
  file 'nodes2/blah.json', {}
322
324
  it 'knife show /nodes/blah.json succeeds' do
323
- pending "don't count directories in nodes" do
324
- knife('show --local /nodes/blah.json').should_succeed ''
325
- end
325
+ knife('show --local /nodes/blah.json').should_succeed <<EOM
326
+ /nodes/blah.json:
327
+ {
328
+ }
329
+ EOM
326
330
  end
327
331
  end
328
332
 
@@ -330,9 +334,11 @@ EOM
330
334
  directory 'roles/blah.json'
331
335
  file 'roles2/blah.json', {}
332
336
  it 'knife show /roles/blah.json succeeds' do
333
- pending "don't count directories in roles" do
334
- knife('show --local /roles/blah.json').should_succeed ''
335
- end
337
+ knife('show --local /roles/blah.json').should_succeed <<EOM
338
+ /roles/blah.json:
339
+ {
340
+ }
341
+ EOM
336
342
  end
337
343
  end
338
344
 
@@ -340,9 +346,11 @@ EOM
340
346
  directory 'users/blah.json'
341
347
  file 'users2/blah.json', {}
342
348
  it 'knife show /users/blah.json succeeds' do
343
- pending "don't count directories in users" do
344
- knife('show --local /users/blah.json').should_succeed ''
345
- end
349
+ knife('show --local /users/blah.json').should_succeed <<EOM
350
+ /users/blah.json:
351
+ {
352
+ }
353
+ EOM
346
354
  end
347
355
  end
348
356
 
@@ -119,8 +119,7 @@ EOM
119
119
  end
120
120
 
121
121
  it "knife list --local -Rfp / should NOT return them" do
122
- pending "Decide whether this is a good/bad idea" do
123
- knife('list --local -Rfp /').should_succeed <<EOM
122
+ knife('list --local -Rfp /').should_succeed <<EOM
124
123
  /data_bags/
125
124
  /data_bags/bag1/
126
125
  /data_bags/bag1/item1.json
@@ -129,7 +128,6 @@ EOM
129
128
  /roles/
130
129
  /roles/role1.json
131
130
  EOM
132
- end
133
131
  end
134
132
  end
135
133
 
@@ -188,8 +186,7 @@ EOM
188
186
  end
189
187
 
190
188
  it "knife list --local -Rfp / should NOT return them" do
191
- pending "Decide whether this is a good idea" do
192
- knife('list --local -Rfp /').should_succeed <<EOM
189
+ knife('list --local -Rfp /').should_succeed <<EOM
193
190
  /cookbooks/
194
191
  /cookbooks/cookbook1/
195
192
  /cookbooks/cookbook1/a.rb
@@ -222,7 +219,6 @@ EOM
222
219
  /cookbooks/cookbook1/templates/c/d.rb
223
220
  /cookbooks/cookbook1/templates/c/e.json
224
221
  EOM
225
- end
226
222
  end
227
223
  end
228
224
 
@@ -238,11 +234,9 @@ EOM
238
234
  when_the_repository "has a file in data_bags/" do
239
235
  file 'data_bags/file', ''
240
236
  it 'does not show up in list -Rfp' do
241
- pending "don't show files when only directories are allowed" do
242
- knife('list --local -Rfp /').should_succeed <<EOM
237
+ knife('list --local -Rfp /').should_succeed <<EOM
243
238
  /data_bags/
244
239
  EOM
245
- end
246
240
  end
247
241
  end
248
242
  end
@@ -31,14 +31,10 @@ describe 'chefignore tests' do
31
31
  /cookbooks/cookbook1/x.json
32
32
  /data_bags/
33
33
  /data_bags/bag1/
34
- /data_bags/bag1/chefignore
35
34
  /data_bags/bag1/x.json
36
- /data_bags/chefignore
37
35
  /environments/
38
- /environments/chefignore
39
36
  /environments/x.json
40
37
  /roles/
41
- /roles/chefignore
42
38
  /roles/x.json
43
39
  EOM
44
40
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-essentials
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: '1.4'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-12 00:00:00.000000000 Z
12
+ date: 2013-06-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: chef
@@ -150,6 +150,8 @@ files:
150
150
  - lib/chef_fs/file_system/already_exists_error.rb
151
151
  - lib/chef_fs/file_system/base_fs_dir.rb
152
152
  - lib/chef_fs/file_system/base_fs_object.rb
153
+ - lib/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb
154
+ - lib/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb
153
155
  - lib/chef_fs/file_system/chef_repository_file_system_cookbooks_dir.rb
154
156
  - lib/chef_fs/file_system/chef_repository_file_system_data_bags_dir.rb
155
157
  - lib/chef_fs/file_system/chef_repository_file_system_entry.rb