halite 1.0.0.rc.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rubocop.yml +20 -0
  4. data/.travis.yml +14 -4
  5. data/.yardopts +7 -0
  6. data/CHANGELOG.md +5 -0
  7. data/Gemfile +30 -8
  8. data/LICENSE +202 -202
  9. data/README.md +104 -2
  10. data/Rakefile +25 -5
  11. data/gemfiles/default.gemfile +17 -0
  12. data/gemfiles/master.gemfile +21 -0
  13. data/halite.gemspec +21 -10
  14. data/lib/berkshelf/halite.rb +25 -0
  15. data/lib/berkshelf/locations/gem.rb +84 -0
  16. data/lib/halite.rb +34 -4
  17. data/lib/halite/berkshelf/helper.rb +8 -2
  18. data/lib/halite/berkshelf/source.rb +9 -1
  19. data/lib/halite/converter.rb +34 -10
  20. data/lib/halite/converter/chef.rb +43 -0
  21. data/lib/halite/converter/libraries.rb +93 -26
  22. data/lib/halite/converter/metadata.rb +48 -10
  23. data/lib/halite/converter/misc.rb +43 -0
  24. data/lib/halite/dependencies.rb +48 -8
  25. data/lib/halite/error.rb +20 -0
  26. data/lib/halite/gem.rb +106 -21
  27. data/lib/halite/helper_base.rb +129 -0
  28. data/lib/halite/rake_helper.rb +46 -60
  29. data/lib/halite/rake_tasks.rb +17 -1
  30. data/lib/halite/spec_helper.rb +403 -54
  31. data/lib/halite/spec_helper/patcher.rb +130 -0
  32. data/lib/halite/spec_helper/runner.rb +57 -9
  33. data/lib/halite/version.rb +19 -1
  34. data/spec/converter/chef_spec.rb +54 -0
  35. data/spec/converter/libraries_spec.rb +131 -123
  36. data/spec/converter/metadata_spec.rb +61 -8
  37. data/spec/converter/misc_spec.rb +61 -0
  38. data/spec/converter_spec.rb +21 -6
  39. data/spec/dependencies_spec.rb +64 -10
  40. data/spec/example_resources/poise.rb +42 -0
  41. data/spec/example_resources/simple.rb +48 -0
  42. data/spec/{data/gems/test1/lib → fixtures/cookbooks/test1/files/halite_gem}/test1.rb +0 -0
  43. data/spec/{data/gems/test1/lib → fixtures/cookbooks/test1/files/halite_gem}/test1/version.rb +0 -0
  44. data/spec/fixtures/cookbooks/test1/libraries/default.rb +4 -0
  45. data/spec/{data/integration_cookbooks → fixtures/cookbooks}/test1/metadata.rb +0 -0
  46. data/spec/{data/gems/test2/chef → fixtures/cookbooks/test2}/attributes.rb +0 -0
  47. data/spec/{data/gems/test2/lib → fixtures/cookbooks/test2/files/halite_gem}/test2.rb +0 -0
  48. data/spec/{data/gems/test2/lib → fixtures/cookbooks/test2/files/halite_gem}/test2/resource.rb +0 -0
  49. data/spec/{data/gems/test2/lib → fixtures/cookbooks/test2/files/halite_gem}/test2/version.rb +0 -0
  50. data/spec/fixtures/cookbooks/test2/libraries/default.rb +3 -0
  51. data/spec/{data/integration_cookbooks → fixtures/cookbooks}/test2/metadata.rb +1 -1
  52. data/spec/{data/gems/test2/chef → fixtures/cookbooks/test2}/recipes/default.rb +0 -0
  53. data/spec/{data/gems/test2/chef → fixtures/cookbooks/test2}/templates/default/conf.erb +0 -0
  54. data/spec/{data/gems/test3/lib → fixtures/cookbooks/test3/files/halite_gem}/test3.rb +0 -0
  55. data/spec/{data/gems/test3/lib → fixtures/cookbooks/test3/files/halite_gem}/test3/dsl.rb +0 -0
  56. data/spec/{data/gems/test3/lib → fixtures/cookbooks/test3/files/halite_gem}/test3/version.rb +0 -0
  57. data/spec/fixtures/cookbooks/test3/libraries/default.rb +4 -0
  58. data/spec/{data/integration_cookbooks → fixtures/cookbooks}/test3/metadata.rb +0 -0
  59. data/spec/{data/gems/test3/chef → fixtures/cookbooks/test3}/recipes/default.rb +0 -0
  60. data/spec/{data → fixtures}/gems/test1/Rakefile +0 -0
  61. data/spec/fixtures/gems/test1/lib/test1.rb +2 -0
  62. data/spec/fixtures/gems/test1/lib/test1/version.rb +3 -0
  63. data/spec/{data → fixtures}/gems/test1/test1.gemspec +0 -0
  64. data/spec/{data → fixtures}/gems/test2/Rakefile +0 -0
  65. data/spec/{data/integration_cookbooks/test2 → fixtures/gems/test2/chef}/attributes.rb +0 -0
  66. data/spec/{data/integration_cookbooks/test2 → fixtures/gems/test2/chef}/recipes/default.rb +0 -0
  67. data/spec/{data/integration_cookbooks/test2 → fixtures/gems/test2/chef}/templates/default/conf.erb +0 -0
  68. data/spec/fixtures/gems/test2/lib/test2.rb +4 -0
  69. data/spec/{data/integration_cookbooks/test2/libraries/test2__resource.rb → fixtures/gems/test2/lib/test2/resource.rb} +1 -2
  70. data/spec/fixtures/gems/test2/lib/test2/version.rb +3 -0
  71. data/spec/{data → fixtures}/gems/test2/test2.gemspec +0 -0
  72. data/spec/{data → fixtures}/gems/test3/Rakefile +0 -0
  73. data/spec/{data/integration_cookbooks/test3 → fixtures/gems/test3/chef}/recipes/default.rb +0 -0
  74. data/spec/fixtures/gems/test3/lib/test3.rb +4 -0
  75. data/spec/{data/integration_cookbooks/test3/libraries/test3__dsl.rb → fixtures/gems/test3/lib/test3/dsl.rb} +1 -2
  76. data/spec/fixtures/gems/test3/lib/test3/version.rb +3 -0
  77. data/spec/{data → fixtures}/gems/test3/test3.gemspec +1 -0
  78. data/spec/gem_spec.rb +41 -31
  79. data/spec/integration_spec.rb +58 -82
  80. data/spec/runner_spec.rb +108 -0
  81. data/spec/spec_helper.rb +19 -26
  82. data/spec/spec_helper_spec.rb +238 -0
  83. metadata +124 -151
  84. data/lib/halite/converter/other.rb +0 -19
  85. data/lib/halite/converter/readme.rb +0 -20
  86. data/spec/converter/other_spec.rb +0 -56
  87. data/spec/converter/readme_spec.rb +0 -55
  88. data/spec/data/integration_cookbooks/test1/libraries/test1.rb +0 -3
  89. data/spec/data/integration_cookbooks/test1/libraries/test1__version.rb +0 -4
  90. data/spec/data/integration_cookbooks/test2/libraries/test2.rb +0 -5
  91. data/spec/data/integration_cookbooks/test2/libraries/test2__version.rb +0 -4
  92. data/spec/data/integration_cookbooks/test3/libraries/test3.rb +0 -5
  93. data/spec/data/integration_cookbooks/test3/libraries/test3__version.rb +0 -4
