grimoire 0.1.4 → 0.1.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 40a6acabedf3270488bbf3be2eba64330a819044
4
- data.tar.gz: 0da4eaa00a46d7a6beb0d68452183e7557e55d04
3
+ metadata.gz: 9e488dfe4964214969754e066c275034a4663d67
4
+ data.tar.gz: 015e51d0f9a05e51a00b5f0b41c4de77764c77f6
5
5
  SHA512:
6
- metadata.gz: e39fbd0a25f246552db87ecbc890288ab47107846485257e4e0e6bc8eed821388ac1e82dfa9416fe19a4e9a914c05e9019a7acaf2228f7a19da7274e7bc94817
7
- data.tar.gz: 02d3a49f7df811b8a98a255e3234ae7ec47da17f9033b23d9a47f1e077bc2d9e40c2f4459e901a25c99769a0f90644311eee1d98e862b3608601e495f34d9efe
6
+ metadata.gz: d4756adf5a06f61ed26b4732e7f8848b1a063f47372577578038be52ff8532e31d2c0f8e789612d9131d23aad8c27528fad05753d751b4bef6f821f8670253ce
7
+ data.tar.gz: 387138f63f6e94ee25c359be79359266721441b3f0779452fc20f871f525f1e2df03954a43702cf9473de8c10899c2249aa6ca547a2df7cad887d632dced909e
@@ -1,3 +1,8 @@
1
+ # v0.1.6
2
+ * Add debug output if UI is available for output
3
+ * Update exception errors to provide more detail/context
4
+ * Provide better type checking prior to processing
5
+
1
6
  # v0.1.4
2
7
  * Provide simple system serialization support
3
8
  * Fix dependency listing from units within path
data/README.md CHANGED
@@ -52,7 +52,7 @@ solver = Grimoire::Solver.new(
52
52
 
53
53
  * Generate solutions
54
54
 
55
- ``ruby
55
+ ```ruby
56
56
  solutions = solver.generate!
57
57
  p solutions.pop
58
58
  ```
@@ -20,6 +20,34 @@ module Grimoire
20
20
  autoload :UnitScoreKeeper, 'grimoire/unit_score_keeper'
21
21
  autoload :Utility, 'grimoire/utility'
22
22
 
23
+ class << self
24
+
25
+ # @return [Bogo::Ui]
26
+ attr_reader :ui
27
+
28
+ # Set Ui instance
29
+ #
30
+ # @param ui [Bogo::Ui]
31
+ # @return [Bogo::Ui]
32
+ def ui=(ui)
33
+ unless(ui.respond_to?(:debug))
34
+ raise TypeError.new "Expecting type `Bogo::Ui` but received `#{ui.class}`"
35
+ end
36
+ @ui = ui
37
+ end
38
+
39
+
40
+ # Write debug message
41
+ def debug(*args)
42
+ if(ui)
43
+ if(block_given?)
44
+ args.push(yield)
45
+ end
46
+ ui.debug(*args)
47
+ end
48
+ end
49
+ end
50
+
23
51
  end
24
52
 
25
53
  require 'grimoire/version'
@@ -5,7 +5,7 @@ module Grimoire
5
5
  # Requirment list for solver
6
6
  class RequirementList < Utility
7
7
  attribute :name, String, :required => true, :coerce => lambda{|val| val.to_s}
8
- attribute :requirements, DEPENDENCY_CLASS, :multiple => true, :default => [], :coerce => lambda{|val| DEPENDENCY_CLASS.new(val.first, *val.last)}
8
+ attribute :requirements, DEPENDENCY_CLASS, :multiple => true, :default => [], :coerce => lambda{|val| Grimoire.const_get(:DEPENDENCY_CLASS).new(val.first, *val.last)}
9
9
  end
10
10
 
11
11
  end
@@ -13,6 +13,7 @@ module Grimoire
13
13
  attribute :requirements, RequirementList, :required => true
14
14
  attribute :system, System, :required => true
15
15
  attribute :score_keeper, UnitScoreKeeper
16
+ attribute :result_limit, Integer, :required => true, :default => 1
16
17
 
17
18
  # @return [System] subset of full system based on requirements
18
19
  attr_reader :world
@@ -39,11 +40,16 @@ module Grimoire
39
40
  deps.each do |dep|
40
41
  units = root.subset(dep.name, dep.requirement)
41
42
  sha = Digest::SHA256.hexdigest(MultiJson.dump(units))
42
- next if @log.include?(sha)
43
+ if(@log.include?(sha))
44
+ debug "Units checksum already added to world. Skipping. (`#{sha}`)"
45
+ next
46
+ end
47
+ debug "Logging units checksum for world addition. (`#{sha}`)"
43
48
  @log.push(sha)
44
49
  units.each do |unit|
45
50
  build_world(unit.dependencies, my_world, root)
46
51
  end
52
+ debug "Units added to world: #{MultiJson.dump(units.map{|u| {u.name => u.version} })}"
47
53
  my_world.add_unit(units)
48
54
  end
49
55
  end
@@ -108,6 +114,9 @@ module Grimoire
108
114
  # @raises [Error::UnitUnavailable]
109
115
  def unit_for(dep)
110
116
  unit = nil
117
+ if(queues[dep.name].nil?)
118
+ raise KeyError.new "No valid units for requested name found within system! (`#{dep.name}`)"
119
+ end
111
120
  until(unit || queues[dep.name].empty?)
112
121
  unit = queues[dep.name].pop
113
122
  unit = nil unless dep.requirement.satisfied_by?(unit.version)
@@ -158,7 +167,8 @@ module Grimoire
158
167
  end
159
168
  end
160
169
  end
161
- rescue Error::ResolutionPathInvalid
170
+ rescue Error::ResolutionPathInvalid => e
171
+ debug "Resolution path deadend: #{e} (trying new path)"
162
172
  retry
163
173
  end
164
174
  deps.uniq
@@ -169,30 +179,32 @@ module Grimoire
169
179
  #
170
180
  # @return [Bogo::PriorityQueue<Path>]
171
181
  def generate!
182
+ if(requirements.requirements.empty?)
183
+ raise ArgumentError.new 'No cookbook constraints provided within Batali file!'
184
+ end
172
185
  custom_unit = Unit.new(
173
186
  :name => '~_SOLVER_UNIT_~',
174
187
  :version => '1.0.0',
175
188
  :dependencies => requirements.requirements
176
189
  )
177
190
  count = 0
191
+ debug "Solver Unit: #{MultiJson.dump(custom_unit)}"
192
+ debug{ "Solver world context of unit system: #{world.inspect}" }
178
193
  results = Bogo::PriorityQueue.new
179
194
  begin
180
- until(count > MAX_GENERATION_LOOPS)
195
+ until(count >= result_limit)
181
196
  result = resolve(nil, custom_unit)
182
197
  results.push(Path.new(:units => result.slice(1, result.size)), count)
183
198
  count += 1
184
199
  end
185
- rescue Error::UnitUnavailable
200
+ rescue Error::UnitUnavailable => e
201
+ debug "Failed to unit: #{e}"
186
202
  count = nil
187
203
  end
188
- unless(count.nil?)
189
- raise Error::MaximumGenerationLoopsExceeded.new("Exceeded maximum allowed loops for path generation: #{MAX_GENERATION_LOOPS}")
204
+ if(results.empty?)
205
+ raise Error::NoSolution.new("Failed to generate valid path for requirements: `#{custom_unit.dependencies}`")
190
206
  else
191
- if(results.empty?)
192
- raise Error::NoSolution.new("Failed to generate valid path for requirements: `#{custom_unit.dependencies.inspect}`")
193
- else
194
- results
195
- end
207
+ results
196
208
  end
197
209
  end
198
210
 
@@ -58,6 +58,9 @@ module Grimoire
58
58
  unless(constraint.respond_to?(:requirements))
59
59
  raise TypeError.new "Expecting `#{REQUIREMENT_CLASS}` but received `#{constraint.class}`"
60
60
  end
61
+ unless(units[unit_name])
62
+ raise KeyError.new("Failed to locate any units loaded in system with requested name: `#{unit_name}`")
63
+ end
61
64
  units[unit_name].find_all do |unit|
62
65
  constraint.satisfied_by?(unit.version)
63
66
  end
@@ -83,5 +86,13 @@ module Grimoire
83
86
  )
