berkshelf 2.0.1 → 2.0.3
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/CHANGELOG.md +11 -0
- data/berkshelf.gemspec +1 -1
- data/features/upload_command.feature +31 -0
- data/lib/berkshelf.rb +5 -5
- data/lib/berkshelf/berksfile.rb +16 -28
- data/lib/berkshelf/cookbook_generator.rb +10 -2
- data/lib/berkshelf/errors.rb +16 -2
- data/lib/berkshelf/git.rb +6 -7
- data/lib/berkshelf/mixin.rb +7 -0
- data/lib/berkshelf/mixin/dsl_eval.rb +58 -0
- data/lib/berkshelf/thor_ext.rb +3 -0
- data/lib/{thor/monkies → berkshelf/thor_ext}/hash_with_indifferent_access.rb +0 -0
- data/lib/{thor/monkies → berkshelf/thor_ext}/shell.rb +0 -0
- data/lib/berkshelf/version.rb +1 -1
- data/spec/unit/berkshelf/berksfile_spec.rb +20 -26
- data/spec/unit/berkshelf/cookbook_generator_spec.rb +10 -0
- data/spec/unit/berkshelf/mixin/dsl_eval_spec.rb +55 -0
- metadata +11 -9
- data/lib/berkshelf/command.rb +0 -116
- data/lib/berkshelf/mixin/shellout.rb +0 -71
- data/lib/thor/monkies.rb +0 -3
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
# 2.0.3
|
2
|
+
|
3
|
+
* Fix issue where groups defined in the Berksfile would not be evaluated
|
4
|
+
|
5
|
+
# 2.0.2
|
6
|
+
|
7
|
+
* Fix issue with shellout on Windows. This would effect uploads and downloads of cookbooks using the Git location.
|
8
|
+
* The Berksfile DSL now evaluates in a clean room to prevent end-users from calling restricted methods.
|
9
|
+
* Fix issue with `berks upload -D` not properly skipping dependencies
|
10
|
+
* Added friendly error message when an unknown license is chosen during cookbook generation
|
11
|
+
|
1
12
|
# 2.0.1
|
2
13
|
|
3
14
|
* Improve performance of `berks upload`. It will now properly respect the Lockfile
|
data/berkshelf.gemspec
CHANGED
@@ -38,7 +38,7 @@ Gem::Specification.new do |s|
|
|
38
38
|
s.add_dependency 'hashie', '>= 2.0.2'
|
39
39
|
s.add_dependency 'minitar', '~> 0.5.4'
|
40
40
|
s.add_dependency 'retryable', '~> 1.3.3'
|
41
|
-
s.add_dependency 'ridley', '~> 1.0.
|
41
|
+
s.add_dependency 'ridley', '~> 1.0.2'
|
42
42
|
s.add_dependency 'solve', '>= 0.4.4'
|
43
43
|
s.add_dependency 'test-kitchen', '>= 1.0.0.alpha7'
|
44
44
|
s.add_dependency 'thor', '~> 0.18.0'
|
@@ -263,3 +263,34 @@ Feature: Uploading cookbooks to a Chef Server
|
|
263
263
|
The cookbook 'cookbook with spaces' has invalid filenames:
|
264
264
|
"""
|
265
265
|
And the CLI should exit with the status code for error "InvalidCookbookFiles"
|
266
|
+
|
267
|
+
@chef_server @slow_process
|
268
|
+
Scenario: With the --skip-dependencies flag
|
269
|
+
Given the cookbook store has the cookbooks:
|
270
|
+
| fake | 1.0.0 |
|
271
|
+
| ekaf | 2.0.0 |
|
272
|
+
And the cookbook store contains a cookbook "reset" "3.4.5" with dependencies:
|
273
|
+
| fake | ~> 1.0.0 |
|
274
|
+
And I write to "Berksfile" with:
|
275
|
+
"""
|
276
|
+
cookbook 'fake', '1.0.0'
|
277
|
+
cookbook 'ekaf', '2.0.0'
|
278
|
+
cookbook 'reset', '3.4.5'
|
279
|
+
"""
|
280
|
+
And the Chef server does not have the cookbooks:
|
281
|
+
| fake | 1.0.0 |
|
282
|
+
| ekaf | 2.0.0 |
|
283
|
+
| reset | 3.4.5 |
|
284
|
+
When I successfully run `berks upload reset -D`
|
285
|
+
Then the output should contain:
|
286
|
+
"""
|
287
|
+
Uploading reset (3.4.5) to: 'http://localhost:4000/'
|
288
|
+
Uploading fake (1.0.0) to: 'http://localhost:4000/'
|
289
|
+
"""
|
290
|
+
And the Chef server should have the cookbooks:
|
291
|
+
| reset | 3.4.5 |
|
292
|
+
| fake | 1.0.0 |
|
293
|
+
And the Chef server should not have the cookbooks:
|
294
|
+
| ekaf | 2.0.0 |
|
295
|
+
And the exit status should be 0
|
296
|
+
|
data/lib/berkshelf.rb
CHANGED
@@ -14,9 +14,10 @@ require 'tmpdir'
|
|
14
14
|
require 'uri'
|
15
15
|
require 'zlib'
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
require_relative 'berkshelf/core_ext'
|
18
|
+
require_relative 'berkshelf/errors'
|
19
|
+
require_relative 'berkshelf/mixin'
|
20
|
+
require_relative 'berkshelf/thor_ext'
|
20
21
|
|
21
22
|
JSON.create_id = nil
|
22
23
|
|
@@ -24,7 +25,6 @@ module Berkshelf
|
|
24
25
|
DEFAULT_FILENAME = 'Berksfile'.freeze
|
25
26
|
|
26
27
|
class << self
|
27
|
-
require 'berkshelf/mixin/logging'
|
28
28
|
include Berkshelf::Mixin::Logging
|
29
29
|
|
30
30
|
attr_accessor :ui
|
@@ -160,4 +160,4 @@ require_relative 'berkshelf/ui'
|
|
160
160
|
require_relative 'berkshelf/version'
|
161
161
|
|
162
162
|
Ridley.logger = Celluloid.logger = Berkshelf.logger = Logger.new(STDOUT)
|
163
|
-
Berkshelf.logger.level = Logger::WARN
|
163
|
+
Berkshelf.logger.level = Logger::WARN
|
data/lib/berkshelf/berksfile.rb
CHANGED
@@ -1,21 +1,16 @@
|
|
1
1
|
module Berkshelf
|
2
2
|
class Berksfile
|
3
|
-
require 'berkshelf/mixin/logging'
|
4
|
-
include Berkshelf::Mixin::Logging
|
5
|
-
|
6
|
-
extend Forwardable
|
7
|
-
|
8
3
|
class << self
|
9
|
-
# @param [
|
4
|
+
# @param [#to_s] file
|
10
5
|
# a path on disk to a Berksfile to instantiate from
|
11
6
|
#
|
12
7
|
# @return [Berksfile]
|
13
8
|
def from_file(file)
|
14
|
-
|
15
|
-
|
16
|
-
object.load(content)
|
17
|
-
rescue Errno::ENOENT => e
|
9
|
+
new(file).dsl_eval_file(file)
|
10
|
+
rescue Errno::ENOENT => ex
|
18
11
|
raise BerksfileNotFound, "No Berksfile or Berksfile.lock found at: #{file}"
|
12
|
+
rescue => ex
|
13
|
+
raise BerksfileReadError.new(ex)
|
19
14
|
end
|
20
15
|
|
21
16
|
# Copy all cached_cookbooks to the given directory. Each cookbook will be contained in
|
@@ -60,6 +55,16 @@ module Berkshelf
|
|
60
55
|
end
|
61
56
|
end
|
62
57
|
|
58
|
+
include Berkshelf::Mixin::Logging
|
59
|
+
include Berkshelf::Mixin::DSLEval
|
60
|
+
extend Forwardable
|
61
|
+
|
62
|
+
expose_method :metadata
|
63
|
+
expose_method :group
|
64
|
+
expose_method :site
|
65
|
+
expose_method :chef_api
|
66
|
+
expose_method :cookbook
|
67
|
+
|
63
68
|
@@active_group = nil
|
64
69
|
|
65
70
|
# @return [String]
|
@@ -549,7 +554,7 @@ module Berkshelf
|
|
549
554
|
end
|
550
555
|
|
551
556
|
if options[:skip_dependencies]
|
552
|
-
missing_cookbooks = options.fetch(:cookbooks, nil) -
|
557
|
+
missing_cookbooks = options.fetch(:cookbooks, nil) - cached_cookbooks.map(&:cookbook_name)
|
553
558
|
unless missing_cookbooks.empty?
|
554
559
|
msg = "Unable to upload cookbooks: #{missing_cookbooks.sort.join(', ')}\n"
|
555
560
|
msg << "Specified cookbooks must be defined within the Berkshelf file when using the"
|
@@ -681,23 +686,6 @@ module Berkshelf
|
|
681
686
|
{ solution: resolver.resolve, sources: resolver.sources }
|
682
687
|
end
|
683
688
|
|
684
|
-
# Reload this instance of Berksfile with the given content. The content
|
685
|
-
# is a string that may contain terms from the included DSL.
|
686
|
-
#
|
687
|
-
# @param [String] content
|
688
|
-
#
|
689
|
-
# @raise [BerksfileReadError] if Berksfile contains bad content
|
690
|
-
#
|
691
|
-
# @return [Berksfile]
|
692
|
-
def load(content)
|
693
|
-
begin
|
694
|
-
instance_eval(content)
|
695
|
-
rescue => e
|
696
|
-
raise BerksfileReadError.new(e)
|
697
|
-
end
|
698
|
-
self
|
699
|
-
end
|
700
|
-
|
701
689
|
# Get the lockfile corresponding to this Berksfile. This is necessary because
|
702
690
|
# the user can specify a different path to the Berksfile. So assuming the lockfile
|
703
691
|
# is named "Berksfile.lock" is a poor assumption.
|
@@ -2,6 +2,14 @@ module Berkshelf
|
|
2
2
|
class CookbookGenerator < BaseGenerator
|
3
3
|
require_relative 'config'
|
4
4
|
|
5
|
+
LICENSES = [
|
6
|
+
"apachev2",
|
7
|
+
"gplv2",
|
8
|
+
"gplv3",
|
9
|
+
"mit",
|
10
|
+
"reserved"
|
11
|
+
].freeze
|
12
|
+
|
5
13
|
argument :name,
|
6
14
|
type: :string,
|
7
15
|
required: true
|
@@ -79,7 +87,7 @@ module Berkshelf
|
|
79
87
|
when 'mit'; 'MIT'
|
80
88
|
when 'reserved'; 'All rights reserved'
|
81
89
|
else
|
82
|
-
raise Berkshelf::
|
90
|
+
raise Berkshelf::LicenseNotFound.new(options[:license])
|
83
91
|
end
|
84
92
|
end
|
85
93
|
|
@@ -95,7 +103,7 @@ module Berkshelf
|
|
95
103
|
when 'mit'; 'licenses/mit.erb'
|
96
104
|
when 'reserved'; 'licenses/reserved.erb'
|
97
105
|
else
|
98
|
-
raise Berkshelf::
|
106
|
+
raise Berkshelf::LicenseNotFound.new(options[:license])
|
99
107
|
end
|
100
108
|
end
|
101
109
|
|
data/lib/berkshelf/errors.rb
CHANGED
@@ -185,7 +185,6 @@ module Berkshelf
|
|
185
185
|
|
186
186
|
class ConfigExists < BerkshelfError; status_code(116); end
|
187
187
|
class ConfigurationError < BerkshelfError; status_code(117); end
|
188
|
-
class CommandUnsuccessful < BerkshelfError; status_code(118); end
|
189
188
|
class InsufficientPrivledges < BerkshelfError; status_code(119); end
|
190
189
|
class ExplicitCookbookNotFound < BerkshelfError; status_code(120); end
|
191
190
|
class ValidationFailed < BerkshelfError; status_code(121); end
|
@@ -340,10 +339,25 @@ module Berkshelf
|
|
340
339
|
end
|
341
340
|
end
|
342
341
|
|
342
|
+
class LicenseNotFound < BerkshelfError
|
343
|
+
status_code(134)
|
344
|
+
|
345
|
+
attr_reader :license
|
346
|
+
|
347
|
+
def initialize(license)
|
348
|
+
@license = license
|
349
|
+
end
|
350
|
+
|
351
|
+
def to_s
|
352
|
+
"Unknown license: '#{license}'\n" +
|
353
|
+
"Available licenses: #{Berkshelf::CookbookGenerator::LICENSES.join(', ')}"
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
343
357
|
# Raised when a cookbook or its recipes contain a space or invalid
|
344
358
|
# character in the path.
|
345
359
|
class ConfigNotFound < BerkshelfError
|
346
|
-
status_code(
|
360
|
+
status_code(135)
|
347
361
|
|
348
362
|
# @param [String] type
|
349
363
|
# the type of config that was not found (Berkshelf, Chef, etc)
|
data/lib/berkshelf/git.rb
CHANGED
@@ -2,9 +2,6 @@ require 'uri'
|
|
2
2
|
|
3
3
|
module Berkshelf
|
4
4
|
class Git
|
5
|
-
require 'berkshelf/mixin/shellout'
|
6
|
-
extend Berkshelf::Mixin::Shellout
|
7
|
-
|
8
5
|
GIT_REGEXP = URI.regexp(%w(http https ssh git+ssh git rsync))
|
9
6
|
SCP_REGEXP = /^(.+@)?[\w\d\.-]+:.*$/
|
10
7
|
|
@@ -12,6 +9,8 @@ module Berkshelf
|
|
12
9
|
HAS_SPACE_RE = %r{\s}.freeze
|
13
10
|
|
14
11
|
class << self
|
12
|
+
include Ridley::Mixin::ShellOut
|
13
|
+
|
15
14
|
# @overload git(commands)
|
16
15
|
# Shellout to the Git executable on your system with the given commands.
|
17
16
|
#
|
@@ -22,13 +21,13 @@ module Berkshelf
|
|
22
21
|
def git(*command)
|
23
22
|
command.unshift(git_cmd)
|
24
23
|
command_str = command.map { |p| quote_cmd_arg(p) }.join(' ')
|
25
|
-
|
24
|
+
response = shell_out(command_str)
|
26
25
|
|
27
|
-
unless
|
28
|
-
raise GitError.new(
|
26
|
+
unless response.success?
|
27
|
+
raise GitError.new(response.stderr.strip)
|
29
28
|
end
|
30
29
|
|
31
|
-
|
30
|
+
response.stdout.strip
|
32
31
|
end
|
33
32
|
|
34
33
|
# Clone a remote Git repository to disk
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Berkshelf
|
2
|
+
module Mixin
|
3
|
+
module DSLEval
|
4
|
+
class CleanRoom
|
5
|
+
attr_reader :instance
|
6
|
+
|
7
|
+
def initialize(instance)
|
8
|
+
@instance = instance
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def included(base)
|
14
|
+
base.send(:extend, ClassMethods)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
def clean_room
|
20
|
+
@clean_room ||= begin
|
21
|
+
exposed_methods = self.exposed_methods
|
22
|
+
|
23
|
+
Class.new(DSLEval::CleanRoom) do
|
24
|
+
exposed_methods.each do |exposed_method|
|
25
|
+
define_method(exposed_method) do |*args, &block|
|
26
|
+
instance.send(exposed_method, *args, &block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def expose_method(method)
|
34
|
+
exposed_methods << method.to_sym
|
35
|
+
end
|
36
|
+
|
37
|
+
def exposed_methods
|
38
|
+
@exposed_methods ||= Array.new
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [Object]
|
43
|
+
def dsl_eval(&block)
|
44
|
+
self.class.clean_room.new(self).instance_eval(&block)
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
# @param [String] filepath
|
49
|
+
#
|
50
|
+
# @return [Object]
|
51
|
+
def dsl_eval_file(filepath)
|
52
|
+
filepath = filepath.to_s
|
53
|
+
contents = File.read(filepath)
|
54
|
+
dsl_eval { eval(contents, binding, filepath, 1) }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
File without changes
|
File without changes
|
data/lib/berkshelf/version.rb
CHANGED
@@ -2,10 +2,27 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Berkshelf::Berksfile do
|
4
4
|
describe '.from_file' do
|
5
|
-
let(:
|
5
|
+
let(:content) do
|
6
|
+
<<-EOF.strip
|
7
|
+
cookbook 'ntp', '<= 1.0.0'
|
8
|
+
cookbook 'mysql'
|
9
|
+
cookbook 'nginx', '< 0.101.2'
|
10
|
+
cookbook 'ssh_known_hosts2', :git => 'https://github.com/erikh/chef-ssh_known_hosts2.git'
|
11
|
+
EOF
|
12
|
+
end
|
13
|
+
let(:berksfile) { tmp_path.join('Berksfile') }
|
6
14
|
|
7
|
-
|
8
|
-
|
15
|
+
before { File.open(berksfile, 'w+') { |f| f.write(content) } }
|
16
|
+
subject(:from_file) { described_class.from_file(berksfile) }
|
17
|
+
|
18
|
+
it "reads the content of the Berksfile and binds them to a new instance" do
|
19
|
+
%w(ntp mysql nginx ssh_known_hosts2).each do |name|
|
20
|
+
expect(subject).to have_source(name)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it "returns an instance of Berkshelf::Berksfile" do
|
25
|
+
expect(subject).to be_a(described_class)
|
9
26
|
end
|
10
27
|
|
11
28
|
context 'when Berksfile does not exist at given path' do
|
@@ -340,29 +357,6 @@ describe Berkshelf::Berksfile do
|
|
340
357
|
end
|
341
358
|
end
|
342
359
|
|
343
|
-
describe '#load' do
|
344
|
-
let(:content) do
|
345
|
-
<<-EOF.strip
|
346
|
-
cookbook 'ntp', '<= 1.0.0'
|
347
|
-
cookbook 'mysql'
|
348
|
-
cookbook 'nginx', '< 0.101.2'
|
349
|
-
cookbook 'ssh_known_hosts2', :git => 'https://github.com/erikh/chef-ssh_known_hosts2.git'
|
350
|
-
EOF
|
351
|
-
end
|
352
|
-
|
353
|
-
it 'reads the content of a Berksfile and adds the sources to the Shelf' do
|
354
|
-
subject.load(content)
|
355
|
-
|
356
|
-
%w(ntp mysql nginx ssh_known_hosts2).each do |name|
|
357
|
-
expect(subject).to have_source(name)
|
358
|
-
end
|
359
|
-
end
|
360
|
-
|
361
|
-
it 'returns an instance of Berksfile' do
|
362
|
-
expect(subject.load(content)).to be_a(Berkshelf::Berksfile)
|
363
|
-
end
|
364
|
-
end
|
365
|
-
|
366
360
|
describe '#add_source' do
|
367
361
|
let(:name) { 'cookbook_one' }
|
368
362
|
let(:constraint) { '= 1.2.0' }
|
@@ -77,4 +77,14 @@ describe Berkshelf::CookbookGenerator do
|
|
77
77
|
}
|
78
78
|
end
|
79
79
|
end
|
80
|
+
|
81
|
+
context "given an invalid option for :license" do
|
82
|
+
subject(:run) do
|
83
|
+
capture(:stdout) { described_class.new([target, name], license: 'not-there').invoke_all }
|
84
|
+
end
|
85
|
+
|
86
|
+
it "raises a LicenseNotFound error" do
|
87
|
+
expect { run }.to raise_error(Berkshelf::LicenseNotFound)
|
88
|
+
end
|
89
|
+
end
|
80
90
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Berkshelf::Mixin::DSLEval do
|
4
|
+
let(:klass) do
|
5
|
+
klass = Class.new
|
6
|
+
klass.send(:include, described_class)
|
7
|
+
klass
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "ClassMethods" do
|
11
|
+
describe "::clean_room" do
|
12
|
+
subject { klass.clean_room }
|
13
|
+
|
14
|
+
it "returns an anonymous class inheriting from DSLEval::CleanRoom" do
|
15
|
+
expect(subject.superclass).to eql(described_class::CleanRoom)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "::expose_method" do
|
20
|
+
subject { klass }
|
21
|
+
|
22
|
+
it "adds a method to the exposed methods" do
|
23
|
+
klass.expose_method(:something)
|
24
|
+
expect(subject.exposed_methods).to have(1).item
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "::exposed_methods" do
|
29
|
+
it "returns an array" do
|
30
|
+
expect(klass.exposed_methods).to be_a(Array)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#dsl_eval" do
|
36
|
+
subject do
|
37
|
+
klass.new.dsl_eval { }
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns an instance of the including class" do
|
41
|
+
expect(subject).to be_a(klass)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#dsl_eval_file" do
|
46
|
+
let(:filepath) { tmp_path.join('somefile') }
|
47
|
+
before { FileUtils.touch(filepath) }
|
48
|
+
|
49
|
+
subject { klass.new.dsl_eval_file(filepath) }
|
50
|
+
|
51
|
+
it "returns an instance of the including class" do
|
52
|
+
expect(subject).to be_a(klass)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: berkshelf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2013-06-
|
16
|
+
date: 2013-06-11 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: activesupport
|
@@ -150,7 +150,7 @@ dependencies:
|
|
150
150
|
requirements:
|
151
151
|
- - ~>
|
152
152
|
- !ruby/object:Gem::Version
|
153
|
-
version: 1.0.
|
153
|
+
version: 1.0.2
|
154
154
|
type: :runtime
|
155
155
|
prerelease: false
|
156
156
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -158,7 +158,7 @@ dependencies:
|
|
158
158
|
requirements:
|
159
159
|
- - ~>
|
160
160
|
- !ruby/object:Gem::Version
|
161
|
-
version: 1.0.
|
161
|
+
version: 1.0.2
|
162
162
|
- !ruby/object:Gem::Dependency
|
163
163
|
name: solve
|
164
164
|
requirement: !ruby/object:Gem::Requirement
|
@@ -579,7 +579,6 @@ files:
|
|
579
579
|
- lib/berkshelf/chef/cookbook.rb
|
580
580
|
- lib/berkshelf/chef/cookbook/chefignore.rb
|
581
581
|
- lib/berkshelf/cli.rb
|
582
|
-
- lib/berkshelf/command.rb
|
583
582
|
- lib/berkshelf/commands/shelf.rb
|
584
583
|
- lib/berkshelf/commands/test_command.rb
|
585
584
|
- lib/berkshelf/community_rest.rb
|
@@ -608,17 +607,18 @@ files:
|
|
608
607
|
- lib/berkshelf/locations/site_location.rb
|
609
608
|
- lib/berkshelf/lockfile.rb
|
610
609
|
- lib/berkshelf/logger.rb
|
610
|
+
- lib/berkshelf/mixin.rb
|
611
611
|
- lib/berkshelf/mixin/config.rb
|
612
|
+
- lib/berkshelf/mixin/dsl_eval.rb
|
612
613
|
- lib/berkshelf/mixin/logging.rb
|
613
|
-
- lib/berkshelf/mixin/shellout.rb
|
614
614
|
- lib/berkshelf/resolver.rb
|
615
615
|
- lib/berkshelf/test.rb
|
616
616
|
- lib/berkshelf/thor.rb
|
617
|
+
- lib/berkshelf/thor_ext.rb
|
618
|
+
- lib/berkshelf/thor_ext/hash_with_indifferent_access.rb
|
619
|
+
- lib/berkshelf/thor_ext/shell.rb
|
617
620
|
- lib/berkshelf/ui.rb
|
618
621
|
- lib/berkshelf/version.rb
|
619
|
-
- lib/thor/monkies.rb
|
620
|
-
- lib/thor/monkies/hash_with_indifferent_access.rb
|
621
|
-
- lib/thor/monkies/shell.rb
|
622
622
|
- spec/config/berkshelf.pem
|
623
623
|
- spec/config/knife.rb
|
624
624
|
- spec/config/validator.pem
|
@@ -693,6 +693,7 @@ files:
|
|
693
693
|
- spec/unit/berkshelf/locations/site_location_spec.rb
|
694
694
|
- spec/unit/berkshelf/lockfile_spec.rb
|
695
695
|
- spec/unit/berkshelf/logger_spec.rb
|
696
|
+
- spec/unit/berkshelf/mixin/dsl_eval_spec.rb
|
696
697
|
- spec/unit/berkshelf/mixin/logging_spec.rb
|
697
698
|
- spec/unit/berkshelf/resolver_spec.rb
|
698
699
|
- spec/unit/berkshelf/ui_spec.rb
|
@@ -830,6 +831,7 @@ test_files:
|
|
830
831
|
- spec/unit/berkshelf/locations/site_location_spec.rb
|
831
832
|
- spec/unit/berkshelf/lockfile_spec.rb
|
832
833
|
- spec/unit/berkshelf/logger_spec.rb
|
834
|
+
- spec/unit/berkshelf/mixin/dsl_eval_spec.rb
|
833
835
|
- spec/unit/berkshelf/mixin/logging_spec.rb
|
834
836
|
- spec/unit/berkshelf/resolver_spec.rb
|
835
837
|
- spec/unit/berkshelf/ui_spec.rb
|
data/lib/berkshelf/command.rb
DELETED
@@ -1,116 +0,0 @@
|
|
1
|
-
module Berkshelf
|
2
|
-
# This superclass is responsible for handling common command methods and options.
|
3
|
-
module Command
|
4
|
-
# Initialize a new instance of the parent class
|
5
|
-
#
|
6
|
-
# @param [Hash] options
|
7
|
-
# the list of options to pass to the installer
|
8
|
-
def initialize(options = {})
|
9
|
-
@options = options
|
10
|
-
end
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
# Validate the options hash, ensuring there are no conflicting arguments
|
15
|
-
#
|
16
|
-
# @raise [Berkshelf::ArgumentError]
|
17
|
-
# if there are conflicting or invalid options
|
18
|
-
def validate_options!
|
19
|
-
if options[:except] && options[:only]
|
20
|
-
raise Berkshelf::ArgumentError, 'Cannot specify both :except and :only'
|
21
|
-
end
|
22
|
-
|
23
|
-
if options[:cookbooks] && (options[:except] || options[:only])
|
24
|
-
Berkshelf.ui.warn ':cookbooks were supplied to update(), so :except and :only are ignored...'
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
# Ensure the berkshelf directory is created and accessible.
|
29
|
-
def ensure_berkshelf_directory!
|
30
|
-
unless File.exists?(Berkshelf.berkshelf_path)
|
31
|
-
FileUtils.mkdir_p(Berkshelf.berkshelf_path)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
# Check for the presence of a Berksfile. Berkshelf cannot do anything
|
36
|
-
# without the presence of a Berksfile.lock.
|
37
|
-
def ensure_berksfile!
|
38
|
-
unless File.exists?(options[:berksfile])
|
39
|
-
raise Berkshelf::BerksfileNotFound, "No #{options[:berksfile]} was found at ."
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# Check that the Berksfile has content. If the Berksfile is empty, raise
|
44
|
-
# an exception to require at least one definition.
|
45
|
-
def ensure_berksfile_content!
|
46
|
-
begin
|
47
|
-
unless File.read(options[:berksfile]).size > 1
|
48
|
-
raise Berkshelf::BerksfileNotFound, "Your #{options[:berksfile]} is empty! You need at least one cookbook definition."
|
49
|
-
end
|
50
|
-
rescue Errno::ENOENT
|
51
|
-
ensure_berksfile!
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# @return [Hash]
|
56
|
-
# the options for this installer
|
57
|
-
def options
|
58
|
-
@options ||= {}
|
59
|
-
end
|
60
|
-
|
61
|
-
# Attempt to load and parse the lockfile associated with this berksfile.
|
62
|
-
#
|
63
|
-
# @return [Berkshelf::Lockfile, nil]
|
64
|
-
# the lockfile for the current berksfile
|
65
|
-
def lockfile
|
66
|
-
@lockfile ||= berksfile.lockfile
|
67
|
-
end
|
68
|
-
|
69
|
-
# Load the Berksfile for the current project.
|
70
|
-
#
|
71
|
-
# @raise [Berkshelf::BerksfileNotFound]
|
72
|
-
# if the file is not found
|
73
|
-
#
|
74
|
-
# @return [Berkshelf::Berksfile]
|
75
|
-
# the current Berksfile
|
76
|
-
def berksfile
|
77
|
-
@berksfile ||= Berkshelf::Berksfile.from_file(options[:berksfile])
|
78
|
-
end
|
79
|
-
|
80
|
-
# Filter the list of sources from the options passed to the installer.
|
81
|
-
#
|
82
|
-
# @param [Array<Berkshelf::CookbookSource>] sources
|
83
|
-
# the list of sources to resolve
|
84
|
-
#
|
85
|
-
# @raise [Berkshelf::ArgumentError]
|
86
|
-
# if a value for both :except and :only is provided
|
87
|
-
#
|
88
|
-
# @raise [Berkshelf::CookbookNotFound]
|
89
|
-
# if a cookbook name is specified that does not exist
|
90
|
-
#
|
91
|
-
# @return [Array<Berkshelf::CookbookSource>]
|
92
|
-
def filter(sources)
|
93
|
-
cookbooks = Array(options[:cookbooks]).map(&:to_s)
|
94
|
-
except = Array(options[:except]).map(&:to_sym)
|
95
|
-
only = Array(options[:only]).map(&:to_sym)
|
96
|
-
|
97
|
-
case
|
98
|
-
when !cookbooks.empty?
|
99
|
-
missing_cookbooks = (cookbooks - sources.map(&:name))
|
100
|
-
|
101
|
-
unless missing_cookbooks.empty?
|
102
|
-
raise Berkshelf::CookbookNotFound, "Could not find cookbooks #{missing_cookbooks.collect{|cookbook| "'#{cookbook}'"}.join(', ')} in any of the sources. #{missing_cookbooks.size == 1 ? 'Is it' : 'Are they' } in your Berksfile?"
|
103
|
-
end
|
104
|
-
|
105
|
-
sources.select { |source| options[:cookbooks].include?(source.name) }
|
106
|
-
when !except.empty?
|
107
|
-
sources.select { |source| (except & source.groups).empty? }
|
108
|
-
when !only.empty?
|
109
|
-
sources.select { |source| !(only & source.groups).empty? }
|
110
|
-
else
|
111
|
-
sources
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
end
|
116
|
-
end
|
@@ -1,71 +0,0 @@
|
|
1
|
-
require 'hashie'
|
2
|
-
|
3
|
-
module Berkshelf
|
4
|
-
module Mixin
|
5
|
-
module Shellout
|
6
|
-
# Perform a cross-platform shell command, returning the process result.
|
7
|
-
# This uses Process.spawn under the hood for Ruby 1.9, so see
|
8
|
-
# {Process.spawn} for more information.
|
9
|
-
#
|
10
|
-
# On JRuby, a system command is used and $stdout and $stderr are captured.
|
11
|
-
#
|
12
|
-
# @param [String] command
|
13
|
-
# @param [Hash] options
|
14
|
-
# a list of options to send to {Process.spawn}
|
15
|
-
# @return [Hashie::Mash]
|
16
|
-
# information about the command including:
|
17
|
-
# - stderr
|
18
|
-
# - stdout
|
19
|
-
# - exitstatus
|
20
|
-
# - pid
|
21
|
-
# - success?
|
22
|
-
# - failure?
|
23
|
-
def shellout(command)
|
24
|
-
if defined?(RUBY_PLATFORM) && RUBY_PLATFORM == 'java' # jruby
|
25
|
-
out, err, e = capture do
|
26
|
-
system(command)
|
27
|
-
end
|
28
|
-
else
|
29
|
-
begin
|
30
|
-
out_file, err_file = Tempfile.new('berkshelf.stdout'), Tempfile.new('berkshelf.stderr')
|
31
|
-
pid = Process.spawn({}, command, out: out_file.to_i, err: err_file.to_i)
|
32
|
-
Process.waitpid(pid)
|
33
|
-
|
34
|
-
out, err = File.read(out_file), File.read(err_file)
|
35
|
-
e = $?
|
36
|
-
rescue Errno::ENOENT
|
37
|
-
out, err = "", "command not found: #{command}"
|
38
|
-
e = $?
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
Hashie::Mash.new({
|
43
|
-
stdout: out.strip,
|
44
|
-
stderr: err.strip,
|
45
|
-
exitstatus: e.exitstatus,
|
46
|
-
pid: e.pid,
|
47
|
-
success?: e.success?,
|
48
|
-
failure?: !e.success?
|
49
|
-
})
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
# Execute the given block, capturing $stdout, $stderr, and the returned process.
|
54
|
-
#
|
55
|
-
# @return [Array<StringIO, StringIO, Process>]
|
56
|
-
# a tuple of $stdout, $stderr, and the Process
|
57
|
-
def capture(&block)
|
58
|
-
out, err = StringIO.new, StringIO.new
|
59
|
-
$stdout, $stderr = out, err
|
60
|
-
|
61
|
-
yield
|
62
|
-
|
63
|
-
out.rewind
|
64
|
-
err.rewind
|
65
|
-
return out.read, err.read, $?
|
66
|
-
ensure
|
67
|
-
$stdout, $stderr = STDOUT, STDERR
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
data/lib/thor/monkies.rb
DELETED