batali 0.4.10 → 0.5.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.
@@ -1,13 +1,12 @@
1
- require 'batali'
2
- require 'stringio'
3
- require 'fileutils'
4
- require 'tmpdir'
1
+ require "batali"
2
+ require "stringio"
3
+ require "fileutils"
4
+ require "tmpdir"
5
5
 
6
6
  # ChefSpec namespace
7
7
  module ChefSpec
8
8
  # Batali integration class
9
9
  class Batali
10
-
11
10
  class << self
12
11
  extend Forwardable
13
12
  def_delegators :instance, :setup!, :teardown!
@@ -17,24 +16,24 @@ module ChefSpec
17
16
 
18
17
  # Create new instance
19
18
  def initialize
20
- @vendor_path = Dir.mktmpdir
19
+ @vendor_path = Utility.clean_path(Dir.mktmpdir)
21
20
  end
22
21
 
23
22
  # Setup the environment (load cookbooks)
24
23
  def setup!
25
- output = ''
24
+ output = ""
26
25
  begin
27
26
  ::Batali::Command::Update.new(
28
27
  Smash.new(
29
- :file => File.join(Dir.pwd, 'Batali'),
28
+ :file => Utility.join_path(Dir.pwd, "Batali"),
30
29
  :path => @vendor_path,
31
30
  :update => {
32
- :install => true
31
+ :install => true,
33
32
  },
34
33
  :ui => Bogo::Ui.new(
35
- :app_name => 'Batali',
36
- :output_to => StringIO.new(output)
37
- )
34
+ :app_name => "Batali",
35
+ :output_to => StringIO.new(output),
36
+ ),
38
37
  ),
39
38
  []
40
39
  ).execute!
@@ -50,15 +49,14 @@ module ChefSpec
50
49
 
51
50
  # Clean up after complete
52
51
  def teardown!
53
- if(File.directory?(@vendor_path))
52
+ if File.directory?(@vendor_path)
54
53
  FileUtils.rm_rf(@vendor_path)
55
54
  end
56
55
  end
57
-
58
56
  end
59
57
  end
60
58
 
61
59
  RSpec.configure do |config|
62
- config.before(:suite){ ChefSpec::Batali.setup! }
63
- config.after(:suite){ ChefSpec::Batali.teardown! }
60
+ config.before(:suite) { ChefSpec::Batali.setup! }
61
+ config.after(:suite) { ChefSpec::Batali.teardown! }
64
62
  end
@@ -1,21 +1,20 @@
1
- require 'batali'
2
- require 'fileutils'
1
+ require "batali"
2
+ require "fileutils"
3
3
 
4
4
  module Batali
5
5
  # Customized command base for Batali
6
6
  class Command < Bogo::Cli::Command
7
-
8
- DEFAULT_CONFIGURATION_FILES = ['.batali']
7
+ DEFAULT_CONFIGURATION_FILES = [".batali"]
9
8
 
10
9
  include Bogo::Memoization
11
10
 
12
- autoload :Cache, 'batali/command/cache'
13
- autoload :Configure, 'batali/command/configure'
14
- autoload :Display, 'batali/command/display'
15
- autoload :Install, 'batali/command/install'
16
- autoload :Resolve, 'batali/command/resolve'
17
- autoload :Supermarket, 'batali/command/supermarket'
18
- autoload :Update, 'batali/command/update'
11
+ autoload :Cache, "batali/command/cache"
12
+ autoload :Configure, "batali/command/configure"
13
+ autoload :Display, "batali/command/display"
14
+ autoload :Install, "batali/command/install"
15
+ autoload :Resolve, "batali/command/resolve"
16
+ autoload :Supermarket, "batali/command/supermarket"
17
+ autoload :Update, "batali/command/update"
19
18
 
20
19
  # Set UI when loading via command
21
20
  def initialize(*_)
@@ -27,14 +26,14 @@ module Batali
27
26
  def batali_file
28
27
  memoize(:batali_file) do
29
28
  # TODO: Add directory traverse searching