84
87
  end
85
88
 
89
+ # @return [String]
90
+ def inspect
91
+ "<#{self.class}:#{self.object_id}>: " <<
92
+ units.to_a.sort_by(&:first).map do |name, units|
93
+ "#{name}: #{units.map(&:version).sort.map(&:to_s).join(', ')}"
94
+ end.join("\n")
95
+ end
96
+
86
97
  end
87
98
  end
@@ -6,8 +6,8 @@ module Grimoire
6
6
  class Unit < Utility
7
7
 
8
8
  attribute :name, String, :required => true
9
- attribute :dependencies, DEPENDENCY_CLASS, :multiple => true, :default => [], :coerce => lambda{|val| DEPENDENCY_CLASS.new(val.first, *val.last)}
10
- attribute :version, VERSION_CLASS, :required => true, :coerce => lambda{|val| VERSION_CLASS.new(val)}
9
+ attribute :dependencies, DEPENDENCY_CLASS, :multiple => true, :default => [], :coerce => lambda{|val| Grimoire.const_get(:DEPENDENCY_CLASS).new(val.first, *val.last)}
10
+ attribute :version, VERSION_CLASS, :required => true, :coerce => lambda{|val| Grimoire.const_get(:VERSION_CLASS).new(val)}
11
11
 
12
12
  end
13
13
 
@@ -20,6 +20,12 @@ module Grimoire
20
20
  def to_json(*args)
21
21
  MultiJson.dump(data, *args)
22
22
  end
23
+
24
+ # Write debug message
25
+ def debug(*args, &block)
26
+ Grimoire.debug(*args, &block)
27
+ end
28
+
23
29
  end
24
30
 
25
31
  end
@@ -1,4 +1,4 @@
1
1
  module Grimoire
2
2
  # Current library version
3
- VERSION = Gem::Version.new('0.1.4')
3
+ VERSION = Gem::Version.new('0.1.6')
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grimoire
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Roberts
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-10 00:00:00.000000000 Z
11
+ date: 2015-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bogo