halite 1.0.0.rc.1
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.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.travis.yml +10 -0
- data/Gemfile +15 -0
- data/LICENSE +202 -0
- data/README.md +75 -0
- data/Rakefile +22 -0
- data/halite.gemspec +33 -0
- data/lib/berkshelf/halite.rb +2 -0
- data/lib/halite.rb +12 -0
- data/lib/halite/berkshelf/helper.rb +69 -0
- data/lib/halite/berkshelf/source.rb +56 -0
- data/lib/halite/converter.rb +17 -0
- data/lib/halite/converter/libraries.rb +40 -0
- data/lib/halite/converter/metadata.rb +21 -0
- data/lib/halite/converter/other.rb +19 -0
- data/lib/halite/converter/readme.rb +20 -0
- data/lib/halite/dependencies.rb +72 -0
- data/lib/halite/error.rb +4 -0
- data/lib/halite/gem.rb +82 -0
- data/lib/halite/rake_helper.rb +151 -0
- data/lib/halite/rake_tasks.rb +2 -0
- data/lib/halite/spec_helper.rb +134 -0
- data/lib/halite/spec_helper/empty/README.md +1 -0
- data/lib/halite/spec_helper/runner.rb +43 -0
- data/lib/halite/version.rb +3 -0
- data/spec/converter/libraries_spec.rb +152 -0
- data/spec/converter/metadata_spec.rb +60 -0
- data/spec/converter/other_spec.rb +56 -0
- data/spec/converter/readme_spec.rb +55 -0
- data/spec/converter_spec.rb +14 -0
- data/spec/data/gems/test1/Rakefile +1 -0
- data/spec/data/gems/test1/lib/test1.rb +2 -0
- data/spec/data/gems/test1/lib/test1/version.rb +3 -0
- data/spec/data/gems/test1/test1.gemspec +25 -0
- data/spec/data/gems/test2/Rakefile +1 -0
- data/spec/data/gems/test2/chef/attributes.rb +0 -0
- data/spec/data/gems/test2/chef/recipes/default.rb +0 -0
- data/spec/data/gems/test2/chef/templates/default/conf.erb +0 -0
- data/spec/data/gems/test2/lib/test2.rb +4 -0
- data/spec/data/gems/test2/lib/test2/resource.rb +6 -0
- data/spec/data/gems/test2/lib/test2/version.rb +3 -0
- data/spec/data/gems/test2/test2.gemspec +24 -0
- data/spec/data/gems/test3/Rakefile +1 -0
- data/spec/data/gems/test3/chef/recipes/default.rb +1 -0
- data/spec/data/gems/test3/lib/test3.rb +4 -0
- data/spec/data/gems/test3/lib/test3/dsl.rb +15 -0
- data/spec/data/gems/test3/lib/test3/version.rb +3 -0
- data/spec/data/gems/test3/test3.gemspec +24 -0
- data/spec/data/integration_cookbooks/test1/libraries/test1.rb +3 -0
- data/spec/data/integration_cookbooks/test1/libraries/test1__version.rb +4 -0
- data/spec/data/integration_cookbooks/test1/metadata.rb +4 -0
- data/spec/data/integration_cookbooks/test2/attributes.rb +0 -0
- data/spec/data/integration_cookbooks/test2/libraries/test2.rb +5 -0
- data/spec/data/integration_cookbooks/test2/libraries/test2__resource.rb +7 -0
- data/spec/data/integration_cookbooks/test2/libraries/test2__version.rb +4 -0
- data/spec/data/integration_cookbooks/test2/metadata.rb +4 -0
- data/spec/data/integration_cookbooks/test2/recipes/default.rb +0 -0
- data/spec/data/integration_cookbooks/test2/templates/default/conf.erb +0 -0
- data/spec/data/integration_cookbooks/test3/libraries/test3.rb +5 -0
- data/spec/data/integration_cookbooks/test3/libraries/test3__dsl.rb +16 -0
- data/spec/data/integration_cookbooks/test3/libraries/test3__version.rb +4 -0
- data/spec/data/integration_cookbooks/test3/metadata.rb +4 -0
- data/spec/data/integration_cookbooks/test3/recipes/default.rb +1 -0
- data/spec/dependencies_spec.rb +167 -0
- data/spec/gem_spec.rb +164 -0
- data/spec/integration_spec.rb +104 -0
- data/spec/spec_helper.rb +28 -0
- metadata +307 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'halite/gem'
|
18
|
+
require 'berkshelf/source'
|
19
|
+
require 'berkshelf/api_client/remote_cookbook'
|
20
|
+
|
21
|
+
module Halite
|
22
|
+
module Berkshelf
|
23
|
+
|
24
|
+
class Source < ::Berkshelf::Source
|
25
|
+
def initialize
|
26
|
+
super 'https://supermarket.chef.io'
|
27
|
+
end
|
28
|
+
|
29
|
+
def build_universe
|
30
|
+
# Scan all gems
|
31
|
+
::Gem::Specification.stubs.map do |spec|
|
32
|
+
Gem.new(spec)
|
33
|
+
end.select do |cook|
|
34
|
+
cook.is_halite_cookbook?
|
35
|
+
end.map do |cook|
|
36
|
+
# Build a fake "remote" cookbook
|
37
|
+
::Berkshelf::APIClient::RemoteCookbook.new(
|
38
|
+
cook.cookbook_name,
|
39
|
+
cook.version,
|
40
|
+
{
|
41
|
+
location_type: 'halite',
|
42
|
+
location_path: cook.name,
|
43
|
+
dependencies: cook.cookbook_dependencies.inject({}) {|memo, dep| memo[dep.name] = dep.requirement; memo },
|
44
|
+
},
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_s
|
50
|
+
"Halite gems"
|
51
|
+
end
|
52
|
+
alias :uri :to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'halite/converter/libraries'
|
2
|
+
require 'halite/converter/metadata'
|
3
|
+
require 'halite/converter/other'
|
4
|
+
require 'halite/converter/readme'
|
5
|
+
|
6
|
+
module Halite
|
7
|
+
module Converter
|
8
|
+
|
9
|
+
def self.write(spec, base_path)
|
10
|
+
Metadata.write(spec, base_path)
|
11
|
+
Libraries.write(spec, base_path)
|
12
|
+
Other.write(spec, base_path)
|
13
|
+
Readme.write(spec, base_path)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Halite
|
2
|
+
module Converter
|
3
|
+
module Libraries
|
4
|
+
|
5
|
+
# Chef doesn't allow subfolders under libraries/ currently
|
6
|
+
def self.flatten_filename(path)
|
7
|
+
path.gsub(/\//, '__')
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.generate(spec, data, entry_point=false)
|
11
|
+
# No newline on the header so that line numbers in the files aren't changed.
|
12
|
+
buf = (entry_point ? "ENV['HALITE_LOAD'] = '1'; begin; " : "if ENV['HALITE_LOAD']; ")
|
13
|
+
# Rewrite requires to require_relative as needed.
|
14
|
+
data = data.gsub(/require ['"](#{spec.name}[^'"]*)['"]/) { "require_relative '#{flatten_filename($1)}'" }
|
15
|
+
spec.cookbook_dependencies.each do |dep|
|
16
|
+
next unless dep.type == :dependencies
|
17
|
+
# This is kind of gross, but not sure what else to do
|
18
|
+
data = data.gsub(/require ['"](#{dep.name}[^'"]*)['"]/) { "require_relative '../../#{dep.name}/libraries/#{flatten_filename($1)}'" }
|
19
|
+
end
|
20
|
+
buf << data.rstrip
|
21
|
+
# Match up with the header. All files get one line longer. ¯\_(ツ)_/¯
|
22
|
+
buf << (entry_point ? "\nensure; ENV.delete('HALITE_LOAD'); end\n" : "\nend\n")
|
23
|
+
buf
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.write(spec, base_path, entry_point_name=nil)
|
27
|
+
entry_point_name ||= spec.name
|
28
|
+
# Handle both cases, with .rb and without
|
29
|
+
entry_point_name += '.rb' unless entry_point_name.end_with?('.rb')
|
30
|
+
lib_path = File.join(base_path, 'libraries')
|
31
|
+
# Create cookbook's libraries folder
|
32
|
+
Dir.mkdir(lib_path) unless File.directory?(lib_path)
|
33
|
+
spec.each_library_file do |path, rel_path|
|
34
|
+
IO.write(File.join(lib_path, flatten_filename(rel_path)), generate(spec, IO.read(path), entry_point_name == rel_path))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Halite
|
2
|
+
module Converter
|
3
|
+
module Metadata
|
4
|
+
|
5
|
+
def self.generate(spec)
|
6
|
+
buf = spec.license_header
|
7
|
+
buf << "name #{spec.cookbook_name.inspect}\n"
|
8
|
+
buf << "version #{spec.version.inspect}\n"
|
9
|
+
spec.cookbook_dependencies.each do |dep|
|
10
|
+
buf << "depends #{dep.name.inspect}, #{dep.requirement.inspect}\n"
|
11
|
+
end
|
12
|
+
buf
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.write(spec, base_path)
|
16
|
+
IO.write(File.join(base_path, 'metadata.rb'), generate(spec))
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Halite
|
2
|
+
module Converter
|
3
|
+
module Other
|
4
|
+
|
5
|
+
def self.write(spec, base_path)
|
6
|
+
spec.each_file('chef') do |path, rel_path|
|
7
|
+
dir_path = File.dirname(rel_path)
|
8
|
+
FileUtils.mkdir_p(File.join(base_path, dir_path)) unless dir_path == '.'
|
9
|
+
File.open(path, 'rb') do |in_f|
|
10
|
+
File.open(File.join(base_path, rel_path), 'wb') do |out_f|
|
11
|
+
IO.copy_stream(in_f, out_f)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Halite
|
2
|
+
module Converter
|
3
|
+
module Readme
|
4
|
+
|
5
|
+
def self.write(spec, base_path)
|
6
|
+
readme_path = %w{README.md README README.txt readme.md readme readme.txt}.map do |name|
|
7
|
+
File.join(spec.full_gem_path, name)
|
8
|
+
end.find {|path| File.exists?(path) }
|
9
|
+
if readme_path
|
10
|
+
File.open(readme_path, 'rb') do |in_f|
|
11
|
+
File.open(File.join(base_path, File.basename(readme_path)), 'wb') do |out_f|
|
12
|
+
IO.copy_stream(in_f, out_f)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'halite/error'
|
2
|
+
|
3
|
+
module Halite
|
4
|
+
module Dependencies
|
5
|
+
class InvalidDependencyError < Error; end
|
6
|
+
|
7
|
+
Dependency = Struct.new(:name, :requirement, :type)
|
8
|
+
|
9
|
+
def self.extract(spec)
|
10
|
+
deps = []
|
11
|
+
deps += clean_and_tag(extract_from_requirements(spec), :requirements)
|
12
|
+
deps += clean_and_tag(extract_from_metadata(spec), :metadata)
|
13
|
+
deps += clean_and_tag(extract_from_dependencies(spec), :dependencies)
|
14
|
+
deps
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.extract_from_requirements(spec)
|
18
|
+
# Simple dependencies in the requirements array.
|
19
|
+
spec.requirements
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.extract_from_metadata(spec)
|
23
|
+
# This will only work on Rubygems 2.0 or higher I think, gee thats just too bad.
|
24
|
+
# The metadata can only be a single string, so split on comma.
|
25
|
+
spec.metadata.fetch('halite_dependencies', '').split(/,/)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.extract_from_dependencies(spec)
|
29
|
+
# Find any gem dependencies that are cookbooks in disguise.
|
30
|
+
spec.dependencies.select do |dep|
|
31
|
+
Gem.new(dep).is_halite_cookbook?
|
32
|
+
end.map do |dep|
|
33
|
+
[Gem.new(dep).cookbook_name] + dep.requirements_list
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.clean_and_tag(deps, tag)
|
38
|
+
deps.map do |dep|
|
39
|
+
dep = clean(dep)
|
40
|
+
Dependency.new(dep[0], dep[1], tag)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
def self.clean(dep)
|
46
|
+
# Convert to an array of strings
|
47
|
+
dep = Array(dep).map {|obj| obj.to_s.strip }
|
48
|
+
# Unpack single strings like 'foo >= 1.0'
|
49
|
+
dep = dep.first.split(/\s+/, 2) if dep.length == 1
|
50
|
+
# Default version constraint to match rubygems behavior when sourcing from simple strings
|
51
|
+
dep << '>= 0' if dep.length == 1
|
52
|
+
raise InvalidDependencyError.new("Chef only supports a single version constraint on each dependency: #{dep}") if dep.length > 2 # ಠ_ಠ
|
53
|
+
dep[1] = clean_requirement(dep[1])
|
54
|
+
dep
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.clean_requirement(req)
|
58
|
+
req = ::Gem::Requirement.create(req)
|
59
|
+
req.requirements[0][1] = clean_version(req.requirements[0][1])
|
60
|
+
req.to_s
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.clean_version(ver)
|
64
|
+
segments = ver.segments
|
65
|
+
# Various ways Chef differs from Rubygems
|
66
|
+
raise InvalidDependencyError.new("Chef only supports two or three version segments: #{ver}") if segments.length < 1 || segments.length > 3
|
67
|
+
segments.each {|s| raise InvalidDependencyError.new("Chef does not support pre-release version numbers: #{ver}") unless s.is_a?(Integer) }
|
68
|
+
segments << 0 if segments.length == 1
|
69
|
+
::Gem::Version.new(segments.join('.'))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/halite/error.rb
ADDED
data/lib/halite/gem.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'halite/dependencies'
|
2
|
+
|
3
|
+
module Halite
|
4
|
+
class Gem
|
5
|
+
# name can be either a string name, Gem::Dependency, or Gem::Specification
|
6
|
+
def initialize(name, version=nil)
|
7
|
+
name = name.to_spec if name.is_a?(::Gem::Dependency) # Allow passing either
|
8
|
+
if name.is_a?(::Gem::Specification)
|
9
|
+
raise Error.new("Cannot pass version when using an explicit specficiation") if version
|
10
|
+
@spec = name
|
11
|
+
@name = spec.name
|
12
|
+
else
|
13
|
+
@name = name
|
14
|
+
@version = version
|
15
|
+
raise Error.new("Gem #{name}#{version ? " v#{version}" : ''} not found") unless spec
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def spec
|
20
|
+
@spec ||= ::Gem::Dependency.new(@name, ::Gem::Requirement.new(@version)).to_spec
|
21
|
+
end
|
22
|
+
|
23
|
+
def method_missing(*args)
|
24
|
+
spec.send(*args)
|
25
|
+
end
|
26
|
+
|
27
|
+
def version
|
28
|
+
spec.version.to_s
|
29
|
+
end
|
30
|
+
|
31
|
+
def cookbook_name
|
32
|
+
if spec.metadata.include?('halite_name')
|
33
|
+
spec.metadata['halite_name']
|
34
|
+
else
|
35
|
+
spec.name.gsub(/(^(chef|cookbook)[_-])|([_-](chef|cookbook))$/, '')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# The Rubygems API is shit and just assumes the file layout
|
40
|
+
def spec_file
|
41
|
+
File.join(spec.full_gem_path, spec.name + '.gemspec')
|
42
|
+
end
|
43
|
+
|
44
|
+
def license_header
|
45
|
+
IO.readlines(spec_file).take_while { |line| line.strip.empty? || line.strip.start_with?('#') }.join('')
|
46
|
+
end
|
47
|
+
|
48
|
+
def each_file(prefix_paths=nil, &block)
|
49
|
+
files = []
|
50
|
+
spec.files.each do |path|
|
51
|
+
prefix = if prefix_paths
|
52
|
+
Array(prefix_paths).map {|p| p.end_with?('/') ? p : p + '/' }.find {|p| path.start_with?(p) }
|
53
|
+
else
|
54
|
+
''
|
55
|
+
end
|
56
|
+
next unless prefix # No match
|
57
|
+
value = [
|
58
|
+
File.join(spec.full_gem_path, path), # Full path
|
59
|
+
path[prefix.length..-1], # Relative path
|
60
|
+
]
|
61
|
+
files << value
|
62
|
+
block.call(*value) if block
|
63
|
+
end
|
64
|
+
files.sort! # To be safe
|
65
|
+
end
|
66
|
+
|
67
|
+
# Special case of the above using spec's require paths
|
68
|
+
def each_library_file(&block)
|
69
|
+
each_file(spec.require_paths, &block)
|
70
|
+
end
|
71
|
+
|
72
|
+
def cookbook_dependencies
|
73
|
+
@cookbook_dependencies ||= Dependencies.extract(spec)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Is this gem really a cookbook? (anything that depends directly on halite and doesn't have the ignore flag)
|
77
|
+
def is_halite_cookbook?
|
78
|
+
spec.dependencies.any? {|subdep| subdep.name == 'halite'} && !spec.metadata.include?('halite_ignore')
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
# Much inspiration from Bundler's GemHelper. Thanks!
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'thor/shell'
|
4
|
+
|
5
|
+
require 'halite'
|
6
|
+
require 'halite/error'
|
7
|
+
|
8
|
+
module Halite
|
9
|
+
class RakeHelper
|
10
|
+
include Rake::DSL if defined? Rake::DSL
|
11
|
+
|
12
|
+
def self.install_tasks(*args)
|
13
|
+
new(*args).install
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_accessor :gem_name, :base, :cookbook_name
|
17
|
+
|
18
|
+
def initialize(gem_name=nil, base=nil, no_gem=nil, no_foodcritic=nil, no_kitchen=nil)
|
19
|
+
if gem_name.is_a?(Hash)
|
20
|
+
opts = gem_name.inject({}) {|memo, (key, value)| memo[key.to_s] = value; memo }
|
21
|
+
gem_name = opts['gem_name']
|
22
|
+
base = opts['base']
|
23
|
+
no_gem = opts['no_gem']
|
24
|
+
no_foodcritic = opts['no_foodcritic']
|
25
|
+
no_kitchen = opts['no_kitchen']
|
26
|
+
end
|
27
|
+
# Order is important, find_gem_name needs base to be set
|
28
|
+
@base = base || if defined? Rake
|
29
|
+
Rake.original_dir
|
30
|
+
else
|
31
|
+
Dir.pwd
|
32
|
+
end
|
33
|
+
@gem_name = gem_name || find_gem_name
|
34
|
+
@gemspec = Bundler.load_gemspec(@gem_name+'.gemspec')
|
35
|
+
@no_gem = no_gem
|
36
|
+
@no_foodcritic = no_foodcritic
|
37
|
+
@no_kitchen = no_kitchen
|
38
|
+
end
|
39
|
+
|
40
|
+
def find_gem_name
|
41
|
+
specs = Dir[File.join(base, '*.gemspec')]
|
42
|
+
raise Error.new("Unable to automatically determine gem name from specs in #{base}. Please set the gem name via Halite::RakeHelper.install_tasks(gem_name: 'name').") if specs.length != 1
|
43
|
+
File.basename(specs.first, '.gemspec')
|
44
|
+
end
|
45
|
+
|
46
|
+
def pkg_path
|
47
|
+
@pkg_path ||= File.join(base, 'pkg', "#{@gem_name}-#{@gemspec.version}")
|
48
|
+
end
|
49
|
+
|
50
|
+
def shell
|
51
|
+
@shell ||= if @no_color || !STDOUT.tty?
|
52
|
+
Thor::Shell::Basic
|
53
|
+
else
|
54
|
+
Thor::Base.shell
|
55
|
+
end.new
|
56
|
+
end
|
57
|
+
|
58
|
+
def install
|
59
|
+
# Core Halite tasks
|
60
|
+
desc "Convert #{@gem_name}-#{@gemspec.version} to a cookbook in the pkg directory"
|
61
|
+
task 'chef:build' do
|
62
|
+
build_cookbook
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "Push #{@gem_name}-#{@gemspec.version} to Supermarket"
|
66
|
+
task 'chef:release' => ['chef:build'] do
|
67
|
+
release_cookbook
|
68
|
+
end
|
69
|
+
|
70
|
+
# Patch the core gem tasks to run ours too
|
71
|
+
if !@no_gem
|
72
|
+
task 'build' => ['chef:build']
|
73
|
+
task 'release' => ['chef:release']
|
74
|
+
end
|
75
|
+
|
76
|
+
# Foodcritic doesn't have a config file, so just always try to add it.
|
77
|
+
if !@no_foodcritic
|
78
|
+
install_foodcritic
|
79
|
+
end
|
80
|
+
|
81
|
+
# If a .kitchen.yml exists, install the Test Kitchen tasks.
|
82
|
+
if !@no_kitchen && File.exists?(File.join(@base, '.kitchen.yml'))
|
83
|
+
install_kitchen
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def install_foodcritic
|
88
|
+
require 'foodcritic'
|
89
|
+
|
90
|
+
desc 'Run Foodcritic linter'
|
91
|
+
task 'chef:foodcritic' do
|
92
|
+
Dir.mktmpdir('halite_test') do |path|
|
93
|
+
Halite.convert(gem_name, path)
|
94
|
+
sh("foodcritic -f any '#{path}'")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
add_test_task('chef:foodcritic')
|
99
|
+
rescue LoadError
|
100
|
+
task 'chef:foodcritic' do
|
101
|
+
raise "Foodcritic is not available. You can use Halite::RakeHelper.install_tasks(no_foodcritic: true) to disable it."
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def install_kitchen
|
106
|
+
desc 'Run all Test Kitchen tests'
|
107
|
+
task 'chef:kitchen' do
|
108
|
+
sh 'kitchen test -d always'
|
109
|
+
end
|
110
|
+
|
111
|
+
add_test_task('chef:kitchen')
|
112
|
+
end
|
113
|
+
|
114
|
+
def add_test_task(name)
|
115
|
+
# Only set a description if the task doesn't already exist
|
116
|
+
desc 'Run all tests' unless Rake.application.lookup('test')
|
117
|
+
task :test => [name]
|
118
|
+
end
|
119
|
+
|
120
|
+
def build_cookbook
|
121
|
+
# Make sure pkg/name-version exists and is empty
|
122
|
+
FileUtils.mkdir_p(pkg_path)
|
123
|
+
remove_files_in_folder(pkg_path)
|
124
|
+
Halite.convert(gem_name, pkg_path)
|
125
|
+
shell.say("#{@gem_name} #{@gemspec.version} converted to pkg/#{@gem_name}-#{@gemspec.version}/.", :green)
|
126
|
+
end
|
127
|
+
|
128
|
+
def release_cookbook
|
129
|
+
Dir.chdir(pkg_path) do
|
130
|
+
#sh('stove --sign')
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Remove everything in a path, but not the directory itself
|
135
|
+
def remove_files_in_folder(base_path)
|
136
|
+
existing_files = Dir.glob(File.join(base_path, '**', '*'), File::FNM_DOTMATCH).map {|path| File.expand_path(path)}.uniq.reverse # expand_path just to normalize foo/. -> foo
|
137
|
+
existing_files.delete(base_path) # Don't remove the base
|
138
|
+
# Fuck FileUtils, it is a confusing pile of fail for remove*/rm*
|
139
|
+
existing_files.each do |path|
|
140
|
+
if File.file?(path)
|
141
|
+
File.unlink(path)
|
142
|
+
elsif File.directory?(path)
|
143
|
+
Dir.unlink(path)
|
144
|
+
else
|
145
|
+
# Because paranoia
|
146
|
+
raise Error.new("Unknown type of file at '#{path}', possible symlink deletion attack")
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|