@@ -1,17 +1,41 @@
1
- require 'halite/converter/libraries'
2
- require 'halite/converter/metadata'
3
- require 'halite/converter/other'
4
- require 'halite/converter/readme'
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
+
5
17
 
6
18
  module Halite
19
+ # (see Converter.write)
7
20
  module Converter
21
+ autoload :Chef, 'halite/converter/chef'
22
+ autoload :Libraries, 'halite/converter/libraries'
23
+ autoload :Metadata, 'halite/converter/metadata'
24
+ autoload :Misc, 'halite/converter/misc'
8
25
 
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)
26
+ # Convert a cookbook gem to a normal Chef cookbook.
27
+ #
28
+ # @since 1.0.0
29
+ # @param gem_data [Halite::Gem] Gem to convert.
30
+ # @param output_path [String] Output path.
31
+ # @return [void]
32
+ # @example
33
+ # Halite::Converter.write(Halite::Gem.new(gemspec), 'dest')
34
+ def self.write(gem_data, output_path)
35
+ Chef.write(gem_data, output_path)
36
+ Libraries.write(gem_data, output_path)
37
+ Metadata.write(gem_data, output_path)
38
+ Misc.write(gem_data, output_path)
14
39
  end
15
-
16
40
  end
17
41
  end
@@ -0,0 +1,43 @@
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 'fileutils'
18
+
19
+
20
+ module Halite
21
+ module Converter
22
+ # Converter module for cookbook-specific files. These are copied verbatim
23
+ # from the chef/ directory in the gem.
24
+ #
25
+ # @since 1.0.0
26
+ # @api private
27
+ module Chef
28
+ # Copy all files in the chef/ directory in the gem.
29
+ #
30
+ # @param gem_data [Halite::Gem] Gem to generate from.
31
+ # @param output_path [String] Output path for the cookbook.
32
+ # @return [void]
33
+ def self.write(gem_data, output_path)
34
+ gem_data.each_file('chef') do |path, rel_path|
35
+ dir_path = File.dirname(rel_path)
36
+ FileUtils.mkdir_p(File.join(output_path, dir_path)) unless dir_path == '.'
37
+ FileUtils.copy(path, File.join(output_path, rel_path), preserve: true)
38
+ end
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -1,40 +1,107 @@
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 'fileutils'
18
+
19
+
1
20
  module Halite
