versus 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.index CHANGED
@@ -2,13 +2,15 @@
2
2
  type: ruby
3
3
  revision: 2013
4
4
  sources:
5
- - Index.yml
5
+ - var
6
6
  authors:
7
7
  - name: trans
8
8
  email: transfire@gmail.com
9
9
  - name: postmodern
10
10
  website: http://trans.github.com
11
- organizations: []
11
+ organizations:
12
+ - name: Rubyworks
13
+ website: http://rubyworks.github.com/
12
14
  requirements:
13
15
  - groups:
14
16
  - test
@@ -18,14 +20,18 @@ requirements:
18
20
  - test
19
21
  development: true
20
22
  name: ae
23
+ - groups:
24
+ - test
25
+ development: true
26
+ name: spectroscope
21
27
  conflicts: []
22
28
  alternatives: []
23
29
  resources:
24
- - type: homepage
25
- uri: http://dotruby.github.com
30
+ - type: home
31
+ uri: http://rubyworks.github.com/versus
26
32
  label: Homepage
27
- - type: source
28
- uri: http://github.com/dotruby/version
33
+ - type: code
34
+ uri: http://github.com/rubyworks/versus
29
35
  label: Source Code
30
36
  repositories: []
31
37
  categories: []
@@ -36,10 +42,14 @@ copyrights:
36
42
  - holder: Rubyworks
37
43
  year: 2011
38
44
  license: BSD-2-Clause
39
- name: versus
40
- title: Versus
41
- version: 0.1.0
45
+ created: '2006-12-10'
42
46
  summary: Best-of-breed Version Class Library
43
- description: The Versus gem provides a solid Version class along with supporting functionality,
44
- such as version constratints and version dependency resolution.
45
- date: '2013-01-05'
47
+ title: Versus
48
+ version: 0.2.0
49
+ name: versus
50
+ description: ! 'The Versus gem provides a solid Version class along with supporting
51
+
52
+ functionality, such as version constratints and version dependency
53
+
54
+ resolution.'
55
+ date: '2013-01-07'
data/HISTORY.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # RELEASE HISTORY
2
2
 
3
+ ## 0.2.0 / 2013-01-07
4
+
5
+ This release fixes a bug in the Resolver that can lead to inifinite recursion
6
+ if one entry requires another that in turn requires the former. Also, resolution
7
+ failures are now tracked so that a nice list of the culprits can be had, helpful
8
+ for trouble-shooting unsuccessful resolutions.
9
+
10
+ Changes:
11
+
12
+ * Prevent possible infinite recustion in Resolver#resolve.
13
+ * Keep record of resolution failures.
14
+
15
+
3
16
  ## 0.1.0 / 2013-01-05
4
17
 
