berkshelf 2.0.0.beta → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +19 -1
- data/CONTRIBUTING.md +1 -3
- data/Gemfile +0 -20
- data/Guardfile +3 -3
- data/LICENSE +6 -5
- data/README.md +1 -0
- data/Thorfile +48 -67
- data/berkshelf.gemspec +48 -37
- data/features/apply_command.feature +17 -11
- data/features/config.feature +11 -11
- data/features/configure_command.feature +8 -8
- data/features/contingent_command.feature +37 -8
- data/features/cookbook_command.feature +17 -14
- data/features/groups_install.feature +24 -20
- data/features/install_command.feature +24 -33
- data/features/licenses.feature +112 -0
- data/features/list_command.feature +17 -5
- data/features/lockfile.feature +307 -188
- data/features/outdated_command.feature +1 -4
- data/features/package_command.feature +41 -19
- data/features/shelf/list.feature +39 -0
- data/features/shelf/show.feature +152 -0
- data/features/shelf/uninstall.feature +103 -0
- data/features/show_command.feature +49 -17
- data/features/step_definitions/filesystem_steps.rb +12 -3
- data/features/step_definitions/utility_steps.rb +0 -1
- data/features/support/env.rb +11 -4
- data/features/update_command.feature +22 -10
- data/features/upload_command.feature +174 -127
- data/features/vendor_install.feature +6 -6
- data/generator_files/Berksfile.erb +1 -1
- data/generator_files/metadata.rb.erb +7 -7
- data/lib/berkshelf.rb +39 -27
- data/lib/berkshelf/base_generator.rb +2 -3
- data/lib/berkshelf/berksfile.rb +69 -17
- data/lib/berkshelf/cached_cookbook.rb +17 -1
- data/lib/berkshelf/chef.rb +2 -4
- data/lib/berkshelf/chef/config.rb +51 -75
- data/lib/berkshelf/chef/cookbook.rb +1 -2
- data/lib/berkshelf/chef/cookbook/chefignore.rb +1 -1
- data/lib/berkshelf/cli.rb +144 -194
- data/lib/berkshelf/command.rb +11 -12
- data/lib/berkshelf/commands/shelf.rb +130 -0
- data/lib/berkshelf/commands/test_command.rb +11 -0
- data/lib/berkshelf/community_rest.rb +1 -2
- data/lib/berkshelf/config.rb +14 -10
- data/lib/berkshelf/cookbook_generator.rb +30 -24
- data/lib/berkshelf/cookbook_source.rb +1 -1
- data/lib/berkshelf/cookbook_store.rb +0 -1
- data/lib/berkshelf/core_ext.rb +1 -1
- data/lib/berkshelf/core_ext/file.rb +1 -1
- data/lib/berkshelf/downloader.rb +3 -1
- data/lib/berkshelf/errors.rb +128 -53
- data/lib/berkshelf/formatters.rb +2 -6
- data/lib/berkshelf/formatters/human_readable.rb +8 -2
- data/lib/berkshelf/formatters/json.rb +7 -1
- data/lib/berkshelf/formatters/null.rb +0 -1
- data/lib/berkshelf/git.rb +16 -16
- data/lib/berkshelf/init_generator.rb +28 -26
- data/lib/berkshelf/location.rb +12 -11
- data/lib/berkshelf/locations/chef_api_location.rb +2 -2
- data/lib/berkshelf/locations/git_location.rb +0 -1
- data/lib/berkshelf/locations/github_location.rb +0 -1
- data/lib/berkshelf/locations/path_location.rb +1 -2
- data/lib/berkshelf/locations/site_location.rb +3 -2
- data/lib/berkshelf/lockfile.rb +29 -10
- data/lib/berkshelf/mixin/config.rb +155 -0
- data/lib/berkshelf/mixin/logging.rb +0 -1
- data/lib/berkshelf/mixin/shellout.rb +71 -0
- data/lib/berkshelf/resolver.rb +7 -4
- data/lib/berkshelf/test.rb +1 -3
- data/lib/berkshelf/ui.rb +8 -4
- data/lib/berkshelf/version.rb +1 -1
- data/lib/thor/monkies/shell.rb +0 -1
- data/spec/config/berkshelf.pem +27 -0
- data/spec/config/knife.rb +12 -0
- data/spec/config/validator.pem +27 -0
- data/spec/spec_helper.rb +4 -8
- data/spec/support/chef_api.rb +14 -9
- data/spec/support/chef_server.rb +3 -4
- data/spec/unit/berkshelf/berksfile_spec.rb +1 -1
- data/spec/unit/berkshelf/cookbook_generator_spec.rb +12 -6
- data/spec/unit/berkshelf/cookbook_source_spec.rb +13 -1
- data/spec/unit/berkshelf/init_generator_spec.rb +5 -0
- data/spec/unit/chef/config_spec.rb +9 -10
- metadata +216 -93
- data/features/info_command.feature +0 -39
- data/features/open_command.feature +0 -36
- data/lib/berkshelf/cli_commands/test_command.rb +0 -11
- data/lib/berkshelf/mixin.rb +0 -10
- data/lib/berkshelf/mixin/path_helpers.rb +0 -30
- data/spec/support/knife.rb +0 -18
data/lib/berkshelf/command.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
module Berkshelf
|
2
2
|
# This superclass is responsible for handling common command methods and options.
|
3
|
-
#
|
4
|
-
# @author Seth Vargo <sethvargo@gmail.com>
|
5
3
|
module Command
|
6
4
|
# Initialize a new instance of the parent class
|
5
|
+
#
|
7
6
|
# @param [Hash] options
|
8
7
|
# the list of options to pass to the installer
|
9
8
|
def initialize(options = {})
|
@@ -18,26 +17,26 @@ module Berkshelf
|
|
18
17
|
# if there are conflicting or invalid options
|
19
18
|
def validate_options!
|
20
19
|
if options[:except] && options[:only]
|
21
|
-
raise
|
20
|
+
raise Berkshelf::ArgumentError, 'Cannot specify both :except and :only'
|
22
21
|
end
|
23
22
|
|
24
23
|
if options[:cookbooks] && (options[:except] || options[:only])
|
25
|
-
|
24
|
+
Berkshelf.ui.warn ':cookbooks were supplied to update(), so :except and :only are ignored...'
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
29
28
|
# Ensure the berkshelf directory is created and accessible.
|
30
29
|
def ensure_berkshelf_directory!
|
31
|
-
unless
|
32
|
-
|
30
|
+
unless File.exists?(Berkshelf.berkshelf_path)
|
31
|
+
FileUtils.mkdir_p(Berkshelf.berkshelf_path)
|
33
32
|
end
|
34
33
|
end
|
35
34
|
|
36
35
|
# Check for the presence of a Berksfile. Berkshelf cannot do anything
|
37
36
|
# without the presence of a Berksfile.lock.
|
38
37
|
def ensure_berksfile!
|
39
|
-
unless
|
40
|
-
raise
|
38
|
+
unless File.exists?(options[:berksfile])
|
39
|
+
raise Berkshelf::BerksfileNotFound, "No #{options[:berksfile]} was found at ."
|
41
40
|
end
|
42
41
|
end
|
43
42
|
|
@@ -45,8 +44,8 @@ module Berkshelf
|
|
45
44
|
# an exception to require at least one definition.
|
46
45
|
def ensure_berksfile_content!
|
47
46
|
begin
|
48
|
-
unless
|
49
|
-
raise ::
|
47
|
+
unless File.read(options[:berksfile]).size > 1
|
48
|
+
raise Berkshelf::BerksfileNotFound, "Your #{options[:berksfile]} is empty! You need at least one cookbook definition."
|
50
49
|
end
|
51
50
|
rescue Errno::ENOENT
|
52
51
|
ensure_berksfile!
|
@@ -75,7 +74,7 @@ module Berkshelf
|
|
75
74
|
# @return [Berkshelf::Berksfile]
|
76
75
|
# the current Berksfile
|
77
76
|
def berksfile
|
78
|
-
@berksfile ||=
|
77
|
+
@berksfile ||= Berkshelf::Berksfile.from_file(options[:berksfile])
|
79
78
|
end
|
80
79
|
|
81
80
|
# Filter the list of sources from the options passed to the installer.
|
@@ -100,7 +99,7 @@ module Berkshelf
|
|
100
99
|
missing_cookbooks = (cookbooks - sources.map(&:name))
|
101
100
|
|
102
101
|
unless missing_cookbooks.empty?
|
103
|
-
raise
|
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?"
|
104
103
|
end
|
105
104
|
|
106
105
|
sources.select { |source| options[:cookbooks].include?(source.name) }
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module Berkshelf
|
2
|
+
# All tasks that operate on the Berkshelf shelf.
|
3
|
+
class Shelf < Thor
|
4
|
+
desc 'list', 'List all cookbooks and their versions'
|
5
|
+
def list
|
6
|
+
cookbooks = store.cookbooks.inject({}) do |hash, cookbook|
|
7
|
+
(hash[cookbook.cookbook_name] ||= []).push(cookbook.version)
|
8
|
+
hash
|
9
|
+
end
|
10
|
+
|
11
|
+
if cookbooks.empty?
|
12
|
+
Berkshelf.formatter.msg 'There are no cookbooks in the Berkshelf shelf'
|
13
|
+
else
|
14
|
+
Berkshelf.formatter.msg 'Cookbooks in the Berkshelf shelf:'
|
15
|
+
cookbooks.sort.each do |cookbook, versions|
|
16
|
+
Berkshelf.formatter.msg(" * #{cookbook} (#{versions.sort.join(', ')})")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
method_option :version, aliases: '-v', type: :string, desc: 'Version to show'
|
22
|
+
desc 'show', 'Display information about a cookbook in the Berkshelf shelf'
|
23
|
+
def show(name)
|
24
|
+
cookbooks = find(name, options[:version])
|
25
|
+
|
26
|
+
if options[:version]
|
27
|
+
Berkshelf.formatter.msg "Displaying '#{name}' (#{options[:version]}) in the Berkshelf shelf:"
|
28
|
+
else
|
29
|
+
Berkshelf.formatter.msg "Displaying all versions of '#{name}' in the Berkshelf shelf:"
|
30
|
+
end
|
31
|
+
|
32
|
+
cookbooks.each do |cookbook|
|
33
|
+
Berkshelf.formatter.show(cookbook)
|
34
|
+
Berkshelf.formatter.msg("\n")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
method_option :version, aliases: '-v', type: :string, desc: 'Version to remove'
|
39
|
+
method_option :force, aliases: '-f', type: :boolean, desc: 'Force removal, even if other cookbooks are contingent', default: false
|
40
|
+
desc 'uninstall', 'Remove a cookbook from the Berkshelf shelf'
|
41
|
+
def uninstall(name)
|
42
|
+
cookbooks = find(name, options[:version])
|
43
|
+
cookbooks.each { |c| uninstall_cookbook(c, options[:force]) }
|
44
|
+
end
|
45
|
+
|
46
|
+
no_tasks do
|
47
|
+
# Shortcut helper to the CookbookStore
|
48
|
+
#
|
49
|
+
# @return [Berkshelf::CookbookStore]
|
50
|
+
def store
|
51
|
+
Berkshelf.cookbook_store
|
52
|
+
end
|
53
|
+
|
54
|
+
# Find a cookbook in the store by name and version. If the no version
|
55
|
+
# is given, all cookbooks with the given name are returned. Otherwise,
|
56
|
+
# only the cookbook matching the given version is returned.
|
57
|
+
#
|
58
|
+
# @param [String] name
|
59
|
+
# the name of the cookbook to find
|
60
|
+
# @param [String, nil] version
|
61
|
+
# the version of the cookbook to find
|
62
|
+
#
|
63
|
+
# @raise [Berkshelf::CookbookNotFound]
|
64
|
+
# if the cookbook does not exist
|
65
|
+
#
|
66
|
+
# @return [Array<Berkshelf::CachedCookbook>]
|
67
|
+
# the list of cookbooks that match the parameters - this is always an
|
68
|
+
# array!
|
69
|
+
def find(name, version = nil)
|
70
|
+
cookbooks = if version
|
71
|
+
[store.cookbook(name, version)].compact
|
72
|
+
else
|
73
|
+
store.cookbooks(name).sort
|
74
|
+
end
|
75
|
+
|
76
|
+
if cookbooks.empty?
|
77
|
+
if version
|
78
|
+
raise Berkshelf::CookbookNotFound, "Cookbook '#{name}' (#{version}) is not in the Berkshelf shelf"
|
79
|
+
else
|
80
|
+
raise Berkshelf::CookbookNotFound, "Cookbook '#{name}' is not in the Berkshelf shelf"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
cookbooks
|
85
|
+
end
|
86
|
+
|
87
|
+
# Uninstall a cookbook from the CookbookStore. This method assumes the
|
88
|
+
# cookbook exists, so perform that validation elsewhere.
|
89
|
+
#
|
90
|
+
# By default, this method will request confirmation from the user to
|
91
|
+
# delete a cookbook that is a dependency on another (contingent). This
|
92
|
+
# behavior can be overridden by setting the second parameter `force` to
|
93
|
+
# true.
|
94
|
+
#
|
95
|
+
# @param [Berkshelf::CachedCookbook] cookbook
|
96
|
+
# the cookbook to uninstall
|
97
|
+
# @param [Boolean] force
|
98
|
+
# if false, the user will need to confirm before uninstalling
|
99
|
+
# if contingencies exist
|
100
|
+
def uninstall_cookbook(cookbook, force = false)
|
101
|
+
unless options[:force] || (contingent = contingencies(cookbook)).empty?
|
102
|
+
contingent = contingent.map { |c| "#{c.cookbook_name} (#{c.version})" }.join(', ')
|
103
|
+
confirm = Berkshelf.ui.ask("[#{contingent}] depend on #{cookbook.cookbook_name}.\n\nAre you sure you want to continue? (y/N)")
|
104
|
+
|
105
|
+
exit unless confirm.upcase[0] == 'Y'
|
106
|
+
end
|
107
|
+
|
108
|
+
FileUtils.rm_rf(cookbook.path)
|
109
|
+
Berkshelf.formatter.msg("Successfully uninstalled #{cookbook.cookbook_name} (#{cookbook.version})")
|
110
|
+
end
|
111
|
+
|
112
|
+
# Return a list of all cookbooks which are contingent upon the given
|
113
|
+
# cookbook.
|
114
|
+
#
|
115
|
+
# @param [Berkshelf::CachedCookbook] cookbook
|
116
|
+
# the cached cookbook to search for dependencies against
|
117
|
+
#
|
118
|
+
# @return [Array<Berkshelf::CachedCookbook>]
|
119
|
+
# the list of cookbooks which depend on the parameter
|
120
|
+
def contingencies(cookbook)
|
121
|
+
store.cookbooks.select { |c| c.dependencies.include?(cookbook.cookbook_name) }
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
class Cli < Thor
|
127
|
+
desc 'shelf SUBCOMMAND', 'Interact with the cookbook store'
|
128
|
+
subcommand 'shelf', Berkshelf::Shelf
|
129
|
+
end
|
130
|
+
end
|
@@ -3,7 +3,6 @@ require 'retryable'
|
|
3
3
|
require 'addressable/uri'
|
4
4
|
|
5
5
|
module Berkshelf
|
6
|
-
# @author Jamie Winsor <reset@riotgames.com>
|
7
6
|
class CommunityREST < Faraday::Connection
|
8
7
|
class << self
|
9
8
|
# @param [String] target
|
@@ -74,7 +73,7 @@ module Berkshelf
|
|
74
73
|
@retry_interval = options[:retry_interval]
|
75
74
|
|
76
75
|
builder = Faraday::Builder.new do |b|
|
77
|
-
b.response :
|
76
|
+
b.response :parse_json
|
78
77
|
b.request :retry,
|
79
78
|
max: @retries,
|
80
79
|
interval: @retry_interval,
|
data/lib/berkshelf/config.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
require 'chozo/config'
|
2
2
|
|
3
3
|
module Berkshelf
|
4
|
-
# @author Justin Campbell <justin.campbell@riotgames.com>
|
5
|
-
# @author Jamie Winsor <reset@riotgames.com>
|
6
4
|
class Config < Chozo::Config::JSON
|
7
5
|
LOCATIONS = [
|
8
6
|
File.join('.', '.berkshelf', 'config.json').freeze,
|
@@ -70,28 +68,34 @@ module Berkshelf
|
|
70
68
|
|
71
69
|
attribute 'chef.chef_server_url',
|
72
70
|
type: String,
|
73
|
-
default: Berkshelf
|
71
|
+
default: Berkshelf.chef_config[:chef_server_url]
|
74
72
|
attribute 'chef.validation_client_name',
|
75
73
|
type: String,
|
76
|
-
default: Berkshelf
|
74
|
+
default: Berkshelf.chef_config[:validation_client_name]
|
77
75
|
attribute 'chef.validation_key_path',
|
78
76
|
type: String,
|
79
|
-
default: Berkshelf
|
77
|
+
default: Berkshelf.chef_config[:validation_key]
|
80
78
|
attribute 'chef.client_key',
|
81
79
|
type: String,
|
82
|
-
default: Berkshelf
|
80
|
+
default: Berkshelf.chef_config[:client_key]
|
83
81
|
attribute 'chef.node_name',
|
84
82
|
type: String,
|
85
|
-
default: Berkshelf
|
83
|
+
default: Berkshelf.chef_config[:node_name]
|
86
84
|
attribute 'cookbook.copyright',
|
87
85
|
type: String,
|
88
|
-
default: Berkshelf
|
86
|
+
default: Berkshelf.chef_config[:cookbook_copyright]
|
89
87
|
attribute 'cookbook.email',
|
90
88
|
type: String,
|
91
|
-
default: Berkshelf
|
89
|
+
default: Berkshelf.chef_config[:cookbook_email]
|
92
90
|
attribute 'cookbook.license',
|
93
91
|
type: String,
|
94
|
-
default: Berkshelf
|
92
|
+
default: Berkshelf.chef_config[:cookbook_license]
|
93
|
+
attribute 'allowed_licenses',
|
94
|
+
type: Array,
|
95
|
+
default: Array.new
|
96
|
+
attribute 'raise_license_exception',
|
97
|
+
type: Boolean,
|
98
|
+
default: false
|
95
99
|
attribute 'vagrant.vm.box',
|
96
100
|
type: String,
|
97
101
|
default: 'Berkshelf-CentOS-6.3-x86_64-minimal',
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Berkshelf
|
2
|
-
# @author Jamie Winsor <reset@riotgames.com>
|
3
2
|
class CookbookGenerator < BaseGenerator
|
3
|
+
require_relative 'config'
|
4
|
+
|
4
5
|
argument :name,
|
5
6
|
type: :string,
|
6
7
|
required: true
|
@@ -13,6 +14,11 @@ module Berkshelf
|
|
13
14
|
type: :boolean,
|
14
15
|
default: false
|
15
16
|
|
17
|
+
class_option :skip_test_kitchen,
|
18
|
+
type: :boolean,
|
19
|
+
default: false,
|
20
|
+
desc: 'Skip adding a testing environment to your cookbook'
|
21
|
+
|
16
22
|
class_option :foodcritic,
|
17
23
|
type: :boolean,
|
18
24
|
default: false
|
@@ -42,19 +48,19 @@ module Berkshelf
|
|
42
48
|
default: Berkshelf::Config.instance.cookbook.email
|
43
49
|
|
44
50
|
def generate
|
45
|
-
empty_directory target.join(
|
46
|
-
empty_directory target.join(
|
47
|
-
empty_directory target.join(
|
48
|
-
empty_directory target.join(
|
49
|
-
empty_directory target.join(
|
50
|
-
empty_directory target.join(
|
51
|
-
empty_directory target.join(
|
52
|
-
empty_directory target.join(
|
53
|
-
|
54
|
-
template
|
55
|
-
template
|
56
|
-
template license_file, target.join(
|
57
|
-
template
|
51
|
+
empty_directory target.join('files/default')
|
52
|
+
empty_directory target.join('templates/default')
|
53
|
+
empty_directory target.join('attributes')
|
54
|
+
empty_directory target.join('definitions')
|
55
|
+
empty_directory target.join('libraries')
|
56
|
+
empty_directory target.join('providers')
|
57
|
+
empty_directory target.join('recipes')
|
58
|
+
empty_directory target.join('resources')
|
59
|
+
|
60
|
+
template 'default_recipe.erb', target.join('recipes/default.rb')
|
61
|
+
template 'metadata.rb.erb', target.join('metadata.rb')
|
62
|
+
template license_file, target.join('LICENSE')
|
63
|
+
template 'README.md.erb', target.join('README.md')
|
58
64
|
|
59
65
|
Berkshelf::InitGenerator.new([target], options.merge(default_options)).invoke_all
|
60
66
|
end
|
@@ -67,11 +73,11 @@ module Berkshelf
|
|
67
73
|
|
68
74
|
def license_name
|
69
75
|
case options[:license]
|
70
|
-
when
|
71
|
-
when
|
72
|
-
when
|
73
|
-
when
|
74
|
-
when
|
76
|
+
when 'apachev2'; 'Apache 2.0'
|
77
|
+
when 'gplv2'; 'GNU Public License 2.0'
|
78
|
+
when 'gplv3'; 'GNU Public License 3.0'
|
79
|
+
when 'mit'; 'MIT'
|
80
|
+
when 'reserved'; 'All rights reserved'
|
75
81
|
else
|
76
82
|
raise Berkshelf::InternalError, "Unknown license: '#{options[:license]}'"
|
77
83
|
end
|
@@ -83,11 +89,11 @@ module Berkshelf
|
|
83
89
|
|
84
90
|
def license_file
|
85
91
|
case options[:license]
|
86
|
-
when
|
87
|
-
when
|
88
|
-
when
|
89
|
-
when
|
90
|
-
when
|
92
|
+
when 'apachev2'; 'licenses/apachev2.erb'
|
93
|
+
when 'gplv2'; 'licenses/gplv2.erb'
|
94
|
+
when 'gplv3'; 'licenses/gplv3.erb'
|
95
|
+
when 'mit'; 'licenses/mit.erb'
|
96
|
+
when 'reserved'; 'licenses/reserved.erb'
|
91
97
|
else
|
92
98
|
raise Berkshelf::InternalError, "Unknown license: '#{options[:license]}'"
|
93
99
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module Berkshelf
|
2
|
-
# @author Jamie Winsor <reset@riotgames.com>
|
3
2
|
class CookbookSource
|
4
3
|
class << self
|
5
4
|
@@valid_options = [:constraint, :locations, :group, :locked_version]
|
@@ -206,6 +205,7 @@ module Berkshelf
|
|
206
205
|
if location.kind_of?(GitLocation)
|
207
206
|
h[:git] = location.uri
|
208
207
|
h[:ref] = location.ref
|
208
|
+
h[:rel] = location.rel if location.rel
|
209
209
|
end
|
210
210
|
|
211
211
|
# Path is intentionally left relative here for cross-team compatibility
|
data/lib/berkshelf/core_ext.rb
CHANGED
data/lib/berkshelf/downloader.rb
CHANGED
data/lib/berkshelf/errors.rb
CHANGED
@@ -15,7 +15,7 @@ module Berkshelf
|
|
15
15
|
class ArgumentError < InternalError; end
|
16
16
|
class AbstractFunction < InternalError
|
17
17
|
def to_s
|
18
|
-
|
18
|
+
'Function must be implemented on includer'
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -25,51 +25,67 @@ module Berkshelf
|
|
25
25
|
class CookbookNotFound < BerkshelfError; status_code(103); end
|
26
26
|
class GitError < BerkshelfError
|
27
27
|
status_code(104)
|
28
|
-
attr_reader :stderr
|
29
28
|
|
29
|
+
# @param [#to_s] stderr
|
30
|
+
# the error that came from stderr
|
30
31
|
def initialize(stderr)
|
31
|
-
@stderr = stderr
|
32
|
+
@stderr = stderr.to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
# A common header for all git errors. The #to_s method should
|
36
|
+
# use this before outputting any specific errors.
|
37
|
+
#
|
38
|
+
# @return [String]
|
39
|
+
def header
|
40
|
+
'An error occurred during Git execution:'
|
32
41
|
end
|
33
42
|
|
34
43
|
def to_s
|
35
|
-
|
36
|
-
|
44
|
+
[
|
45
|
+
header,
|
46
|
+
"",
|
47
|
+
" " + @stderr.to_s.split("\n").map(&:strip).join("\n "),
|
48
|
+
""
|
49
|
+
].join("\n")
|
37
50
|
end
|
38
51
|
end
|
39
|
-
class PrivateGitRepo < GitError; end
|
40
|
-
class AmbiguousGitRef < GitError
|
41
|
-
attr_reader :ref
|
42
52
|
|
53
|
+
class AmbiguousGitRef < GitError
|
43
54
|
def initialize(ref)
|
44
55
|
@ref = ref
|
45
56
|
end
|
46
57
|
|
47
58
|
def to_s
|
48
|
-
|
49
|
-
|
59
|
+
[
|
60
|
+
header,
|
61
|
+
"",
|
62
|
+
" Ambiguous Git ref: '#{@ref}'",
|
63
|
+
"",
|
64
|
+
].join("\n")
|
50
65
|
end
|
51
66
|
end
|
52
|
-
class InvalidGitRef < GitError
|
53
|
-
attr_reader :ref
|
54
67
|
|
68
|
+
class InvalidGitRef < GitError
|
55
69
|
def initialize(ref)
|
56
70
|
@ref = ref
|
57
71
|
end
|
58
72
|
|
59
73
|
def to_s
|
60
|
-
|
61
|
-
|
74
|
+
[
|
75
|
+
header,
|
76
|
+
"",
|
77
|
+
" Invalid Git ref: '#{@ref}'",
|
78
|
+
"",
|
79
|
+
].join("\n")
|
62
80
|
end
|
63
81
|
end
|
64
82
|
|
65
83
|
class DuplicateSourceDefined < BerkshelfError; status_code(105); end
|
66
84
|
class NoSolution < BerkshelfError; status_code(106); end
|
67
85
|
class CookbookSyntaxError < BerkshelfError; status_code(107); end
|
68
|
-
class BerksConfigNotFound < BerkshelfError; status_code(109); end
|
69
86
|
|
70
87
|
class InvalidGitURI < BerkshelfError
|
71
88
|
status_code(110)
|
72
|
-
attr_reader :uri
|
73
89
|
|
74
90
|
# @param [String] uri
|
75
91
|
def initialize(uri)
|
@@ -77,13 +93,12 @@ module Berkshelf
|
|
77
93
|
end
|
78
94
|
|
79
95
|
def to_s
|
80
|
-
"'#{uri}' is not a valid Git URI
|
96
|
+
"'#{@uri}' is not a valid Git URI"
|
81
97
|
end
|
82
98
|
end
|
83
99
|
|
84
100
|
class UnknownGitHubProtocol < BerkshelfError
|
85
101
|
status_code(110)
|
86
|
-
attr_reader :protocol
|
87
102
|
|
88
103
|
# @param [String] protocol
|
89
104
|
def initialize(protocol)
|
@@ -91,7 +106,7 @@ module Berkshelf
|
|
91
106
|
end
|
92
107
|
|
93
108
|
def to_s
|
94
|
-
"'#{
|
109
|
+
"'#{@protocol}' is not supported for the 'github' location key - please use 'git' instead"
|
95
110
|
end
|
96
111
|
end
|
97
112
|
|
@@ -99,13 +114,14 @@ module Berkshelf
|
|
99
114
|
status_code(110)
|
100
115
|
|
101
116
|
def to_s
|
102
|
-
|
117
|
+
'Could not find a Git executable in your path - please add it and try again'
|
103
118
|
end
|
104
119
|
end
|
105
120
|
|
106
121
|
class ConstraintNotSatisfied < BerkshelfError; status_code(111); end
|
107
122
|
class InvalidChefAPILocation < BerkshelfError; status_code(112); end
|
108
123
|
class BerksfileReadError < BerkshelfError
|
124
|
+
# @param [#status_code] original_error
|
109
125
|
def initialize(original_error)
|
110
126
|
@original_error = original_error
|
111
127
|
end
|
@@ -115,18 +131,19 @@ module Berkshelf
|
|
115
131
|
def status_code
|
116
132
|
@original_error.respond_to?(:status_code) ? @original_error.status_code : 113
|
117
133
|
end
|
134
|
+
|
135
|
+
def to_s
|
136
|
+
[
|
137
|
+
"An error occurred while reading the Berksfile:",
|
138
|
+
"",
|
139
|
+
" " + @original_error.to_s.split("\n").map(&:strip).join("\n "),
|
140
|
+
].join("\n")
|
141
|
+
end
|
118
142
|
end
|
119
143
|
|
120
|
-
# @author Seth Vargo <sethvargo@gmail.com>
|
121
144
|
class MismatchedCookbookName < BerkshelfError
|
122
145
|
status_code(114)
|
123
146
|
|
124
|
-
# @return [Berkshelf::Location]
|
125
|
-
attr_reader :location
|
126
|
-
|
127
|
-
# @return [Berkshelf::CachedCookbook]
|
128
|
-
attr_reader :cached_cookbook
|
129
|
-
|
130
147
|
# @param [Berkshelf::Location] location
|
131
148
|
# the location that is mismatched
|
132
149
|
# @param [Berkshelf::CachedCookbook] cached_cookbook
|
@@ -140,13 +157,13 @@ module Berkshelf
|
|
140
157
|
[
|
141
158
|
"In your Berksfile, you have:",
|
142
159
|
"",
|
143
|
-
" cookbook '#{location.name}'",
|
160
|
+
" cookbook '#{@location.name}'",
|
144
161
|
"",
|
145
|
-
"But that cookbook is actually named '#{cached_cookbook.cookbook_name}'
|
162
|
+
"But that cookbook is actually named '#{@cached_cookbook.cookbook_name}'",
|
146
163
|
"",
|
147
|
-
"This can cause potentially unwanted side-effects in the future
|
164
|
+
"This can cause potentially unwanted side-effects in the future",
|
148
165
|
"",
|
149
|
-
"NOTE: If you don't explicitly set the `name` attribute in the metadata, the name of the directory will be used!"
|
166
|
+
"NOTE: If you don't explicitly set the `name` attribute in the metadata, the name of the directory will be used!",
|
150
167
|
].join("\n")
|
151
168
|
end
|
152
169
|
end
|
@@ -159,15 +176,10 @@ module Berkshelf
|
|
159
176
|
end
|
160
177
|
|
161
178
|
def to_s
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
strings << " #{key} #{error}"
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
strings.join "\n"
|
179
|
+
[
|
180
|
+
'Invalid configuration:',
|
181
|
+
@errors.map { |key, errors| errors.map { |error| " #{key} #{error}" } },
|
182
|
+
].join("\n")
|
171
183
|
end
|
172
184
|
end
|
173
185
|
|
@@ -200,7 +212,7 @@ module Berkshelf
|
|
200
212
|
"does not satisfy the version constraint:",
|
201
213
|
" #{@cached_cookbook.cookbook_name} (#{@location.version_constraint})",
|
202
214
|
"",
|
203
|
-
"This occurs when the Chef Server has a cookbook with a missing/mis-matched version number in its `metadata.rb
|
215
|
+
"This occurs when the Chef Server has a cookbook with a missing/mis-matched version number in its `metadata.rb`",
|
204
216
|
].join("\n")
|
205
217
|
end
|
206
218
|
end
|
@@ -219,16 +231,17 @@ module Berkshelf
|
|
219
231
|
end
|
220
232
|
|
221
233
|
def to_s
|
222
|
-
|
234
|
+
[
|
235
|
+
"Unknown site shortname '#{@shortname}' - supported shortnames are:",
|
236
|
+
"",
|
237
|
+
" * " + SiteLocation::SHORTNAMES.keys.join("\n * "),
|
238
|
+
].join("\n")
|
223
239
|
end
|
224
240
|
end
|
225
241
|
|
226
242
|
class OutdatedCookbookSource < BerkshelfError
|
227
243
|
status_code(128)
|
228
244
|
|
229
|
-
# @return [Berkshelf::CookbookSource]
|
230
|
-
attr_reader :locked_source, :source
|
231
|
-
|
232
245
|
# @param [Berkshelf::CookbookSource] source
|
233
246
|
# the cookbook source that is outdated
|
234
247
|
def initialize(locked_source, source)
|
@@ -238,14 +251,14 @@ module Berkshelf
|
|
238
251
|
|
239
252
|
def to_s
|
240
253
|
[
|
241
|
-
"Berkshelf could not find compatible versions for cookbook '#{source.name}':",
|
254
|
+
"Berkshelf could not find compatible versions for cookbook '#{@source.name}':",
|
242
255
|
" In Berksfile:",
|
243
|
-
" #{locked_source.name} (#{locked_source.locked_version})",
|
256
|
+
" #{@locked_source.name} (#{@locked_source.locked_version})",
|
244
257
|
"",
|
245
258
|
" In Berksfile.lock:",
|
246
|
-
" #{source.name} (#{source.version_constraint})",
|
259
|
+
" #{@source.name} (#{@source.version_constraint})",
|
247
260
|
"",
|
248
|
-
"Try running `berks update #{source.name}, which will try to find '#{source.name}' matching '#{source.version_constraint}'."
|
261
|
+
"Try running `berks update #{@source.name}, which will try to find '#{@source.name}' matching '#{@source.version_constraint}'.",
|
249
262
|
].join("\n")
|
250
263
|
end
|
251
264
|
end
|
@@ -258,7 +271,7 @@ module Berkshelf
|
|
258
271
|
end
|
259
272
|
|
260
273
|
def to_s
|
261
|
-
|
274
|
+
"The environment '#{@environment_name}' does not exist"
|
262
275
|
end
|
263
276
|
end
|
264
277
|
|
@@ -266,11 +279,10 @@ module Berkshelf
|
|
266
279
|
status_code(130)
|
267
280
|
|
268
281
|
def to_s
|
269
|
-
|
282
|
+
'There was an error connecting to the Chef Server'
|
270
283
|
end
|
271
284
|
end
|
272
285
|
|
273
|
-
# @author Seth Vargo <sethvargo@gmail.com>
|
274
286
|
class UnknownCompressionType < BerkshelfError
|
275
287
|
status_code(131)
|
276
288
|
|
@@ -279,8 +291,71 @@ module Berkshelf
|
|
279
291
|
end
|
280
292
|
|
281
293
|
def to_s
|
282
|
-
"The file at '#{@destination}' is not a known compression type
|
294
|
+
"The file at '#{@destination}' is not a known compression type"
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
# Raised when a cookbook or its recipes contain a space or invalid
|
299
|
+
# character in the path.
|
300
|
+
#
|
301
|
+
# @param [Berkshelf::CachedCookbook] cookbook
|
302
|
+
# the cookbook that failed validation
|
303
|
+
# @param [Array<#to_s>] files
|
304
|
+
# the list of files that were not valid
|
305
|
+
class InvalidCookbookFiles < BerkshelfError
|
306
|
+
status_code(132)
|
307
|
+
|
308
|
+
def initialize(cookbook, files)
|
309
|
+
@cookbook = cookbook
|
310
|
+
@files = files
|
311
|
+
end
|
312
|
+
|
313
|
+
def to_s
|
314
|
+
[
|
315
|
+
"The cookbook '#{@cookbook.cookbook_name}' has invalid filenames:",
|
316
|
+
"",
|
317
|
+
" " + @files.map(&:to_s).join("\n "),
|
318
|
+
"",
|
319
|
+
"Please note, spaces are not a valid character in filenames",
|
320
|
+
].join("\n")
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
# Raised when a CachedCookbook has a license file that isn't allowed
|
325
|
+
# by the Berksfile.
|
326
|
+
#
|
327
|
+
# @param [Berkshelf::CachedCookbook] cookbook
|
328
|
+
# the cookbook that failed license validation
|
329
|
+
class LicenseNotAllowed < BerkshelfError
|
330
|
+
status_code(133)
|
331
|
+
|
332
|
+
def initialize(cookbook)
|
333
|
+
@cookbook = cookbook
|
334
|
+
end
|
335
|
+
|
336
|
+
def to_s
|
337
|
+
msg = "'#{@cookbook.cookbook_name}' has a license of '#{@cookbook.metadata.license}', but"
|
338
|
+
msg << " '#{@cookbook.metadata.license}' is not in your list of allowed licenses"
|
339
|
+
msg
|
283
340
|
end
|
341
|
+
end
|
284
342
|
|
343
|
+
# Raised when a cookbook or its recipes contain a space or invalid
|
344
|
+
# character in the path.
|
345
|
+
class ConfigNotFound < BerkshelfError
|
346
|
+
status_code(133)
|
347
|
+
|
348
|
+
# @param [String] type
|
349
|
+
# the type of config that was not found (Berkshelf, Chef, etc)
|
350
|
+
# @param [#to_s] path
|
351
|
+
# the path to the specified Chef config that did not exist
|
352
|
+
def initialize(type, path)
|
353
|
+
@type = type.to_s
|
354
|
+
@path = path
|
355
|
+
end
|
356
|
+
|
357
|
+
def to_s
|
358
|
+
"No #{@type.capitalize} config file found at: '#{@path}'!"
|
359
|
+
end
|
285
360
|
end
|
286
361
|
end
|