knife-essentials 1.3.2 → 1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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