2
21
  module Converter
22
+ # Converter methods for gem library code (ex. files under lib/).
23
+ #
24
+ # @since 1.0.0
25
+ # @api private
3
26
  module Libraries
4
-
5
- # Chef doesn't allow subfolders under libraries/ currently
6
- def self.flatten_filename(path)
7
- path.gsub(/\//, '__')
27
+ # Generate the bootstrap code for the Chef cookbook.
28
+ #
29
+ # @param gem_data [Halite::Gem] Gem to generate from.
30
+ # @param entry_points [Array<String>] Zero or more entry points to be
31
+ # automatically loaded.
32
+ # @return [String]
33
+ def self.generate_bootstrap(gem_data, entry_points)
34
+ ''.tap do |buf|
35
+ buf << gem_data.license_header
36
+ buf << <<-EOH
37
+ raise 'Halite is not compatible with no_lazy_load false, please set no_lazy_load true in your Chef configuration file.' unless Chef::Config[:no_lazy_load]
38
+ $LOAD_PATH << File.expand_path('../../files/halite_gem', __FILE__)
39
+ EOH
40
+ entry_points.each do |entry_point|
41
+ buf << "require #{entry_point.inspect}\n"
42
+ end
43
+ end
8
44
  end
9
45
 
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)}'" }
46
+ # Copy all library code to the files/halite_gem/ directory in the cookbook.
47
+ #
48
+ # @param gem_data [Halite::Gem] Gem to generate from.
49
+ # @param output_path [String] Output path for the cookbook.
50
+ # @return [void]
51
+ def self.write_libraries(gem_data, output_path)
52
+ dest_path = File.join(output_path, 'files', 'halite_gem')
53
+ FileUtils.mkdir_p(dest_path)
54
+ gem_data.each_library_file do |path, rel_path|
55
+ dir_path = File.dirname(rel_path)
56
+ FileUtils.mkdir_p(File.join(dest_path, dir_path)) unless dir_path == '.'
57
+ FileUtils.copy(path, File.join(dest_path, rel_path), preserve: true)
19
58
  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
59
  end
25
60
 
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))
61
+ # Find any default entry points (files name cheftie.rb) in the gem.
62
+ #
63
+ # @param gem_data [Halite::Gem] Gem to generate from.
64
+ # @return [Array<String>]
65
+ def self.find_default_entry_points(gem_data)
66
+ [].tap do |entry_points|
67
+ gem_data.each_library_file do |_path, rel_path|
68
+ if File.basename(rel_path) == 'cheftie.rb'
69
+ # Trim the .rb for cleanliness.
70
+ entry_points << rel_path[0..-4]
71
+ end
72
+ end
35
73
  end