30
- path = config.fetch(:file, File.join(Dir.pwd, 'Batali'))
29
+ path = Utility.clean_path(config.fetch(:file, File.join(Dir.pwd, "Batali")))
31
30
  ui.verbose "Loading Batali file from: #{path}"
32
31
  bfile = BFile.new(path, cache_directory)
33
- if(bfile.discover)
32
+ if bfile.discover
34
33
  bfile.auto_discover!(config[:environment])
35
34
  end
36
35
  bfile.data.keys.each do |key|
37
- unless(bfile.respond_to?(key))
36
+ unless bfile.respond_to?(key)
38
37
  ui.warn "Unknown keyword used within Batali file: #{key.inspect}"
39
38
  end
40
39
  end
@@ -45,23 +44,32 @@ module Batali
45
44
  # @return [Manifest]
46
45
  def manifest
47
46
  memoize(:manifest) do
48
- path = File.join(
47
+ path = Utility.join_path(
49
48
  File.dirname(
50
- config.fetch(:file, File.join(Dir.pwd, 'batali.manifest'))
51
- ), 'batali.manifest'
49
+ config.fetch(:file, File.join(Dir.pwd, "batali.manifest"))
50
+ ), "batali.manifest"
52
51
  )
53
52
  ui.verbose "Loading manifest file from: #{path}"
54
53
  Manifest.build(path)
55
54
  end
56
55
  end
57
56
 
57
+ # @return [String] correct user home location for platform
58
+ def user_home
59
+ if (RUBY_PLATFORM =~ /mswin|mingw|windows/)
60
+ Utility.clean_path(ENV.fetch("LOCALAPPDATA", Dir.home))
61
+ else
62
+ Utility.clean_path(Dir.home)
63
+ end
64
+ end
65
+
58
66
  # @return [String] path to local cache
59
67
  def cache_directory(*args)
60
- memoize(['cache_directory', *args].join('_')) do
61
- directory = config.fetch(:cache_directory, File.join(Dir.home, '.batali', 'cache'))
68
+ memoize(["cache_directory", *args].join("_")) do
69
+ directory = Utility.clean_path(config.fetch(:cache_directory, File.join(user_home, ".batali", "cache")))
62
70
  ui.debug "Cache directory to persist cookbooks: #{directory}"
63
- unless(args.empty?)
64
- directory = File.join(directory, *args.map(&:to_s))
71
+ unless args.empty?
72
+ directory = Utility.join_path(directory, *args.map(&:to_s))
65
73
  end
66
74
  FileUtils.mkdir_p(directory)
67
75
  directory
@@ -73,7 +81,7 @@ module Batali
73
81
  # @param action [String] action to be performed
74
82
  # @yield block to execute
75
83
  def dry_run(action)
76
- if(config[:dry_run])
84
+ if config[:dry_run]
77
85
  ui.warn "Dry run disabled: #{action}"
78
86
  else
79
87
  yield
@@ -82,11 +90,8 @@ module Batali
82
90
 
83
91
  # @return [TrueClass, FalseClass] infrastructure mode
84
92
  def infrastructure?
85
- config[:infrastructure] || (
86
- config[:infrastructure].nil? &&
87
- manifest.infrastructure
88
- )
93
+ config[:infrastructure] || (config[:infrastructure].nil? &&
94
+ manifest.infrastructure)
89
95
  end
90
-
91
96
  end
92
97
  end
@@ -1,4 +1,4 @@
1
- require 'batali'
1
+ require "batali"
2
2
 
3
3
  module Batali
4
4
  class Command
@@ -8,17 +8,17 @@ module Batali
8
8
 
9
9
  # Display information from manifest
10
10
  def execute!
11
- if(opts[:scrub])
11
+ if opts[:scrub]
12
12
  scrub!
13
13
  end
14
- ui.puts ui.color('Batali cache information:', :bold) + "\n"
14
+ ui.puts ui.color("Batali cache information:", :bold) + "\n"
15
15
  display
16
16
  end
17
17
 
18
18
  # Remove all contents from local cache
19
19
  def scrub!
