berkshelf 5.5.0 → 5.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -3
- data/Gemfile +31 -31
- data/Gemfile.lock +3 -3
- data/Guardfile +13 -13
- data/Rakefile +1 -0
- data/Thorfile +16 -16
- data/berkshelf.gemspec +35 -35
- data/features/step_definitions/chef/config_steps.rb +4 -4
- data/features/step_definitions/chef_server_steps.rb +6 -6
- data/features/step_definitions/cli_steps.rb +3 -3
- data/features/step_definitions/config_steps.rb +5 -5
- data/features/step_definitions/filesystem_steps.rb +12 -11
- data/features/support/env.rb +21 -21
- data/lib/berkshelf.rb +66 -66
- data/lib/berkshelf/base_generator.rb +10 -11
- data/lib/berkshelf/berksfile.rb +38 -38
- data/lib/berkshelf/cached_cookbook.rb +7 -7
- data/lib/berkshelf/cli.rb +126 -126
- data/lib/berkshelf/commands/shelf.rb +19 -18
- data/lib/berkshelf/commands/test_command.rb +2 -2
- data/lib/berkshelf/community_rest.rb +38 -38
- data/lib/berkshelf/config.rb +42 -41
- data/lib/berkshelf/cookbook_generator.rb +38 -38
- data/lib/berkshelf/cookbook_store.rb +4 -4
- data/lib/berkshelf/core_ext/file_utils.rb +1 -1
- data/lib/berkshelf/dependency.rb +23 -21
- data/lib/berkshelf/downloader.rb +24 -25
- data/lib/berkshelf/errors.rb +17 -17
- data/lib/berkshelf/file_syncer.rb +9 -8
- data/lib/berkshelf/formatters/human.rb +3 -3
- data/lib/berkshelf/formatters/json.rb +2 -2
- data/lib/berkshelf/init_generator.rb +64 -64
- data/lib/berkshelf/installer.rb +103 -102
- data/lib/berkshelf/location.rb +9 -9
- data/lib/berkshelf/locations/git.rb +16 -16
- data/lib/berkshelf/locations/github.rb +1 -1
- data/lib/berkshelf/locations/path.rb +2 -2
- data/lib/berkshelf/lockfile.rb +309 -315
- data/lib/berkshelf/mixin/git.rb +3 -3
- data/lib/berkshelf/packager.rb +4 -4
- data/lib/berkshelf/resolver.rb +2 -2
- data/lib/berkshelf/resolver/graph.rb +1 -1
- data/lib/berkshelf/shell.rb +1 -1
- data/lib/berkshelf/source.rb +6 -6
- data/lib/berkshelf/source_uri.rb +2 -2
- data/lib/berkshelf/ssl_policies.rb +3 -3
- data/lib/berkshelf/thor.rb +1 -1
- data/lib/berkshelf/uploader.rb +48 -48
- data/lib/berkshelf/validator.rb +2 -2
- data/lib/berkshelf/version.rb +1 -1
- data/lib/berkshelf/visualizer.rb +11 -11
- data/spec/config/knife.rb +2 -2
- data/spec/fixtures/Berksfile +3 -3
- data/spec/fixtures/cookbook-path/jenkins-config/metadata.rb +3 -3
- data/spec/fixtures/cookbook-store/jenkins-2.0.3/metadata.rb +5 -5
- data/spec/fixtures/cookbook-store/jenkins-2.0.4/metadata.rb +4 -4
- data/spec/fixtures/cookbooks/example_cookbook-0.5.0/metadata.rb +3 -3
- data/spec/fixtures/cookbooks/example_cookbook/metadata.rb +3 -3
- data/spec/spec_helper.rb +9 -9
- data/spec/support/chef_api.rb +11 -12
- data/spec/support/chef_server.rb +10 -10
- data/spec/support/git.rb +23 -23
- data/spec/support/kitchen.rb +2 -2
- data/spec/support/matchers/filepath_matchers.rb +2 -2
- data/spec/support/path_helpers.rb +12 -12
- data/spec/support/shared_examples/formatter.rb +1 -1
- data/spec/unit/berkshelf/berksfile_spec.rb +78 -78
- data/spec/unit/berkshelf/cached_cookbook_spec.rb +42 -42
- data/spec/unit/berkshelf/cli_spec.rb +6 -6
- data/spec/unit/berkshelf/community_rest_spec.rb +83 -83
- data/spec/unit/berkshelf/config_spec.rb +13 -13
- data/spec/unit/berkshelf/cookbook_generator_spec.rb +39 -39
- data/spec/unit/berkshelf/cookbook_store_spec.rb +41 -41
- data/spec/unit/berkshelf/core_ext/file_utils_spec.rb +5 -6
- data/spec/unit/berkshelf/core_ext/pathname_spec.rb +1 -1
- data/spec/unit/berkshelf/dependency_spec.rb +43 -43
- data/spec/unit/berkshelf/downloader_spec.rb +20 -20
- data/spec/unit/berkshelf/errors_spec.rb +3 -3
- data/spec/unit/berkshelf/file_syncer_spec.rb +86 -86
- data/spec/unit/berkshelf/formatters/base_spec.rb +23 -23
- data/spec/unit/berkshelf/formatters/human_spec.rb +2 -2
- data/spec/unit/berkshelf/formatters/json_spec.rb +2 -2
- data/spec/unit/berkshelf/formatters/null_spec.rb +3 -3
- data/spec/unit/berkshelf/init_generator_spec.rb +92 -92
- data/spec/unit/berkshelf/installer_spec.rb +8 -8
- data/spec/unit/berkshelf/location_spec.rb +11 -11
- data/spec/unit/berkshelf/locations/base_spec.rb +35 -35
- data/spec/unit/berkshelf/locations/git_spec.rb +87 -87
- data/spec/unit/berkshelf/locations/path_spec.rb +40 -40
- data/spec/unit/berkshelf/lockfile_parser_spec.rb +71 -71
- data/spec/unit/berkshelf/lockfile_spec.rb +197 -197
- data/spec/unit/berkshelf/logger_spec.rb +3 -3
- data/spec/unit/berkshelf/mixin/logging_spec.rb +5 -5
- data/spec/unit/berkshelf/packager_spec.rb +2 -2
- data/spec/unit/berkshelf/resolver/graph_spec.rb +1 -1
- data/spec/unit/berkshelf/resolver_spec.rb +17 -17
- data/spec/unit/berkshelf/shell_spec.rb +34 -34
- data/spec/unit/berkshelf/source_spec.rb +12 -11
- data/spec/unit/berkshelf/source_uri_spec.rb +1 -1
- data/spec/unit/berkshelf/ssl_policies_spec.rb +25 -25
- data/spec/unit/berkshelf/uploader_spec.rb +54 -54
- data/spec/unit/berkshelf/validator_spec.rb +16 -16
- data/spec/unit/berkshelf/visualizer_spec.rb +17 -17
- data/spec/unit/berkshelf_spec.rb +18 -18
- metadata +5 -5
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "fileutils"
|
2
2
|
|
3
3
|
module Berkshelf
|
4
4
|
class CookbookStore
|
@@ -7,7 +7,7 @@ module Berkshelf
|
|
7
7
|
#
|
8
8
|
# @return [String]
|
9
9
|
def default_path
|
10
|
-
File.join(Berkshelf.berkshelf_path,
|
10
|
+
File.join(Berkshelf.berkshelf_path, "cookbooks")
|
11
11
|
end
|
12
12
|
|
13
13
|
# @return [Berkshelf::CookbookStore]
|
@@ -48,7 +48,7 @@ module Berkshelf
|
|
48
48
|
|
49
49
|
# Destroy the contents of the initialized storage path.
|
50
50
|
def clean!
|
51
|
-
FileUtils.rm_rf(Dir.glob(File.join(storage_path,
|
51
|
+
FileUtils.rm_rf(Dir.glob(File.join(storage_path, "*")))
|
52
52
|
end
|
53
53
|
|
54
54
|
# Import a cookbook found on the local filesystem into this instance of the cookbook store.
|
@@ -162,7 +162,7 @@ module Berkshelf
|
|
162
162
|
graph = Solve::Graph.new
|
163
163
|
cookbooks(name).each { |cookbook| graph.artifact(name, cookbook.version) }
|
164
164
|
|
165
|
-
name, version = Solve.it!(graph, [[name, constraint]], ENV[
|
165
|
+
name, version = Solve.it!(graph, [[name, constraint]], ENV["DEBUG_RESOLVER"] ? { ui: Berkshelf.ui } : {}).first
|
166
166
|
|
167
167
|
cookbook(name, version)
|
168
168
|
rescue Solve::Errors::NoSolutionError
|
data/lib/berkshelf/dependency.rb
CHANGED
@@ -122,23 +122,24 @@ module Berkshelf
|
|
122
122
|
def cached_cookbook
|
123
123
|
return @cached_cookbook if @cached_cookbook
|
124
124
|
|
125
|
-
@cached_cookbook =
|
126
|
-
|
125
|
+
@cached_cookbook =
|
126
|
+
if location
|
127
|
+
cookbook = location.cached_cookbook
|
127
128
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
129
|
+
# If we have a cached cookbook, tighten our constraints
|
130
|
+
if cookbook
|
131
|
+
self.locked_version = cookbook.version
|
132
|
+
self.version_constraint = cookbook.version
|
133
|
+
end
|
133
134
|
|
134
|
-
|
135
|
-
else
|
136
|
-
if locked_version
|
137
|
-
CookbookStore.instance.cookbook(name, locked_version)
|
135
|
+
cookbook
|
138
136
|
else
|
139
|
-
|
137
|
+
if locked_version
|
138
|
+
CookbookStore.instance.cookbook(name, locked_version)
|
139
|
+
else
|
140
|
+
CookbookStore.instance.satisfy(name, version_constraint)
|
141
|
+
end
|
140
142
|
end
|
141
|
-
end
|
142
143
|
|
143
144
|
@cached_cookbook
|
144
145
|
end
|
@@ -175,20 +176,21 @@ module Berkshelf
|
|
175
176
|
end
|
176
177
|
|
177
178
|
def inspect
|
178
|
-
|
179
|
+
"#<Berkshelf::Dependency: " << [
|
179
180
|
"#{name} (#{version_constraint})",
|
180
181
|
"locked_version: #{locked_version.inspect}",
|
181
182
|
"groups: #{groups}",
|
182
|
-
"location: #{location || 'default'}>"
|
183
|
-
].join(
|
183
|
+
"location: #{location || 'default'}>",
|
184
|
+
].join(", ")
|
184
185
|
end
|
185
186
|
|
186
187
|
def to_lock
|
187
|
-
out =
|
188
|
-
"
|
189
|
-
|
190
|
-
|
191
|
-
|
188
|
+
out =
|
189
|
+
if location || version_constraint.to_s == ">= 0.0.0"
|
190
|
+
" #{name}\n"
|
191
|
+
else
|
192
|
+
" #{name} (#{version_constraint})\n"
|
193
|
+
end
|
192
194
|
|
193
195
|
out << location.to_lock if location
|
194
196
|
out
|
data/lib/berkshelf/downloader.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "net/http"
|
2
|
+
require "mixlib/archive"
|
3
|
+
require "berkshelf/ssl_policies"
|
4
4
|
|
5
5
|
module Berkshelf
|
6
6
|
class Downloader
|
@@ -48,7 +48,7 @@ module Berkshelf
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
raise CookbookNotFound.new(dependency, version,
|
51
|
+
raise CookbookNotFound.new(dependency, version, "in any of the sources")
|
52
52
|
end
|
53
53
|
|
54
54
|
# @param [Berkshelf::Source] source
|
@@ -66,21 +66,21 @@ module Berkshelf
|
|
66
66
|
CommunityREST.new(remote_cookbook.location_path).download(name, version)
|
67
67
|
when :chef_server
|
68
68
|
# @todo Dynamically get credentials for remote_cookbook.location_path
|
69
|
-
ssl_options = {verify: Berkshelf::Config.instance.ssl.verify}
|
69
|
+
ssl_options = { verify: Berkshelf::Config.instance.ssl.verify }
|
70
70
|
ssl_options[:cert_store] = ssl_policy.store if ssl_policy.store
|
71
71
|
|
72
72
|
credentials = {
|
73
73
|
server_url: remote_cookbook.location_path,
|
74
74
|
client_name: Berkshelf::Config.instance.chef.node_name,
|
75
75
|
client_key: Berkshelf::Config.instance.chef.client_key,
|
76
|
-
ssl: ssl_options
|
76
|
+
ssl: ssl_options,
|
77
77
|
}
|
78
78
|
# @todo Something scary going on here - getting an instance of Kitchen::Logger from test-kitchen
|
79
79
|
# https://github.com/opscode/test-kitchen/blob/master/lib/kitchen.rb#L99
|
80
80
|
Celluloid.logger = nil unless ENV["DEBUG_CELLULOID"]
|
81
81
|
Ridley.open(credentials) { |r| r.cookbook.download(name, version) }
|
82
82
|
when :github
|
83
|
-
require
|
83
|
+
require "octokit"
|
84
84
|
|
85
85
|
tmp_dir = Dir.mktmpdir
|
86
86
|
archive_path = File.join(tmp_dir, "#{name}-#{version}.tar.gz")
|
@@ -89,16 +89,16 @@ module Berkshelf
|
|
89
89
|
# Find the correct github connection options for this specific cookbook.
|
90
90
|
cookbook_uri = URI.parse(remote_cookbook.location_path)
|
91
91
|
if cookbook_uri.host == "github.com"
|
92
|
-
options = Berkshelf::Config.instance.github.detect { |opts| opts["web_endpoint"]
|
93
|
-
options = {} if options
|
92
|
+
options = Berkshelf::Config.instance.github.detect { |opts| opts["web_endpoint"].nil? }
|
93
|
+
options = {} if options.nil?
|
94
94
|
else
|
95
95
|
options = Berkshelf::Config.instance.github.detect { |opts| opts["web_endpoint"] == "#{cookbook_uri.scheme}://#{cookbook_uri.host}" }
|
96
|
-
raise ConfigurationError.new "Missing github endpoint configuration for #{cookbook_uri.scheme}://#{cookbook_uri.host}" if options
|
96
|
+
raise ConfigurationError.new "Missing github endpoint configuration for #{cookbook_uri.scheme}://#{cookbook_uri.host}" if options.nil?
|
97
97
|
end
|
98
98
|
|
99
99
|
github_client = Octokit::Client.new(access_token: options[:access_token],
|
100
|
-
|
101
|
-
|
100
|
+
api_endpoint: options[:api_endpoint], web_endpoint: options[:web_endpoint],
|
101
|
+
connection_options: { ssl: { verify: options[:ssl_verify].nil? ? true : options[:ssl_verify] } })
|
102
102
|
|
103
103
|
begin
|
104
104
|
url = URI(github_client.archive_link(cookbook_uri.path.gsub(/^\//, ""), ref: "v#{version}"))
|
@@ -119,20 +119,20 @@ module Berkshelf
|
|
119
119
|
# we need to figure out where the cookbook is located in the archive. This is because the directory name
|
120
120
|
# pattern is not cosistant between private and public github repositories
|
121
121
|
cookbook_directory = Dir.entries(unpack_dir).select do |f|
|
122
|
-
(! f.start_with?(
|
122
|
+
(! f.start_with?(".")) && (Pathname.new(File.join(unpack_dir, f)).cookbook?)
|
123
123
|
end[0]
|
124
124
|
|
125
125
|
File.join(unpack_dir, cookbook_directory)
|
126
126
|
when :uri
|
127
|
-
require
|
127
|
+
require "open-uri"
|
128
128
|
|
129
129
|
tmp_dir = Dir.mktmpdir
|
130
130
|
archive_path = Pathname.new(tmp_dir) + "#{name}-#{version}.tar.gz"
|
131
131
|
unpack_dir = Pathname.new(tmp_dir) + "#{name}-#{version}"
|
132
132
|
|
133
133
|
url = remote_cookbook.location_path
|
134
|
-
open(url,
|
135
|
-
archive_path.open(
|
134
|
+
open(url, "rb") do |remote_file|
|
135
|
+
archive_path.open("wb") { |local_file| local_file.write remote_file.read }
|
136
136
|
end
|
137
137
|
|
138
138
|
Mixlib::Archive.new(archive_path).extract(unpack_dir)
|
@@ -140,7 +140,7 @@ module Berkshelf
|
|
140
140
|
# The top level directory is inconsistant. So we unpack it and
|
141
141
|
# use the only directory created in the unpack_dir.
|
142
142
|
cookbook_directory = unpack_dir.entries.select do |filename|
|
143
|
-
(! filename.to_s.start_with?(
|
143
|
+
(! filename.to_s.start_with?(".")) && (unpack_dir + filename).cookbook?
|
144
144
|
end.first
|
145
145
|
|
146
146
|
(unpack_dir + cookbook_directory).to_s
|
@@ -153,26 +153,25 @@ module Berkshelf
|
|
153
153
|
cookbook_uri = URI.parse(remote_cookbook.location_path)
|
154
154
|
if cookbook_uri.host
|
155
155
|
options = Berkshelf::Config.instance.gitlab.detect { |opts| opts["web_endpoint"] == "#{cookbook_uri.scheme}://#{cookbook_uri.host}" }
|
156
|
-
raise ConfigurationError.new "Missing github endpoint configuration for #{cookbook_uri.scheme}://#{cookbook_uri.host}" if options
|
156
|
+
raise ConfigurationError.new "Missing github endpoint configuration for #{cookbook_uri.scheme}://#{cookbook_uri.host}" if options.nil?
|
157
157
|
end
|
158
158
|
|
159
159
|
connection ||= Faraday.new(url: options[:web_endpoint]) do |faraday|
|
160
|
-
faraday.headers[:accept] =
|
160
|
+
faraday.headers[:accept] = "application/x-tar"
|
161
161
|
faraday.response :logger, @logger unless @logger.nil?
|
162
|
-
faraday.adapter Faraday.default_adapter
|
162
|
+
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
|
163
163
|
end
|
164
164
|
|
165
|
-
resp = connection.get(cookbook_uri.request_uri +
|
165
|
+
resp = connection.get(cookbook_uri.request_uri + "&private_token=" + options[:private_token])
|
166
166
|
return nil unless resp.status == 200
|
167
167
|
open(archive_path, "wb") { |file| file.write(resp.body) }
|
168
168
|
|
169
|
-
|
170
|
-
Archive::Tar::Minitar.unpack(tgz, unpack_dir)
|
169
|
+
Mixlib::Archive.new(archive_path).extract(unpack_dir)
|
171
170
|
|
172
171
|
# The top level directory is inconsistant. So we unpack it and
|
173
172
|
# use the only directory created in the unpack_dir.
|
174
173
|
cookbook_directory = unpack_dir.entries.select do |filename|
|
175
|
-
(! filename.to_s.start_with?(
|
174
|
+
(! filename.to_s.start_with?(".")) && (unpack_dir + filename).cookbook?
|
176
175
|
end.first
|
177
176
|
|
178
177
|
(unpack_dir + cookbook_directory).to_s
|
@@ -181,7 +180,7 @@ module Berkshelf
|
|
181
180
|
FileUtils.cp_r(remote_cookbook.location_path, tmp_dir)
|
182
181
|
File.join(tmp_dir, name)
|
183
182
|
else
|
184
|
-
raise
|
183
|
+
raise "unknown location type #{remote_cookbook.location_type}"
|
185
184
|
end
|
186
185
|
rescue CookbookNotFound
|
187
186
|
nil
|
data/lib/berkshelf/errors.rb
CHANGED
@@ -61,7 +61,7 @@ module Berkshelf
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def to_s
|
64
|
-
out
|
64
|
+
out = "Your Berksfile contains multiple entries named "
|
65
65
|
out << "'#{@name}'. Please remove duplicate dependencies, or put them in "
|
66
66
|
out << "different groups."
|
67
67
|
out
|
@@ -83,7 +83,7 @@ module Berkshelf
|
|
83
83
|
|
84
84
|
def to_s
|
85
85
|
@original_exception.to_s +
|
86
|
-
|
86
|
+
"Unable to find a solution for demands: #{demands.join(', ')}"
|
87
87
|
end
|
88
88
|
|
89
89
|
alias_method :message, :to_s
|
@@ -285,11 +285,11 @@ module Berkshelf
|
|
285
285
|
|
286
286
|
def to_s
|
287
287
|
"Berkshelf could not find compatible versions for cookbook '#{@dependency.name}':\n" +
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
288
|
+
" In Berksfile:\n" +
|
289
|
+
" #{@dependency.name} (#{@dependency.version_constraint})\n\n" +
|
290
|
+
" In Berksfile.lock:\n" +
|
291
|
+
" #{@locked.name} (#{@locked.version})\n\n" +
|
292
|
+
"Try running `berks update #{@dependency.name}`, which will try to find '#{@dependency.name}' matching " +
|
293
293
|
"'#{@dependency.version_constraint}'."
|
294
294
|
end
|
295
295
|
|
@@ -314,7 +314,7 @@ module Berkshelf
|
|
314
314
|
set_status_code(130)
|
315
315
|
|
316
316
|
def to_s
|
317
|
-
|
317
|
+
"There was an error connecting to the Chef Server"
|
318
318
|
end
|
319
319
|
end
|
320
320
|
|
@@ -372,7 +372,7 @@ module Berkshelf
|
|
372
372
|
|
373
373
|
def to_s
|
374
374
|
"Unknown license: '#{license}'\n" +
|
375
|
-
|
375
|
+
"Available licenses: #{CookbookGenerator::LICENSES.join(', ')}"
|
376
376
|
end
|
377
377
|
|
378
378
|
alias_method :message, :to_s
|
@@ -440,7 +440,7 @@ module Berkshelf
|
|
440
440
|
set_status_code(140)
|
441
441
|
|
442
442
|
def to_s
|
443
|
-
|
443
|
+
"Lockfile not found! Run `berks install` to create the lockfile."
|
444
444
|
end
|
445
445
|
end
|
446
446
|
|
@@ -467,7 +467,7 @@ module Berkshelf
|
|
467
467
|
set_status_code(144)
|
468
468
|
|
469
469
|
def to_s
|
470
|
-
|
470
|
+
"The lockfile is out of sync! Run `berks install` to sync the lockfile."
|
471
471
|
end
|
472
472
|
end
|
473
473
|
|
@@ -544,7 +544,7 @@ module Berkshelf
|
|
544
544
|
def intialize(environment_file)
|
545
545
|
@environment_file = environment_file
|
546
546
|
end
|
547
|
-
|
547
|
+
|
548
548
|
def to_s
|
549
549
|
"Could not find environment file #{@environment_file}"
|
550
550
|
end
|
@@ -556,11 +556,11 @@ module Berkshelf
|
|
556
556
|
|
557
557
|
class GitNotInstalled < GitError
|
558
558
|
def initialize
|
559
|
-
super
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
559
|
+
super "You need to install Git before you can download " \
|
560
|
+
"cookbooks from git repositories. For more information, please " \
|
561
|
+
"see the Git docs: http://git-scm.org. If you have git installed, " \
|
562
|
+
"please make sure it is in your $PATH and accessible by the user " \
|
563
|
+
"running this command."
|
564
564
|
end
|
565
565
|
end
|
566
566
|
|
@@ -1,11 +1,11 @@
|
|
1
|
-
require
|
1
|
+
require "fileutils"
|
2
2
|
|
3
3
|
module Berkshelf
|
4
4
|
module FileSyncer
|
5
5
|
extend self
|
6
6
|
|
7
7
|
# Files to be ignored during a directory globbing
|
8
|
-
IGNORED_FILES = %w
|
8
|
+
IGNORED_FILES = %w{. ..}.freeze
|
9
9
|
|
10
10
|
#
|
11
11
|
# Glob across the given pattern, accounting for dotfiles, removing Ruby's
|
@@ -62,8 +62,8 @@ module Berkshelf
|
|
62
62
|
# user directory: C:/Users/MATTWR~1/AppData/Local/Temp
|
63
63
|
# so that it matches the parent of source_files
|
64
64
|
source = glob(source).first
|
65
|
-
|
66
|
-
source_files = glob(File.join(source,
|
65
|
+
|
66
|
+
source_files = glob(File.join(source, "**/*"))
|
67
67
|
source_files = source_files.reject do |source_file|
|
68
68
|
basename = relative_path_for(source_file, source)
|
69
69
|
excludes.any? { |exclude| File.fnmatch?(exclude, basename, File::FNM_DOTMATCH) }
|
@@ -94,7 +94,7 @@ module Berkshelf
|
|
94
94
|
FileUtils.cp(source_file, "#{destination}/#{relative_path}")
|
95
95
|
else
|
96
96
|
type = File.ftype(source_file)
|
97
|
-
raise
|
97
|
+
raise "Unknown file type: `#{type}' at " \
|
98
98
|
"`#{source_file}'. Failed to sync `#{source_file}' to " \
|
99
99
|
"`#{destination}/#{relative_path}'!"
|
100
100
|
end
|
@@ -125,6 +125,7 @@ module Berkshelf
|
|
125
125
|
end
|
126
126
|
|
127
127
|
private
|
128
|
+
|
128
129
|
#
|
129
130
|
# The relative path of the given +path+ to the +parent+.
|
130
131
|
#
|
@@ -135,8 +136,8 @@ module Berkshelf
|
|
135
136
|
#
|
136
137
|
# @return [String]
|
137
138
|
#
|
138
|
-
|
139
|
-
|
140
|
-
|
139
|
+
def relative_path_for(path, parent)
|
140
|
+
Pathname.new(path).relative_path_from(Pathname.new(parent)).to_s
|
141
|
+
end
|
141
142
|
end
|
142
143
|
end
|
@@ -60,12 +60,12 @@ module Berkshelf
|
|
60
60
|
# { 'cookbook' => { 'supermarket.chef.io' => #<Cookbook> } }
|
61
61
|
def outdated(hash)
|
62
62
|
if hash.empty?
|
63
|
-
Berkshelf.ui.info(
|
63
|
+
Berkshelf.ui.info("All cookbooks up to date!")
|
64
64
|
else
|
65
|
-
Berkshelf.ui.info(
|
65
|
+
Berkshelf.ui.info("The following cookbooks have newer versions:")
|
66
66
|
|
67
67
|
hash.each do |name, info|
|
68
|
-
info[
|
68
|
+
info["remote"].each do |remote_source, remote_version|
|
69
69
|
out = " * #{name} (#{info['local']} => #{remote_version})"
|
70
70
|
|
71
71
|
unless remote_source.default?
|
@@ -92,11 +92,11 @@ module Berkshelf
|
|
92
92
|
# { 'cookbook' => { 'supermarket.chef.io' => #<Cookbook> } }
|
93
93
|
def outdated(hash)
|
94
94
|
hash.each do |name, info|
|
95
|
-
info[
|
95
|
+
info["remote"].each do |remote_source, remote_version|
|
96
96
|
source = remote_source.uri.to_s
|
97
97
|
|
98
98
|
cookbooks[name] ||= {}
|
99
|
-
cookbooks[name][:local] = info[
|
99
|
+
cookbooks[name][:local] = info["local"].to_s
|
100
100
|
cookbooks[name][:remote] ||= {}
|
101
101
|
cookbooks[name][:remote][source] = remote_version.to_s
|
102
102
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
begin
|
2
|
-
require
|
2
|
+
require "kitchen/generator/init"
|
3
3
|
rescue LoadError; end
|
4
4
|
|
5
5
|
module Berkshelf
|
@@ -24,17 +24,17 @@ module Berkshelf
|
|
24
24
|
class_option :skip_vagrant,
|
25
25
|
type: :boolean,
|
26
26
|
default: false,
|
27
|
-
desc:
|
27
|
+
desc: "Skips adding a Vagrantfile and adding supporting gems to the Gemfile"
|
28
28
|
|
29
29
|
class_option :skip_git,
|
30
30
|
type: :boolean,
|
31
31
|
default: false,
|
32
|
-
desc:
|
32
|
+
desc: "Skips adding a .gitignore and running git init in the cookbook directory"
|
33
33
|
|
34
34
|
class_option :foodcritic,
|
35
35
|
type: :boolean,
|
36
36
|
default: false,
|
37
|
-
desc:
|
37
|
+
desc: "Creates a Thorfile with Foodcritic support to lint test your cookbook"
|
38
38
|
|
39
39
|
class_option :chef_minitest,
|
40
40
|
type: :boolean,
|
@@ -43,12 +43,12 @@ module Berkshelf
|
|
43
43
|
class_option :scmversion,
|
44
44
|
type: :boolean,
|
45
45
|
default: false,
|
46
|
-
desc:
|
46
|
+
desc: "Creates a Thorfile with SCMVersion support to manage versions for continuous integration"
|
47
47
|
|
48
48
|
class_option :no_bundler,
|
49
49
|
type: :boolean,
|
50
50
|
default: false,
|
51
|
-
desc:
|
51
|
+
desc: "Skips generation of a Gemfile and other Bundler specific support"
|
52
52
|
|
53
53
|
class_option :cookbook_name,
|
54
54
|
type: :string
|
@@ -57,7 +57,7 @@ module Berkshelf
|
|
57
57
|
class_option :skip_test_kitchen,
|
58
58
|
type: :boolean,
|
59
59
|
default: false,
|
60
|
-
desc:
|
60
|
+
desc: "Skip adding a testing environment to your cookbook"
|
61
61
|
end
|
62
62
|
|
63
63
|
def generate
|
@@ -65,35 +65,35 @@ module Berkshelf
|
|
65
65
|
validate_configuration
|
66
66
|
check_option_support
|
67
67
|
|
68
|
-
template
|
69
|
-
template
|
68
|
+
template "Berksfile.erb", target.join("Berksfile")
|
69
|
+
template "Thorfile.erb", target.join("Thorfile")
|
70
70
|
|
71
71
|
if options[:chefignore]
|
72
|
-
copy_file
|
72
|
+
copy_file "chefignore", target.join(Ridley::Chef::Chefignore::FILENAME)
|
73
73
|
end
|
74
74
|
|
75
75
|
unless options[:skip_git]
|
76
|
-
template
|
76
|
+
template "gitignore.erb", target.join(".gitignore")
|
77
77
|
|
78
|
-
unless File.exists?(target.join(
|
78
|
+
unless File.exists?(target.join(".git"))
|
79
79
|
inside target do
|
80
|
-
git
|
80
|
+
git "init"
|
81
81
|
end
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
85
|
if options[:chef_minitest]
|
86
|
-
empty_directory target.join(
|
87
|
-
template
|
88
|
-
template
|
86
|
+
empty_directory target.join("files/default/tests/minitest/support")
|
87
|
+
template "default_test.rb.erb", target.join("files/default/tests/minitest/default_test.rb")
|
88
|
+
template "helpers.rb.erb", target.join("files/default/tests/minitest/support/helpers.rb")
|
89
89
|
end
|
90
90
|
|
91
91
|
if options[:scmversion]
|
92
|
-
create_file target.join(
|
92
|
+
create_file target.join("VERSION"), "0.1.0"
|
93
93
|
end
|
94
94
|
|
95
95
|
unless options[:no_bundler]
|
96
|
-
template
|
96
|
+
template "Gemfile.erb", target.join("Gemfile")
|
97
97
|
end
|
98
98
|
|
99
99
|
if defined?(Kitchen::Generator::Init)
|
@@ -103,28 +103,28 @@ module Berkshelf
|
|
103
103
|
end
|
104
104
|
|
105
105
|
unless options[:skip_vagrant]
|
106
|
-
template
|
106
|
+
template "Vagrantfile.erb", target.join("Vagrantfile")
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
110
110
|
private
|
111
111
|
|
112
|
-
|
113
|
-
|
114
|
-
|
112
|
+
def berkshelf_config
|
113
|
+
Berkshelf.config
|
114
|
+
end
|
115
115
|
|
116
116
|
# Read the cookbook name from the metadata.rb
|
117
117
|
#
|
118
118
|
# @return [String]
|
119
119
|
# name of the cookbook
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
end
|
120
|
+
def cookbook_name
|
121
|
+
@cookbook_name ||= begin
|
122
|
+
metadata = Ridley::Chef::Cookbook::Metadata.from_file(target.join("metadata.rb").to_s)
|
123
|
+
metadata.name.empty? ? File.basename(target) : metadata.name
|
124
|
+
rescue CookbookNotFound, IOError
|
125
|
+
File.basename(target)
|
127
126
|
end
|
127
|
+
end
|
128
128
|
|
129
129
|
# Assert the current working directory is a cookbook
|
130
130
|
#
|
@@ -132,64 +132,64 @@ module Berkshelf
|
|
132
132
|
# not a cookbook
|
133
133
|
#
|
134
134
|
# @return [nil]
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
end
|
135
|
+
def validate_cookbook
|
136
|
+
path = File.expand_path(File.join(target, "metadata.rb"))
|
137
|
+
unless File.exists?(path)
|
138
|
+
raise Berkshelf::NotACookbook.new(path)
|
140
139
|
end
|
140
|
+
end
|
141
141
|
|
142
142
|
# Assert valid configuration
|
143
143
|
#
|
144
144
|
# @raise [InvalidConfiguration] if the configuration is invalid
|
145
145
|
#
|
146
146
|
# @return [nil]
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
end
|
147
|
+
def validate_configuration
|
148
|
+
unless Berkshelf.config.valid?
|
149
|
+
raise InvalidConfiguration.new(Berkshelf.config.errors)
|
151
150
|
end
|
151
|
+
end
|
152
152
|
|
153
153
|
# Check for supporting gems for provided options
|
154
154
|
#
|
155
155
|
# @return [Boolean]
|
156
|
-
|
157
|
-
|
158
|
-
assert_option_supported(:scmversion,
|
159
|
-
assert_default_supported(:no_bundler,
|
160
|
-
|
156
|
+
def check_option_support
|
157
|
+
assert_option_supported(:foodcritic) &&
|
158
|
+
assert_option_supported(:scmversion, "thor-scmversion") &&
|
159
|
+
assert_default_supported(:no_bundler, "bundler")
|
160
|
+
end
|
161
161
|
|
162
162
|
# Warn if the supporting gem for an option is not installed
|
163
163
|
#
|
164
164
|
# @return [Boolean]
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
end
|
165
|
+
def assert_option_supported(option, gem_name = option.to_s)
|
166
|
+
if options[option]
|
167
|
+
begin
|
168
|
+
Gem::Specification.find_by_name(gem_name)
|
169
|
+
rescue Gem::LoadError
|
170
|
+
Berkshelf.ui.warn "This cookbook was generated with --#{option}, however, #{gem_name} is not installed."
|
171
|
+
Berkshelf.ui.warn "To make use of --#{option}: gem install #{gem_name}"
|
172
|
+
return false
|
174
173
|
end
|
175
|
-
true
|
176
174
|
end
|
175
|
+
true
|
176
|
+
end
|
177
177
|
|
178
178
|
# Warn if the supporting gem for a default is not installed
|
179
179
|
#
|
180
180
|
# @return [Boolean]
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
end
|
181
|
+
def assert_default_supported(option, gem_name = option.to_s)
|
182
|
+
unless options[option]
|
183
|
+
begin
|
184
|
+
Gem::Specification.find_by_name(gem_name)
|
185
|
+
rescue Gem::LoadError
|
186
|
+
Berkshelf.ui.warn "By default, this cookbook was generated to support #{gem_name}, however, #{gem_name} is not installed."
|
187
|
+
Berkshelf.ui.warn "To skip support for #{gem_name}, use --#{option.to_s.tr('_', '-')}"
|
188
|
+
Berkshelf.ui.warn "To install #{gem_name}: gem install #{gem_name}"
|
189
|
+
return false
|
191
190
|
end
|
192
|
-
true
|
193
191
|
end
|
192
|
+
true
|
193
|
+
end
|
194
194
|
end
|
195
195
|
end
|