36
74
  end
37
75
 
76
+ # Create the bootstrap code in the cookbook.
77
+ #
78
+ # @param gem_data [Halite::Gem] Gem to generate from.
79
+ # @param output_path [String] Output path for the cookbook.
80
+ # @param entry_point [String, Array<String>] Entry point(s) for the
81
+ # bootstrap. These are require paths that will be loaded automatically
82
+ # during a Chef converge.
83
+ # @return [void]
84
+ def self.write_bootstrap(gem_data, output_path, entry_point=nil)
85
+ # Default entry point.
86
+ entry_point ||= gem_data.spec.metadata['halite_entry_point'] || find_default_entry_points(gem_data)
87
+ # Parse and cast.
88
+ entry_point = Array(entry_point).map {|s| s.split }.flatten
89
+ # Write bootstrap file.
90
+ lib_path = File.join(output_path, 'libraries')
91
+ FileUtils.mkdir_p(lib_path)
92
+ IO.write(File.join(lib_path, 'default.rb'), generate_bootstrap(gem_data, entry_point))
93
+ end
94
+
95
+ # Write out the library code for the cookbook.
96
+ #
97
+ # @param gem_data [Halite::Gem] Gem to generate from.
98
+ # @param output_path [String] Output path for the cookbook.
99
+ # @return [void]
100
+ def self.write(gem_data, output_path, entry_point=nil)
101
+ write_libraries(gem_data, output_path)
102
+ write_bootstrap(gem_data, output_path, entry_point)
103
+ end
104
+
38
105
  end
39
106
  end
40
107
  end
@@ -1,19 +1,57 @@
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
+
1
18
  module Halite
2
19
  module Converter
20
+ # Converter module to create the metadata.rb for the cookbook.
21
+ #
22
+ # @since 1.0.0
23
+ # @api private
3
24
  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"
25
+ # Generate a cookbook metadata file.
26
+ #
27
+ # @param gem_data [Halite::Gem] Gem to generate from.
28
+ # @return [String]
29
+ def self.generate(gem_data)
30
+ ''.tap do |buf|
31
+ buf << gem_data.license_header
32
+ buf << "name #{gem_data.cookbook_name.inspect}\n"
33
+ buf << "version #{gem_data.version.inspect}\n"
34
+ if gem_data.spec.description && !gem_data.spec.description.empty?
35
+ buf << "description #{gem_data.spec.description.inspect}\n"
36
+ end
37
+ if readme_path = gem_data.find_misc_path('Readme') # rubocop:disable Lint/AssignmentInCondition
38
+ buf << "long_description #{IO.read(readme_path).inspect}\n"
39
+ end
40
+ gem_data.cookbook_dependencies.each do |dep|
41
+ buf << "depends #{dep.name.inspect}"
42
+ buf << ", #{dep.requirement.inspect}" if dep.requirement != '>= 0'
43
+ buf << "\n"
44
+ end
11
45
  end
12
- buf
13
46
  end
14
47
 
15
- def self.write(spec, base_path)
16
- IO.write(File.join(base_path, 'metadata.rb'), generate(spec))
48
+ # Write out a cookbook metadata file.
49
+ #
50
+ # @param gem_data [Halite::Gem] Gem to generate from.
51
+ # @param output_path [String] Output path for the cookbook.
52
+ # @return [void]
53
+ def self.write(gem_data, output_path)
54
+ IO.write(File.join(output_path, 'metadata.rb'), generate(gem_data))
17
55
  end
18
56
 
19
57
  end
@@ -0,0 +1,43 @@
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 'fileutils'
18
+
19
+
20
+ module Halite
21
+ module Converter
22
+ # Converter module for miscellanous project-level files like README.md
23
+ # and LICENSE.txt.
24
+ #
25
+ # @since 1.0.0
26
+ # @api private
27
+ module Misc
28
+ # Copy miscellaneous project-level files.
29
+ #
30
+ # @param gem_data [Halite::Gem] Gem to generate from.
31
+ # @param output_path [String] Output path for the cookbook.
32
+ # @return [void]
33
+ def self.write(gem_data, output_path)
34
+ %w{Readme License Copying Contributing}.each do |name|
35
+ if path = gem_data.find_misc_path(name) # rubocop:disable Lint/AssignmentInCondition
36
+ FileUtils.copy(path, File.join(output_path, File.basename(path)), preserve: true)
37
+ end
38
+ end
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -1,10 +1,43 @@
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
+
1
17
  require 'halite/error'