20
- ui.confirm "Remove all contents from local cache (#{cache_directory})"
21
- run_action 'Scrubbing local cache' do
20
+ ui.confirm "Remove all contents from local cache (#{cache_directory})" unless opts[:yes]
21
+ run_action "Scrubbing local cache" do
22
22
  FileUtils.rm_rf(cache_directory)
23
23
  nil
24
24
  end
@@ -26,19 +26,17 @@ module Batali
26
26
 
27
27
  # Display local cache information
28
28
  def display
29
- cache_size = Dir.glob(File.join(cache_directory, '**', '**', '*')).map do |path|
29
+ cache_size = Dir.glob(Utility.join_path(cache_directory, "**", "**", "*")).map do |path|
30
30
  File.size(path) if File.file?(path)
31
31
  end.compact.inject(&:+).to_i
32
- cache_size = "#{sprintf('%.2f', ((cache_size / 1024.to_f) / 1024))}M"
32
+ cache_size = "#{sprintf("%.2f", ((cache_size / 1024.to_f) / 1024))}M"
33
33
  [
34
- "#{ui.color('Path:', :bold)} #{cache_directory}",
35
- "#{ui.color('Size:', :bold)} #{cache_size}"
34
+ "#{ui.color("Path:", :bold)} #{cache_directory}",
35
+ "#{ui.color("Size:", :bold)} #{cache_size}",
36
36
  ].each do |line|
37
37
  ui.puts " #{line}"
38
38
  end
39
39
  end
40
-
41
40
  end
42
-
43
41
  end
44
42
  end
@@ -1,12 +1,10 @@
1
- require 'batali'
1
+ require "batali"
2
2
 
3
3
  module Batali
4
4
  class Command
5
5
 
6
6
  # Create/Update Batali configuration
7
7
  class Configure < Batali::Command
8
-
9
8
  end
10
-
11
9
  end
12
10
  end
@@ -1,4 +1,4 @@
1
- require 'batali'
1
+ require "batali"
2
2
 
3
3
  module Batali
4
4
  class Command
@@ -8,7 +8,7 @@ module Batali
8
8
 
9
9
  # Display information from manifest
10
10
  def execute!
11
- ui.puts ui.color('Batali manifest information:', :bold) + "\n"
11
+ ui.puts ui.color("Batali manifest information:", :bold) + "\n"
12
12
  display(arguments)
13
13
  end
14
14
 
@@ -40,8 +40,6 @@ module Batali
40
40
  end
41
41
  end
42
42
  end
43
-
44
43
  end
45
-
46
44
  end
47
45
  end
@@ -1,5 +1,5 @@
1
- require 'batali'
2
- require 'fileutils'
1
+ require "batali"
2
+ require "fileutils"
3
3
 
4
4
  module Batali
5
5
  class Command
@@ -9,34 +9,34 @@ module Batali
9
9
 
10
10
  # Install cookbooks
11
11
  def execute!
12
- dry_run('Cookbook installation') do
13
- install_path = config.fetch(:path, 'cookbooks')
14
- run_action('Readying installation destination') do
12
+ dry_run("Cookbook installation") do
13
+ install_path = Utility.clean_path(config.fetch(:path, "cookbooks"))
14
+ run_action("Readying installation destination") do
15
15
  FileUtils.rm_rf(install_path)
16
16
  FileUtils.mkdir_p(install_path)
17
17
  nil
18
18
  end
19
- if(manifest.cookbook.nil? || manifest.cookbook.empty?)
20
- ui.error 'No cookbooks defined within manifest! Try resolving first. (`batali resolve`)'
19
+ if manifest.cookbook.nil? || manifest.cookbook.empty?
20
+ ui.error "No cookbooks defined within manifest! Try resolving first. (`batali resolve`)"
21
21
  else
22
- run_action('Installing cookbooks') do
22
+ run_action("Installing cookbooks") do
23
23
  manifest.cookbook.each_slice(100) do |units_slice|
24
24
  units_slice.map do |unit|
25
25
  Thread.new do
