berkshelf 2.0.0.beta → 2.0.0
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 +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
|