5
18
  While the code is beening sitting around on my hard drive for nearly
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  [Homepage](http://rubyworks.github.com/versus) /
2
2
  [Report Issue](http://github.com/rubyworks/versus) /
3
3
  [Source Code](http://github.com/rubyworks/versus)
4
- ( )
4
+ ( [![Build Status](https://travis-ci.org/rubyworks/versus.png)](https://travis-ci.org/rubyworks/versus) )
5
5
 
6
6
 
7
7
  # [Versus](http://rubyworks.github.com/versus)
@@ -287,7 +287,11 @@ module Version
287
287
  # FIXME: Ensure it can handle trailing state.
288
288
  def =~(other)
289
289
  upver = other.bump(:last)
290
- #@segments >= other and @segments < upver
290
+ if other.size > 1
291
+ upver = other.bump(-2)
292
+ else
293
+
294
+ end
291
295
  self >= other and self < upver
292
296
  end
293
297
 
@@ -333,7 +337,11 @@ module Version
333
337
  # #=> "1.3.0.rc.1"
334
338
  #
335
339
  def bump(which=:patch)
336
- case which.to_sym
340
+ which = which.to_sym unless Integer === which
341
+
342
+ case which
343
+ when Integer
344
+ bump_at(which)
337
345
  when :major, :first
338
346
  bump_major
339
347
  when :minor
@@ -349,6 +357,7 @@ module Version
349
357
  when :last
350
358
  bump_last
351
359
  else
360
+ # TODO: why is this not an error?
352
361
  self.class.new(@tuple.dup.compact)
353
362
  end
354
363
  end
@@ -368,6 +377,16 @@ module Version
368
377
  self.class[major, minor, inc(patch)]
369
378
  end
370
379
 
380
+ #
381
+ def bump_at(index)
382
+ i = index
383
+ if n = inc(@tuple[i])
384
+ v = @tuple[0...i] + [n] + (@tuple[i+1] ? [1] : [])
385
+ else
386
+ v = @tuple[0...i]
387
+ end
388
+ end
389
+
371
390
  #
372
391
  def bump_state
373
392
  if i = state_index
@@ -6,7 +6,10 @@ module Version
6
6
  class Resolver
7
7
 
8
8
  #
9
+ # Initialize new Resolver.
9
10
  #
11
+ # @param [Array] available
12
+ # List of name, version and requirements for each possible library.
10
13
  #
11
14
  def initialize(*available)
12
15
  @libraries = Hash.new{ |h,k| h[k] = {} }
@@ -21,9 +24,24 @@ module Version
21
24
  #
22
25
  attr :libraries
23
26
 
27
+ #
28
+ # List of library names and versions of failed resolutions
29
+ # subsequent to calling `#resolve`.
30
+ #
31
+ #attr :failures
32
+
24
33
  #
25
34
  # Add available library.
26
35
  #
36
+ # @param [String] name
37
+ # The name of the library.
38
+ #
39
+ # @param [String,Version::Number] version
40
+ # Version number of library.
41
+ #
42
+ # @param [Hash] requirements
43
+ # Requirements for the library in the form of `{name=>version_constraint}`.
44
+ #
27
45
  def add(name, version, requirements={})
28
46
  name = name.to_s
29
47
  number = Number.parse(version)
@@ -68,6 +86,9 @@ module Version
68
86
  name = name.to_s
69
87
  number = Number.parse(number)
70
88
 
89
+ @cache = {}
90
+ @failures = []
91
+
71
92
  sheet = {}
72
93
 
73
94
  result = resolve_(name, number, sheet)
@@ -81,18 +102,47 @@ module Version
81
102
  result ? sheet : nil
82
103
  end
83
104
 
105
+ #
106
+ # Returns a mapping of unresolvable requirements. The key of the Hash is the
107
+ # library that has the requirements and the value of the Hash is an Array
108
+ # of the requirements that could be not be found in the library list.
109
+ #
110
+ # @return [Hash] Unresolved requirements
111
+ #
112
+ def unresolved
113
+ list = Hash.new{ |h,k| h[k] = [] }
114
+ @failures.each do |name, number|
115
+ requirements(name, number).each do |rname, rnumber|
116
+ list[[name,number]] << [rname, rnumber] if possibilities(rname, rnumber.to_s).empty?
117
+ end
118
+ end
119
+ list
120
+ end
121
+
84
122
  private
85
123
 
86
124
  #
87
125
  #
88
126
  #
89
127
  def resolve_(name, number, sheet={})
128
+ # prevent infinite recursion
129
+ return sheet if @cache[[name,number]]
130
+ @cache[[name,number]] = true
131
+
90
132
  return false unless settle(name, number, sheet)
91
133
 
92
- potents = requirements(name, number).map do |(n, c)|
134
+ requirements = requirements(name, number)
135
+
136
+ # there are no requirements to resolve
137
+ return sheet if requirements.empty?
138
+
139
+ # what possibilites exist for resolving all the requirements
140
+ potents = requirements.map do |(n, c)|
93
141
  possibilities(n,c)
94
142
  end
95
143
 
144
+ # TODO: I think this might be a mistake, if there are no possibilities then is it not
145
+ # a failed resolution? Consider adding to failures and returning false instead.
96
146
  return sheet if potents.empty?
97
147
 
98
148
  vectors = product(*potents)
@@ -101,9 +151,21 @@ module Version
101
151
  resolve_vector(vector, sheet)
102
152
  end
103
153
 
154
+ unless success
155
+ @failures << [name, number] unless @failures.include?([name, number])
156
+ end
157
+
104
158
  return success
105
159
  end
106
160
 
161
+ #
162
+ #
163
+ #
164
+ def cached(name, number, sheet)
165
+ @cache[[name, number]] = true
166
+ sheet
167
+ end
168
+
107
169
  #
108
170
  #
109
171
  #
@@ -285,7 +347,7 @@ module Version
285
347
  else
286
348
  most = c
287
349
  end
288
- when '=~'
350
+ when '=~', '~>'
289
351
  # TODO
290
352
  end
291
353
  end
@@ -0,0 +1,5 @@
1
+ require 'spectroscope'
2
+ require 'ae'
3
+
4
+ require 'versus'
5
+
@@ -0,0 +1,63 @@
1
+ require_relative '../helper'
2
+
3
+ describe Version::Resolver do
4
+
5
+ it "resolves greater than constraints" do
6
+ resolver = Version::Resolver.new
7
+ resolver.add('foo', '1.0.0', 'bar'=>'> 0.8')
8
+ resolver.add('bar', '0.1.0')
9
+ resolver.add('bar', '0.8.0')
10
+ resolver.add('bar', '1.0.0')
11
+ result = resolver.resolve('foo', '1.0.0')
12
+ result.assert == {'foo'=>Version['1.0.0'], 'bar'=>Version['1.0.0']}
13
+ end
14
+
15
+ it "resolves greater than or equal constraints" do
16
+ resolver = Version::Resolver.new
17
+ resolver.add('foo', '1.0.0', 'bar'=>'>= 0.8')
18
+ resolver.add('bar', '0.1.0')
19
+ resolver.add('bar', '0.8.0')
20
+ resolver.add('bar', '1.0.0')
21
+ result = resolver.resolve('foo', '1.0.0')
22
+ result.assert == {'foo'=>Version['1.0.0'], 'bar'=>Version['1.0.0']}
23
+
24
+ resolver = Version::Resolver.new
25
+ resolver.add('foo', '1.0.0', 'bar'=>'>= 0.8')
26
+ resolver.add('bar', '0.1.0')
27
+ resolver.add('bar', '0.8.0')
28
+ result = resolver.resolve('foo', '1.0.0')
29
+ result.assert == {'foo'=>Version['1.0.0'], 'bar'=>Version['0.8.0']}
30
+ end
31
+
32
+ it "resolves lesser than constraints" do
33
+ resolver = Version::Resolver.new
34
+ resolver.add('foo', '1.0.0', 'bar'=>'< 1.0.0')
35
+ resolver.add('bar', '0.1.0')
36
+ resolver.add('bar', '0.8.0')
37
+ resolver.add('bar', '1.0.0')
38
+ result = resolver.resolve('foo', '1.0.0')
39
+ result.assert == {'foo'=>Version['1.0.0'], 'bar'=>Version['0.8.0']}
40
+ end
41
+
42
+ it "resolves lesser than or equal constraints" do
43
+ resolver = Version::Resolver.new
44
+ resolver.add('foo', '1.0.0', 'bar'=>'<= 1.0.0')
45
+ resolver.add('bar', '0.1.0')
46
+ resolver.add('bar', '0.8.0')
47
+ resolver.add('bar', '1.0.0')
48
+ result = resolver.resolve('foo', '1.0.0')
49
+ result.assert == {'foo'=>Version['1.0.0'], 'bar'=>Version['1.0.0']}
50
+ end
51
+
52
+ it "resolves semantically equal constraints" do
53
+ resolver = Version::Resolver.new
54
+ resolver.add('foo', '1.0.0', 'bar'=>'~> 1.0.0')
55
+ resolver.add('bar', '1.0.1')
56
+ resolver.add('bar', '1.1.0')
57
+ resolver.add('bar', '2.0.0')
58
+ result = resolver.resolve('foo', '1.0.0')
59
+ result.assert == {'foo'=>Version['1.0.0'], 'bar'=>Version['1.1.0']}
60
+ end
61
+
62
+ end
63
+
@@ -0,0 +1,49 @@
1
+ require_relative '../helper'
2
+
3
+ describe Version::Resolver do
4
+
5
+ it "resolves complex requirements - example 1" do
6
+ resolver = Version::Resolver.new
7
+ resolver.add('foo', '1.0.0', 'bar'=>'> 1.0.0', 'baz'=>'> 2.0.0')
8
+ resolver.add('bar', '1.0.0', 'baz'=>'= 3.1.0')
9
+ resolver.add('bar', '2.0.0', 'baz'=>'= 3.1.0')
10
+ resolver.add('baz', '2.9.0')
11
+ resolver.add('baz', '3.1.0')
12
+ resolver.add('baz', '3.2.0')
13
+ result = resolver.resolve('foo', '1.0.0')
14
+ result.assert == { 'foo'=>Version['1.0.0'], 'bar'=>Version['2.0.0'], 'baz'=>Version['3.1.0'] }
15
+ end
16
+
17
+ it "resolves complex requirements - example 2" do
18
+ resolver = Version::Resolver.new
19
+ resolver.add('foo', '1.0.0', 'bar'=>'> 1.0', 'baz'=>'> 2.0')
20
+ resolver.add('bar', '1.0.0', 'baz'=>'= 3.1')
21
+ resolver.add('bar', '2.0.0', 'baz'=>'= 3.1')
22
+ resolver.add('baz', '2.9.0')
23
+ resolver.add('baz', '3.1.0')
24
+ resolver.add('baz', '3.2.0')
25
+ result = resolver.resolve('foo', '1.0.0')
26
+ result.assert == { 'foo'=>Version['1.0.0'], 'bar'=>Version['2.0.0'], 'baz'=>Version['3.1.0'] }
27
+ end
28
+
29
+ it "resolves complex requirements - example 3" do
30
+ resolver = Version::Resolver.new
31
+ resolver.add('foo', '1.0.0', 'bar'=>'> 1.0.0', 'baz'=>'> 2.0.0')
32
+ resolver.add('bar', '1.0.0', 'baz'=>'= 3.1.0')
33
+ resolver.add('bar', '2.0.0', 'baz'=>'> 3.1.0')
34
+ resolver.add('baz', '3.1.0')
35
+ resolver.add('baz', '3.2.0')
36
+ result = resolver.resolve('foo', '1.0.0')
37
+ result.assert == { 'foo'=>Version['1.0.0'], 'bar'=>Version['2.0.0'], 'baz'=>Version['3.2.0'] }
38
+ end
39
+
40
+ it "does not infinitely recurse" do
41
+ resolver = Version::Resolver.new
42
+ resolver.add('foo', '1.0.0', 'bar'=>'>= 1.0.0')
43
+ resolver.add('bar', '1.0.0', 'foo'=>'>= 1.0.0')
44
+ result = resolver.resolve('foo', '1.0.0')
45
+ result.assert == {'foo'=>Version['1.0.0'], 'bar'=>Version['1.0.0']}
46
+ end
47
+
48
+ end
49
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: versus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-01-05 00:00:00.000000000 Z
13
+ date: 2013-01-08 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: qed
@@ -44,8 +44,27 @@ dependencies:
44
44
  - - ! '>='
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0'
47
- description: The Versus gem provides a solid Version class along with supporting functionality,
48
- such as version constratints and version dependency resolution.
47
+ - !ruby/object:Gem::Dependency
48
+ name: spectroscope
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ description: ! 'The Versus gem provides a solid Version class along with supporting
64
+
65
+ functionality, such as version constratints and version dependency
66
+
67
+ resolution.'
49
68
  email:
50
69
  - transfire@gmail.com
51
70
  executables: []
@@ -92,11 +111,13 @@ files:
92
111
  - lib/versus/resolver.rb
93
112
  - lib/versus/core_ext.rb
94
113
  - lib/versus/number.rb
114
+ - spec/helper.rb
115
+ - spec/resolver/spec_scenarios.rb
116
+ - spec/resolver/spec_contraints.rb
95
117
  - LICENSE.txt
96
- - Index.yml
97
118
  - HISTORY.md
98
119
  - README.md
99
- homepage: http://dotruby.github.com
120
+ homepage: http://rubyworks.github.com/versus
100
121
  licenses:
101
122
  - BSD-2-Clause
102
123
  post_install_message:
@@ -121,4 +142,7 @@ rubygems_version: 1.8.23
121
142
  signing_key:
122
143
  specification_version: 3
123
144
  summary: Best-of-breed Version Class Library
124
- test_files: []
145
+ test_files:
146
+ - spec/helper.rb
147
+ - spec/resolver/spec_scenarios.rb
148
+ - spec/resolver/spec_contraints.rb
data/Index.yml DELETED
@@ -1,37 +0,0 @@
1
- ---
2
- name:
3
- versus
4
-
5
- version:
6
- 0.1.0
7
-
8
- title:
9
- Versus
10
-
11
- summary:
12
- Best-of-breed Version Class Library
13
-
14
- description:
15
- The Versus gem provides a solid Version class along with supporting
16
- functionality, such as version constratints and version dependency
17
- resolution.
18
-
19
- requirements:
20
- - qed (test)
21
- - ae (test)
22
-
23
- authors:
24
- - name: trans
25
- email: transfire@gmail.com
26
- - name: postmodern
27
- website: 'http://trans.github.com'
28
-
29
- resources:
30
- homepage: http://dotruby.github.com
31
- source: http://github.com/dotruby/version
32
-
33
- copyrights:
34
- - year: 2011
35
- holder: Rubyworks
36
- license: BSD-2-Clause
37
-