26
26
  ui.debug "Starting unit install for: #{unit.name}<#{unit.version}>"
27
- if(unit.source.respond_to?(:cache_path))
27
+ if unit.source.respond_to?(:cache_path)
28
28
  unit.source.cache_path = cache_directory(
29
- Bogo::Utility.snake(unit.source.class.name.split('::').last)
29
+ Bogo::Utility.snake(unit.source.class.name.split("::").last)
30
30
  )
31
31
  end
32
32
  asset_path = unit.source.asset
33
- final_path = File.join(install_path, unit.name)
34
- if(infrastructure?)
33
+ final_path = Utility.join_path(install_path, unit.name)
34
+ if infrastructure?
35
35
  final_path << "-#{unit.version}"
36
36
  end
37
37
  begin
38
38
  FileUtils.cp_r(
39
- File.join(asset_path, '.'),
39
+ Utility.join_path(asset_path, "."),
40
40
  final_path
41
41
  )
42
42
  ui.debug "Completed unit install for: #{unit.name}<#{unit.version}>"
@@ -54,8 +54,6 @@ module Batali
54
54
  end
55
55
  end
56
56
  end
57
-
58
57
  end
59
-
60
58
  end
61
59
  end
@@ -1,4 +1,4 @@
1
- require 'batali'
1
+ require "batali"
2
2
 
3
3
  module Batali
4
4
  class Command
@@ -10,27 +10,27 @@ module Batali
10
10
  # and dump serialized manifest
11
11
  def execute!
12
12
  system = Grimoire::System.new
13
- run_action 'Loading sources' do
13
+ run_action "Loading sources" do
14
14
  UnitLoader.new(
15
15
  :file => batali_file,
16
16
  :system => system,
17
17
  :cache => cache_directory(:git),
18
- :auto_path_restrict => !infrastructure?
18
+ :auto_path_restrict => !infrastructure?,
19
19
  ).populate!
20
20
  nil
21
21
  end
22
22
  requirements = Grimoire::RequirementList.new(
23
23
  :name => :batali_resolv,
24
- :requirements => batali_file.cookbook.map{ |ckbk|
25
- [ckbk.name, (ckbk.constraint.nil? || ckbk.constraint.empty? ? ['> 0'] : ckbk.constraint)]
26
- }
24
+ :requirements => batali_file.cookbook.map { |ckbk|
25
+ [ckbk.name, (ckbk.constraint.nil? || ckbk.constraint.empty? ? ["> 0"] : ckbk.constraint)]
26
+ },
27
27
  )
28
28
  solv = Grimoire::Solver.new(
29
29
  :requirements => requirements,
30
30
  :system => system,
31
- :score_keeper => score_keeper
31
+ :score_keeper => score_keeper,
32
32
  )
33
- if(infrastructure?)
33
+ if infrastructure?
34
34
  infrastructure_resolution(solv)
35
35
  else
36
36
  single_path_resolution(solv)
@@ -41,7 +41,7 @@ module Batali
41
41
  def score_keeper
42
42
  memoize(:score_keeper) do
43
43
  sk_manifest = Manifest.new(:cookbook => manifest.cookbook)
44
- unless(config[:least_impact])
44
+ unless config[:least_impact]
45
45
  sk_manifest.cookbook.clear
46
46
  end
47
47
  sk_manifest.cookbook.delete_if do |unit|
@@ -61,50 +61,50 @@ module Batali
61
61
  [unit.name, unit.version]
62
62
  end
63
63
  ]
64
- ui.info 'Performing single path resolution.'
65
- if(manifest.infrastructure)
66
- ui.confirm 'Current manifest is resolved for infrastucture. Convert to single path?'
64
+ ui.info "Performing single path resolution."
65
+ if manifest.infrastructure
66
+ ui.confirm "Current manifest is resolved for infrastucture. Convert to single path?"
67
67
  end
68
68
  results = []
69
- run_action 'Resolving dependency constraints' do
69
+ run_action "Resolving dependency constraints" do
70
70
  results = solv.generate!
71
71
  nil
