halite 1.0.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|