2
18
 
19
+
3
20
  module Halite
21
+ # Error class for invalid dependencies.
22
+ #
23
+ # @since 1.0.0
24
+ class InvalidDependencyError < Error; end
25
+
26
+ # Methods to extract cookbook dependencies from a gem.
27
+ #
28
+ # @since 1.0.0
4
29
  module Dependencies
5
- class InvalidDependencyError < Error; end
30
+ Dependency = Struct.new(:name, :requirement, :type, :spec) do
31
+ def ==(other)
32
+ self.name == other.name && \
33
+ self.requirement == other.requirement && \
34
+ self.type == other.type
35
+ end
6
36
 
7
- Dependency = Struct.new(:name, :requirement, :type)
37
+ def cookbook
38
+ Gem.new(spec) if spec
39
+ end
40
+ end
8
41
 
9
42
  def self.extract(spec)
10
43
  deps = []
@@ -28,29 +61,35 @@ module Halite
28
61
  def self.extract_from_dependencies(spec)
29
62
  # Find any gem dependencies that are cookbooks in disguise.
30
63
  spec.dependencies.select do |dep|
31
- Gem.new(dep).is_halite_cookbook?
64
+ dep.type == :runtime && Gem.new(dep).is_halite_cookbook?
32
65
  end.map do |dep|
33
- [Gem.new(dep).cookbook_name] + dep.requirements_list
66
+ gem = Gem.new(dep)
67
+ [gem.cookbook_name] + dep.requirements_list + [gem.spec]
34
68
  end
35
69
  end
36
70
 
37
71
  def self.clean_and_tag(deps, tag)
38
72
  deps.map do |dep|
39
73
  dep = clean(dep)
40
- Dependency.new(dep[0], dep[1], tag)
74
+ Dependency.new(dep[0], dep[1], tag, dep[2])
41
75
  end
42
76
  end
43
77
 
44
-
45
78
  def self.clean(dep)
46
- # Convert to an array of strings
47
- dep = Array(dep).map {|obj| obj.to_s.strip }
79
+ # Convert to an array of strings, remove the spec to be re-added later.
80
+ dep = Array(dep)
81
+ spec = if dep.last.is_a?(::Gem::Specification)
82
+ dep.pop
83
+ end
84
+ dep = Array(dep).map {|obj| obj.is_a?(::Gem::Specification) ? obj : obj.to_s.strip }
48
85
  # Unpack single strings like 'foo >= 1.0'
49
86
  dep = dep.first.split(/\s+/, 2) if dep.length == 1
50
87
  # Default version constraint to match rubygems behavior when sourcing from simple strings
51
88
  dep << '>= 0' if dep.length == 1
52
89
  raise InvalidDependencyError.new("Chef only supports a single version constraint on each dependency: #{dep}") if dep.length > 2 # ಠ_ಠ
53
90
  dep[1] = clean_requirement(dep[1])
91
+ # Re-add the spec
92
+ dep << spec if spec
54
93
  dep
55
94
  end
56
95
 
@@ -66,6 +105,7 @@ module Halite
66
105
  raise InvalidDependencyError.new("Chef only supports two or three version segments: #{ver}") if segments.length < 1 || segments.length > 3
67
106
  segments.each {|s| raise InvalidDependencyError.new("Chef does not support pre-release version numbers: #{ver}") unless s.is_a?(Integer) }
68
107
  segments << 0 if segments.length == 1
108
+ segments = [0] if segments.all? {|s| s == 0 }
69
109
  ::Gem::Version.new(segments.join('.'))
70
110
  end
71
111
  end
data/lib/halite/error.rb CHANGED
@@ -1,4 +1,24 @@
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
+
1
18
  module Halite
19
+ # Base class for Halite library errors.
20
+ #
21
+ # @since 1.0.0
2
22
  class Error < ::Exception
3
23
  end
4
24
  end