72
72
  end
73
- if(results.empty?)
74
- ui.error 'No solutions found defined requirements!'
73
+ if results.empty?
74
+ ui.error "No solutions found defined requirements!"
75
75
  else
76
76
  ideal_solution = results.pop
77
- ui.debug 'Full solution raw contents:'
77
+ ui.debug "Full solution raw contents:"
78
78
  ideal_solution.units.each do |unit|
79
- ui.debug [unit.name, unit.version].join(' -> ')
79
+ ui.debug [unit.name, unit.version].join(" -> ")
80
80
  end
81
- dry_run('manifest file write') do
82
- run_action 'Writing manifest' do
81
+ dry_run("manifest file write") do
82
+ run_action "Writing manifest" do
83
83
  manifest = Manifest.new(
84
84
  :cookbook => ideal_solution.units,
85
- :infrastructure => false
85
+ :infrastructure => false,
86
86
  )
87
- File.open('batali.manifest', 'w') do |file|
87
+ File.open("batali.manifest", "w") do |file|
88
88
  file.write MultiJson.dump(manifest, :pretty => true)
89
89
  end
90
90
  nil
91
91
  end
92
92
  end
93
93
  # ui.info "Number of solutions collected for defined requirements: #{results.size + 1}"
94
- ui.info 'Ideal solution:'
95
- solution_units = Smash[ideal_solution.units.map{|unit| [unit.name, unit]}]
96
- manifest_units = Smash[manifest.cookbook.map{|unit| [unit.name, unit]}]
94
+ ui.info "Ideal solution:"
95
+ solution_units = Smash[ideal_solution.units.map { |unit| [unit.name, unit] }]
96
+ manifest_units = Smash[manifest.cookbook.map { |unit| [unit.name, unit] }]
97
97
  (solution_units.keys + manifest_units.keys).compact.uniq.sort.each do |unit_name|
98
- if(manifest_units[unit_name])
99
- if(solution_units[unit_name])
100
- if(solution_units[unit_name].same?(manifest_units[unit_name]))
98
+ if manifest_units[unit_name]
99
+ if solution_units[unit_name]
100
+ if solution_units[unit_name].same?(manifest_units[unit_name])
101
101
  ui.puts "#{unit_name} <#{solution_units[unit_name].version}>"
102
102
  else
103
103
  u_diff = manifest_units[unit_name].diff(solution_units[unit_name])
104
- version_output = u_diff[:version] ? u_diff[:version].join(' -> ') : solution_units[unit_name].version
104
+ version_output = u_diff[:version] ? u_diff[:version].join(" -> ") : solution_units[unit_name].version
105
105
  u_diff.delete(:version)
106
- unless(u_diff.empty?)
107
- diff_output = "[#{u_diff.values.map{|v| v.join(' -> ')}.join(' | ')}]"
106
+ unless u_diff.empty?
107
+ diff_output = "[#{u_diff.values.map { |v| v.join(" -> ") }.join(" | ")}]"
108
108
  end
109
109
  ui.puts ui.color("#{unit_name} <#{version_output}> #{diff_output}", :yellow)
110
110
  end
@@ -123,27 +123,27 @@ module Batali
123
123
  # @param solv [Grimoire::Solver]
124
124
  # @return [TrueClass]
125
125
  def infrastructure_resolution(solv)
126
- ui.info 'Performing infrastructure path resolution.'
127
- if(manifest.infrastructure == false)
128
- ui.ask 'Current manifest is resolved single path. Convert to infrastructure?'
126
+ ui.info "Performing infrastructure path resolution."
127
+ if manifest.infrastructure == false
128
+ ui.ask "Current manifest is resolved single path. Convert to infrastructure?"
129
129
  end
130
- run_action 'Resolving dependency constraints' do
130
+ run_action "Resolving dependency constraints" do
131
131
  solv.prune_world!
132
132
  nil
133
133
  end
