grimoire 0.1.2 → 0.1.4
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 +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +59 -0
- data/grimoire.gemspec +1 -0
- data/lib/grimoire/path.rb +2 -1
- data/lib/grimoire/solver.rb +11 -4
- data/lib/grimoire/system.rb +20 -0
- data/lib/grimoire/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 40a6acabedf3270488bbf3be2eba64330a819044
|
4
|
+
data.tar.gz: 0da4eaa00a46d7a6beb0d68452183e7557e55d04
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e39fbd0a25f246552db87ecbc890288ab47107846485257e4e0e6bc8eed821388ac1e82dfa9416fe19a4e9a914c05e9019a7acaf2228f7a19da7274e7bc94817
|
7
|
+
data.tar.gz: 02d3a49f7df811b8a98a255e3234ae7ec47da17f9033b23d9a47f1e077bc2d9e40c2f4459e901a25c99769a0f90644311eee1d98e862b3608601e495f34d9efe
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# v0.1.4
|
2
|
+
* Provide simple system serialization support
|
3
|
+
* Fix dependency listing from units within path
|
4
|
+
* Allow checking existing path for constraint satisfaction
|
5
|
+
|
1
6
|
# v0.1.2
|
2
7
|
* Add JSON serialization support to utility instances
|
3
8
|
* Add abstract for unit scoring
|
data/README.md
CHANGED
@@ -1,5 +1,64 @@
|
|
1
1
|
# Grimoire
|
2
2
|
|
3
|
+
Light weight generic dependency resolver. Supports weighted
|
4
|
+
solutions via scored units.
|
5
|
+
|
6
|
+
## Usage
|
7
|
+
|
8
|
+
Basic usage flow:
|
9
|
+
|
10
|
+
* Create a system
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
system = Grimoire::System.new
|
14
|
+
```
|
15
|
+
|
16
|
+
* Add units
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
system.add_units(
|
20
|
+
Grimoire::Unit.new(
|
21
|
+
:name => 'unit1',
|
22
|
+
:version => '1.0.0'
|
23
|
+
),
|
24
|
+
Grimoire::Unit.new(
|
25
|
+
:name => 'unit1',
|
26
|
+
:version => '1.1.0'
|
27
|
+
),
|
28
|
+
...
|
29
|
+
)
|
30
|
+
```
|
31
|
+
|
32
|
+
* Create a score keeper
|
33
|
+
|
34
|
+
_NOTE: Score keeper is optional and *must* be subclassed. This example will not actually work._
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
score_keeper = Grimoire::ScoreKeeper.new
|
38
|
+
```
|
39
|
+
|
40
|
+
* Create solver
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
solver = Grimoire::Solver.new(
|
44
|
+
:system => system,
|
45
|
+
:score_keeper => score_keeper,
|
46
|
+
:requirements => [
|
47
|
+
['unit1', '> 2.0.0'],
|
48
|
+
['unit2', '> 1', '< 3']
|
49
|
+
]
|
50
|
+
)
|
51
|
+
```
|
52
|
+
|
53
|
+
* Generate solutions
|
54
|
+
|
55
|
+
``ruby
|
56
|
+
solutions = solver.generate!
|
57
|
+
p solutions.pop
|
58
|
+
```
|
59
|
+
|
60
|
+
The ideal solution will be the first path on the queue.
|
61
|
+
|
3
62
|
## Info
|
4
63
|
|
5
64
|
* Repository: https://github.com/spox/grimoire
|
data/grimoire.gemspec
CHANGED
@@ -11,6 +11,7 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.require_path = 'lib'
|
12
12
|
s.license = 'Apache 2.0'
|
13
13
|
s.add_runtime_dependency 'bogo', '~> 0.1.10'
|
14
|
+
s.add_runtime_dependency 'attribute_struct', '>= 0.1.12'
|
14
15
|
s.add_development_dependency 'minitest'
|
15
16
|
s.add_development_dependency 'pry'
|
16
17
|
s.files = Dir['{lib}/**/**/*'] + %w(grimoire.gemspec README.md CHANGELOG.md CONTRIBUTING.md LICENSE)
|
data/lib/grimoire/path.rb
CHANGED
data/lib/grimoire/solver.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'digest/sha2'
|
1
2
|
require 'grimoire'
|
2
3
|
|
3
4
|
module Grimoire
|
@@ -19,7 +20,9 @@ module Grimoire
|
|
19
20
|
def initialize(*_)
|
20
21
|
super
|
21
22
|
@world = System.new
|
23
|
+
@log = []
|
22
24
|
build_world(requirements.requirements, world, system)
|
25
|
+
@log.clear
|
23
26
|
world.scrub!
|
24
27
|
end
|
25
28
|
|
@@ -35,6 +38,9 @@ module Grimoire
|
|
35
38
|
root = system unless root
|
36
39
|
deps.each do |dep|
|
37
40
|
units = root.subset(dep.name, dep.requirement)
|
41
|
+
sha = Digest::SHA256.hexdigest(MultiJson.dump(units))
|
42
|
+
next if @log.include?(sha)
|
43
|
+
@log.push(sha)
|
38
44
|
units.each do |unit|
|
39
45
|
build_world(unit.dependencies, my_world, root)
|
40
46
|
end
|
@@ -118,8 +124,9 @@ module Grimoire
|
|
118
124
|
#
|
119
125
|
# @param dep [DEPENDENCY_CLASS]
|
120
126
|
# @param given [DEPENDENCY_CLASS]
|
127
|
+
# @param current [Array<Unit>] current units within path
|
121
128
|
# @return [Array<Unit>]
|
122
|
-
def resolve(dep, given=nil)
|
129
|
+
def resolve(dep, given=nil, current=[])
|
123
130
|
unit = given || unit_for(dep)
|
124
131
|
if(unit.dependencies.empty?)
|
125
132
|
[unit]
|
@@ -127,7 +134,7 @@ module Grimoire
|
|
127
134
|
deps = [unit]
|
128
135
|
begin
|
129
136
|
unit.dependencies.map do |u_dep|
|
130
|
-
existing = deps.detect{|d| d.name == u_dep.name}
|
137
|
+
existing = (current + deps).detect{|d| d.name == u_dep.name}
|
131
138
|
if(existing)
|
132
139
|
if(u_dep.requirement.satisfied_by?(existing.version))
|
133
140
|
next
|
@@ -138,7 +145,7 @@ module Grimoire
|
|
138
145
|
else
|
139
146
|
reset_queue(u_dep.name) unless given
|
140
147
|
end
|
141
|
-
deps += resolve(u_dep)
|
148
|
+
deps += resolve(u_dep, nil, current + deps)
|
142
149
|
deps.compact!
|
143
150
|
u_dep
|
144
151
|
end.compact.map do |u_dep| # validator
|
@@ -154,7 +161,7 @@ module Grimoire
|
|
154
161
|
rescue Error::ResolutionPathInvalid
|
155
162
|
retry
|
156
163
|
end
|
157
|
-
deps
|
164
|
+
deps.uniq
|
158
165
|
end
|
159
166
|
end
|
160
167
|
|
data/lib/grimoire/system.rb
CHANGED
@@ -19,6 +19,9 @@ module Grimoire
|
|
19
19
|
# @param unit [Unit]
|
20
20
|
# @return [self]
|
21
21
|
def add_unit(*unit)
|
22
|
+
if(bad_u = unit.flatten.detect{|u| !u.is_a?(Unit)})
|
23
|
+
raise TypeError.new "Expecting `Unit` instance but received `#{bad_u.class}`"
|
24
|
+
end
|
22
25
|
[unit].flatten.compact.each do |u|
|
23
26
|
unless(units[u.name])
|
24
27
|
units[u.name] = []
|
@@ -34,8 +37,14 @@ module Grimoire
|
|
34
37
|
# @param deps
|
35
38
|
# @return [self]
|
36
39
|
def remove_unit(unit)
|
40
|
+
unless(unit.is_a?(Unit))
|
41
|
+
raise TypeError.new "Expecting `Unit` instance but received `#{unit.class}`"
|
42
|
+
end
|
37
43
|
if(units[unit.name])
|
38
44
|
units[unit.name].delete(unit)
|
45
|
+
if(units[unit.name].empty?)
|
46
|
+
units.delete(unit.name)
|
47
|
+
end
|
39
48
|
end
|
40
49
|
self
|
41
50
|
end
|
@@ -46,6 +55,9 @@ module Grimoire
|
|
46
55
|
# @param constraint [REQUIREMENT_CLASS]
|
47
56
|
# @return [Array<Unit>]
|
48
57
|
def subset(unit_name, constraint)
|
58
|
+
unless(constraint.respond_to?(:requirements))
|
59
|
+
raise TypeError.new "Expecting `#{REQUIREMENT_CLASS}` but received `#{constraint.class}`"
|
60
|
+
end
|
49
61
|
units[unit_name].find_all do |unit|
|
50
62
|
constraint.satisfied_by?(unit.version)
|
51
63
|
end
|
@@ -63,5 +75,13 @@ module Grimoire
|
|
63
75
|
self
|
64
76
|
end
|
65
77
|
|
78
|
+
# @return [String]
|
79
|
+
def to_json(*args)
|
80
|
+
MultiJson.dump(
|
81
|
+
Smash.new(:units => units),
|
82
|
+
*args
|
83
|
+
)
|
84
|
+
end
|
85
|
+
|
66
86
|
end
|
67
87
|
end
|
data/lib/grimoire/version.rb
CHANGED
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
|
+
version: 0.1.4
|
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-
|
11
|
+
date: 2015-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bogo
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.1.10
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: attribute_struct
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.1.12
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.1.12
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: minitest
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|