fuzzy_version_matcher 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 25c18bf74ddb8c974e826ce0e79a47c77693a0a1
4
+ data.tar.gz: e9046810f88056ec2967824921c8ad42e738b8c9
5
+ SHA512:
6
+ metadata.gz: 02f1f01c3bdfc528623b22d8b3ace4f9d3be3c1f81e4c90eb823f76d6aee49449269e1b452013f8ecfa25bb6c6559784e708b41ae776c85921c5efa10ffd8fbd
7
+ data.tar.gz: a4eccbb5bbb5de46b75580acffee07ad1e8f97ff3e0bd8463312d3365e2cb450917d1956411f8df9b152f2896227fd70295b43832bd39a03a0a55cf98d92b984
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fuzzy_version_matcher.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Will Jessop
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # FuzzyVersionMatcher
2
+
3
+ The Fuzzy Version Matcher gem takes a list of candidate version numbers (strings in the form of numbers/letters separated by non-numbers/letters) eg:
4
+
5
+ 5.1.45-10-percona
6
+ 5.1.45-10.2-percona
7
+ 5.1.66-14.2-percona
8
+ 5.1.67-14.3-percona
9
+ 5.5.23-25.3-percona
10
+ 5.5.27-29.0-percona
11
+ 5.5.28-29.2-percona
12
+ 5.5.29-29.4-percona
13
+
14
+ and a subject version number, eg:
15
+
16
+ 5.1.45-10.3-maria
17
+
18
+ The gem will provide the "best match" version from the candidate list according to some simple rules:
19
+
20
+ * An exact match returns the same version string, eg:
21
+
22
+ 5.1.45-10-percona => 5.1.45-10-percona
23
+
24
+ * A partial match returns the highest version available from the partial match, eg:
25
+
26
+ 5.5 => 5.5.29-29.4-percona
27
+
28
+ * An inexact match matches as many of the most significant version segments as possible before matching the remaining version segments at the highest level, eg:
29
+
30
+ 5.1.66-15.5-percona => 5.1.66-14.2-percona
31
+
32
+ ## Installation
33
+
34
+ Add this line to your application's Gemfile:
35
+
36
+ gem 'fuzzy_version_matcher'
37
+
38
+ And then execute:
39
+
40
+ $ bundle
41
+
42
+ Or install it yourself as:
43
+
44
+ $ gem install fuzzy_version_matcher
45
+
46
+ I've tested the gem on 2.0.0, it probably works on 1.9.3. 1.8.7 YMMV.
47
+
48
+ ## Usage
49
+
50
+ ```ruby
51
+ n = Node.new
52
+
53
+ DATA.readlines.each do |ln|
54
+ # add all available versions
55
+ n.add_node(ln.chomp)
56
+ end
57
+
58
+ puts n.search("5.5.27-29.0-percona") # 5.5.27-29.0-percona
59
+ puts n.search("5.1.45-10-percona") # 5.1.45-10-percona
60
+ puts n.search("5.1.45-10.2-percona") # 5.1.45-10.2-percona
61
+ puts n.search("5.1.45-10.2-maria") # 5.1.45-10.2-percona
62
+ puts n.search("5.1.45-10.400-percona") # 5.1.45-10.2-percona
63
+ puts n.search("5.5") # 5.5.29-30.0-percona
64
+
65
+ __END__
66
+ 5.1.45-10-percona
67
+ 5.1.45-10.2-percona
68
+ 5.1.66-14.2-percona
69
+ 5.1.67-14.3-percona
70
+ 5.5.23-25.3-percona
71
+ 5.5.27-29.0-percona
72
+ 5.5.28-29.2-percona
73
+ 5.5.29-29.4-percona
74
+ 5.5.29-30.0-percona
75
+ ```
76
+
77
+ ## Contributing
78
+
79
+ 1. Fork it
80
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
81
+ 3. Make sure the tests run
82
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
83
+ 5. Push to the branch (`git push origin my-new-feature`)
84
+ 6. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ end
7
+
8
+ task :default => :test
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'fuzzy_version_matcher/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "fuzzy_version_matcher"
8
+ spec.version = FuzzyVersionMatcher::VERSION
9
+ spec.authors = ["Will Jessop"]
10
+ spec.email = ["will@willj.net"]
11
+ spec.description = %q{Does a 'best match' of a version against a list of candiate version numbers}
12
+ spec.summary = %q{The Fuzzy Version Matcher gem takes a list of candidate version numbers and a subject version number and provides the "best match" version from the candidate list according to some simple rules}
13
+ spec.homepage = "https://github.com/wjessop/fuzzy_version_matcher"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "minitest"
24
+ end
@@ -0,0 +1,54 @@
1
+ require "fuzzy_version_matcher/version"
2
+
3
+ module FuzzyVersionMatcher
4
+ class Node
5
+ def initialize
6
+ @nodes = {}
7
+ @version = nil
8
+ @segment = nil
9
+ end
10
+
11
+ def add_node(version_string, version_segments = nil)
12
+ # If version_segments is nil we are the top node, create a version_segments array
13
+ version_segments ||= string_to_segments(version_string)
14
+
15
+ next_segment = version_segments.shift
16
+ if version_segments.size == 0
17
+ # We got to the last remaining version segment, we need to store the whole version string in this node
18
+ @version = version_string
19
+ else
20
+ @nodes[next_segment] = self.class.new unless @nodes.has_key? next_segment
21
+ @nodes[next_segment].add_node(version_string, version_segments)
22
+ end
23
+ @segment = next_segment
24
+ end
25
+
26
+ def search(version_string, version_segments = nil)
27
+ # If version_segments is nil we are the top node, create a version_segments array
28
+ version_segments ||= string_to_segments(version_string)
29
+
30
+ next_segment = version_segments.shift
31
+ if @nodes.has_key? next_segment
32
+ @nodes[next_segment].search(version_string, version_segments)
33
+ else
34
+ return (!@version.nil? && version_segments.size == 0) ? @version : traverse_high
35
+ end
36
+ end
37
+
38
+ protected
39
+
40
+ def traverse_high
41
+ if @nodes.size > 0
42
+ return @nodes.sort_by{|seg, node| seg}.last.last.traverse_high || @version
43
+ else
44
+ return @version
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def string_to_segments(version_string)
51
+ version_string.split(/[^a-zA-Z0-9]/)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,3 @@
1
+ module FuzzyVersionMatcher
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,4 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'fuzzy_version_matcher'
3
+
4
+ require 'minitest/autorun'
@@ -0,0 +1,31 @@
1
+ require 'minitest_helper'
2
+
3
+ class TestFuzzyVersionMatcher < MiniTest::Unit::TestCase
4
+ def setup
5
+ @matcher = FuzzyVersionMatcher::Node.new
6
+ %w{5.1.45-10-percona
7
+ 5.1.45-10.2-percona
8
+ 5.1.66-14.2-percona
9
+ 5.1.67-14.3-percona
10
+ 5.5.23-25.3-percona
11
+ 5.5.27-29.0-percona
12
+ 5.5.28-29.2-percona
13
+ 5.5.29-29.4-percona}.each {|v| @matcher.add_node(v)}
14
+ end
15
+
16
+ def test_that_it_has_a_version_number
17
+ refute_nil ::FuzzyVersionMatcher::VERSION
18
+ end
19
+
20
+ def test_it_matches_exact_versions
21
+ assert_equal @matcher.search("5.1.45-10-percona"), "5.1.45-10-percona"
22
+ end
23
+
24
+ def test_it_returns_highest_version_after_most_significant_match
25
+ assert_equal @matcher.search("5.5"), "5.5.29-29.4-percona"
26
+ end
27
+
28
+ def test_inexact_match_matches_most_significant_segments_then_matches_high
29
+ assert_equal @matcher.search("5.1.66-15.5-maria"), "5.1.66-14.2-percona"
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fuzzy_version_matcher
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Will Jessop
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-03-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Does a 'best match' of a version against a list of candiate version numbers
56
+ email:
57
+ - will@willj.net
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - .travis.yml
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - fuzzy_version_matcher.gemspec
69
+ - lib/fuzzy_version_matcher.rb
70
+ - lib/fuzzy_version_matcher/version.rb
71
+ - test/minitest_helper.rb
72
+ - test/test_fuzzy_version_matcher.rb
73
+ homepage: https://github.com/wjessop/fuzzy_version_matcher
74
+ licenses:
75
+ - MIT
76
+ metadata: {}
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubyforge_project:
93
+ rubygems_version: 2.0.3
94
+ signing_key:
95
+ specification_version: 4
96
+ summary: The Fuzzy Version Matcher gem takes a list of candidate version numbers and
97
+ a subject version number and provides the "best match" version from the candidate
98
+ list according to some simple rules
99
+ test_files:
100
+ - test/minitest_helper.rb
101
+ - test/test_fuzzy_version_matcher.rb