134
- dry_run('manifest file write') do
135
- run_action 'Writing infrastructure manifest file' do
136
- File.open(manifest.path, 'w') do |file|
134
+ dry_run("manifest file write") do
135
+ run_action "Writing infrastructure manifest file" do
136
+ File.open(manifest.path, "w") do |file|
137
137
  manifest = Manifest.new(
138
138
  :cookbook => solv.world.units.values.flatten,
139
- :infrastructure => true
139
+ :infrastructure => true,
140
140
  )
141
141
  file.write MultiJson.dump(manifest, :pretty => true)
142
142
  nil
143
143
  end
144
144
  end
145
145
  end
146
- ui.info 'Infrastructure manifest solution:'
146
+ ui.info "Infrastructure manifest solution:"
147
147
 
148
148
  solution_units = solv.world.units
149
149
  manifest_units = Smash.new.tap do |mu|
@@ -153,41 +153,39 @@ module Batali
153
153
  end
154
154
  end
155
155
  (solution_units.keys + manifest_units.keys).compact.uniq.sort.each do |unit_name|
156
- if(manifest_units[unit_name])
157
- if(solution_units[unit_name])
156
+ if manifest_units[unit_name]
157
+ if solution_units[unit_name]
158
158
  removed = manifest_units[unit_name].find_all do |m_unit|
159
159
  solution_units[unit_name].none? do |s_unit|
160
160
  m_unit.same?(s_unit)
161
161
  end
162
- end.map{|u| [u.version, :red] }
162
+ end.map { |u| [u.version, :red] }
163
163
  added = solution_units[unit_name].find_all do |s_unit|
164
164
  manifest_units[unit_name].none? do |m_unit|
165
165
  s_unit.same?(m_unit)
166
166
  end
167
- end.map{|u| [u.version, :green]}
167
+ end.map { |u| [u.version, :green] }
168
168
  persisted = solution_units[unit_name].find_all do |s_unit|
169
169
  manifest_units[unit_name].any? do |m_unit|
170
170
  s_unit.same?(m_unit)
171
171
  end
172
- end.map{|u| [u.version, nil]}
172
+ end.map { |u| [u.version, nil] }
173
173
  unit_versions = (removed + added + persisted).sort_by(&:first).map do |uv|
174
174
  uv.last ? ui.color(uv.first.to_s, uv.last) : uv.first.to_s
175
175
  end
176
- unless(added.empty? && removed.empty?)
177
- ui.puts "#{ui.color(unit_name, :yellow)} #{ui.color('<', :yellow)}#{unit_versions.join(ui.color(', ', :yellow))}#{ui.color('>', :yellow)}" # rubocop:disable Metrics/LineLength
176
+ unless added.empty? && removed.empty?
177
+ ui.puts "#{ui.color(unit_name, :yellow)} #{ui.color("<", :yellow)}#{unit_versions.join(ui.color(", ", :yellow))}#{ui.color(">", :yellow)}" # rubocop:disable Metrics/LineLength
178
178
  else
179
- ui.puts "#{unit_name} <#{unit_versions.join(', ')}>"
179
+ ui.puts "#{unit_name} <#{unit_versions.join(", ")}>"
180
180
  end
181
181
  else
182
- ui.puts ui.color("#{unit_name} <#{manifest_units[unit_name].map(&:version).sort.map(&:to_s).join(', ')}>", :red) # rubocop:disable Metrics/LineLength
182
+ ui.puts ui.color("#{unit_name} <#{manifest_units[unit_name].map(&:version).sort.map(&:to_s).join(", ")}>", :red) # rubocop:disable Metrics/LineLength
183
183
  end
184
184
  else
185
- ui.puts ui.color("#{unit_name} <#{solution_units[unit_name].map(&:version).sort.map(&:to_s).join(', ')}>", :green) # rubocop:disable Metrics/LineLength
185
+ ui.puts ui.color("#{unit_name} <#{solution_units[unit_name].map(&:version).sort.map(&:to_s).join(", ")}>", :green) # rubocop:disable Metrics/LineLength
186
186
  end
187
187
  end
188
188
  end
189
-
190
189
  end
191
-
192
190
  end
193
191
  end