ruby-libversion 1.0.0 → 1.1.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.
- checksums.yaml +4 -4
- data/.github/workflows/rubocop.yml +16 -0
- data/.github/workflows/test.yml +36 -0
- data/.rubocop.yml +39 -0
- data/ext/libversion/extconf.rb +11 -1
- data/lib/ruby_libversion.rb +121 -0
- data/ruby-libversion.gemspec +2 -2
- data/test/test_ruby_libversion.rb +1 -1
- metadata +8 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8aed1ad2e15370a06bc24ac5669f418ea96964c6bc6cdd65398281fc25c10cd5
|
|
4
|
+
data.tar.gz: 8f2df4487bce8cad0191339051a9ffb22812043ba3ace992470370521c5b5887
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 03670010cfb23c20b9d863b7af8820471761ae93a5226451ade2970197a2fdbff803489ce849c5a2adfadddd48618c71dd039ddd55a81a6fd9f848810c206dca
|
|
7
|
+
data.tar.gz: 93fa1af30f55b561e3aaad4c42f383fe40aeabad965535bce6b87ac862c270719e1ca39d3b2b34d17f165529a56bf0e36081db8a0f8de5369feaac6e8ebba0dd
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: Rubocop
|
|
2
|
+
on: [push, pull_request]
|
|
3
|
+
jobs:
|
|
4
|
+
test:
|
|
5
|
+
runs-on: ubuntu-latest
|
|
6
|
+
steps:
|
|
7
|
+
- name: Download source
|
|
8
|
+
uses: actions/checkout@v5
|
|
9
|
+
- name: Install Ruby
|
|
10
|
+
uses: ruby/setup-ruby@v1
|
|
11
|
+
with:
|
|
12
|
+
ruby-version: '3.4'
|
|
13
|
+
- name: Install rubocop
|
|
14
|
+
run: gem install rubocop
|
|
15
|
+
- name: Run rubocop
|
|
16
|
+
run: rubocop
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
on: [push, pull_request]
|
|
3
|
+
jobs:
|
|
4
|
+
test:
|
|
5
|
+
runs-on: ubuntu-latest
|
|
6
|
+
steps:
|
|
7
|
+
- name: Download source
|
|
8
|
+
uses: actions/checkout@v5
|
|
9
|
+
- name: Install Ruby
|
|
10
|
+
uses: ruby/setup-ruby@v1
|
|
11
|
+
with:
|
|
12
|
+
ruby-version: '3.4'
|
|
13
|
+
- name: Install dependencies
|
|
14
|
+
run: gem install rake-compiler
|
|
15
|
+
- name: Build and install ruby-libversion (Ruby fallback)
|
|
16
|
+
run: |
|
|
17
|
+
gem build ruby-libversion
|
|
18
|
+
gem install -l ruby-libversion
|
|
19
|
+
- name: Run tests (Ruby fallback)
|
|
20
|
+
run: rake test
|
|
21
|
+
- name: Install libversion # Hopefully this will get added as an Ubuntu/Debian package.
|
|
22
|
+
working-directory: ${{ runner.temp }}
|
|
23
|
+
run: |
|
|
24
|
+
git clone --depth 1 -b 3.0.3 https://github.com/repology/libversion
|
|
25
|
+
cd libversion
|
|
26
|
+
mkdir build
|
|
27
|
+
cd build
|
|
28
|
+
cmake .. -DCMAKE_INSTALL_PREFIX=/usr
|
|
29
|
+
make -j "$(nproc)"
|
|
30
|
+
sudo make install
|
|
31
|
+
- name: Build and install ruby-libversion (native extension)
|
|
32
|
+
run: |
|
|
33
|
+
gem build ruby-libversion
|
|
34
|
+
gem install -l ruby-libversion
|
|
35
|
+
- name: Run tests (native extension)
|
|
36
|
+
run: rake test
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
AllCops:
|
|
2
|
+
NewCops: enable
|
|
3
|
+
|
|
4
|
+
Gemspec/RequireMFA:
|
|
5
|
+
Enabled: false
|
|
6
|
+
|
|
7
|
+
# TODO: Find out what ruby version we actually require and then remove this.
|
|
8
|
+
Gemspec/RequiredRubyVersion:
|
|
9
|
+
Enabled: false
|
|
10
|
+
|
|
11
|
+
Layout/LineLength:
|
|
12
|
+
Enabled: false
|
|
13
|
+
|
|
14
|
+
Metrics:
|
|
15
|
+
Enabled: false
|
|
16
|
+
|
|
17
|
+
Naming/FileName:
|
|
18
|
+
Enabled: false
|
|
19
|
+
|
|
20
|
+
Naming/HeredocDelimiterNaming:
|
|
21
|
+
Enabled: false
|
|
22
|
+
|
|
23
|
+
Naming/MethodParameterName:
|
|
24
|
+
Enabled: False
|
|
25
|
+
|
|
26
|
+
Style/Documentation:
|
|
27
|
+
Enabled: False
|
|
28
|
+
|
|
29
|
+
Style/FrozenStringLiteralComment:
|
|
30
|
+
Enabled: False
|
|
31
|
+
|
|
32
|
+
Style/MutableConstant:
|
|
33
|
+
Enabled: False
|
|
34
|
+
|
|
35
|
+
Style/RedundantReturn:
|
|
36
|
+
Enabled: False
|
|
37
|
+
|
|
38
|
+
Style/RedundantSelf:
|
|
39
|
+
Enabled: False
|
data/ext/libversion/extconf.rb
CHANGED
|
@@ -2,4 +2,14 @@ require 'mkmf'
|
|
|
2
2
|
|
|
3
3
|
pkg_config('libversion')
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# If $libs is still empty, we weren't able to find the library, so we don't build the extension.
|
|
6
|
+
if $libs.empty? # rubocop:disable Style/GlobalVars
|
|
7
|
+
# Create a dummy Makefile, to satisfy Gem::Installer#install
|
|
8
|
+
# You would think mkmf's dummy_makefile method would do this, but apparently not.
|
|
9
|
+
File.write 'Makefile', <<~EOF
|
|
10
|
+
.PHONY: install
|
|
11
|
+
install:
|
|
12
|
+
EOF
|
|
13
|
+
else
|
|
14
|
+
create_makefile 'ruby_libversion'
|
|
15
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# This is a pure Ruby implementation of libversion, used as a fallback when the C extension is not available.
|
|
2
|
+
|
|
3
|
+
class VersionComponent
|
|
4
|
+
attr_accessor :component, :rank
|
|
5
|
+
|
|
6
|
+
# Store the ranks in order, so that we can compare their indexes to determine which is greater.
|
|
7
|
+
RANK_ORDERING = %i[lower_bound pre_release zero post_release nonzero letter_suffix upper_bound]
|
|
8
|
+
|
|
9
|
+
def initialize(components, flags)
|
|
10
|
+
# While we pass in a nil component to let determine_rank know we want padding, we set the actual value to 0 when we store it.
|
|
11
|
+
@component = components[1].nil? ? '0' : components[1]
|
|
12
|
+
|
|
13
|
+
@rank = determine_rank(components, flags)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def determine_rank(components, flags)
|
|
17
|
+
# If the current component is nil, it is padding.
|
|
18
|
+
if components[1].nil?
|
|
19
|
+
# When we are passed the lower bound flag, all padding is the lower_bound rank.
|
|
20
|
+
if flags == Libversion::VERSIONFLAG_LOWER_BOUND
|
|
21
|
+
return :lower_bound
|
|
22
|
+
# When we are passed the upper bound flag, all padding is the upper_bound rank.
|
|
23
|
+
elsif flags == Libversion::VERSIONFLAG_UPPER_BOUND
|
|
24
|
+
return :upper_bound
|
|
25
|
+
# If we have not been passed either bound flag, all padding is the zero rank.
|
|
26
|
+
else
|
|
27
|
+
return :zero
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# If the current component starts with a pre-release keyword (case insensitive), it is the pre_release rank.
|
|
32
|
+
return :pre_release if components[1].downcase.start_with?('alpha', 'beta', 'rc', 'pre')
|
|
33
|
+
|
|
34
|
+
# If the current component is an integer and has a value of zero, it is the zero rank.
|
|
35
|
+
return :zero if Integer(components[1], exception: false)&.zero?
|
|
36
|
+
|
|
37
|
+
# If the current component starts with a post-release keyword (case insensitive), or if the current component
|
|
38
|
+
# starts with 'p' (case insensitive) and we were given the VERSIONFLAG_P_IS_PATCH flag, it is the post_release rank.
|
|
39
|
+
return :post_release if components[1].start_with?('post', 'patch', 'pl', 'errata') || (flags == Libversion::VERSIONFLAG_P_IS_PATCH && components[1][0]&.downcase == 'p')
|
|
40
|
+
|
|
41
|
+
# If the current component is an integer and has a nonzero value, it is the nonzero rank.
|
|
42
|
+
return :nonzero if Integer(components[1], exception: false)&.nonzero?
|
|
43
|
+
|
|
44
|
+
# If the previous component is an integer, the current component is alphabetic, and the next component is not an integer, the current component is the letter_suffix rank.
|
|
45
|
+
return :letter_suffix unless Integer(components[0], exception: false).nil? || components[1].match?(/[^[:alpha:]]/) || !Integer(components[2], exception: false).nil?
|
|
46
|
+
|
|
47
|
+
# If we were given the VERSIONFLAG_ANY_IS_PATCH flag, any remaining alphabetic component is of the post_release rank.
|
|
48
|
+
return :post_release if flags == Libversion::VERSIONFLAG_ANY_IS_PATCH
|
|
49
|
+
|
|
50
|
+
# Otherwise, any remaining alphabetic component is of the pre_release rank.
|
|
51
|
+
return :pre_release
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def <=>(other)
|
|
55
|
+
# Compare the rank of both components, and return the result unless they have the same rank.
|
|
56
|
+
rank_comparison = RANK_ORDERING.index(self.rank) <=> RANK_ORDERING.index(other.rank)
|
|
57
|
+
return rank_comparison unless rank_comparison.zero?
|
|
58
|
+
|
|
59
|
+
# If both components are alphabetic, return the case-insensitive comparison of their first letters.
|
|
60
|
+
return self.component[0].downcase <=> other.component[0].downcase if [self, other].none? { _1.component.match?(/[^[:alpha:]]/) }
|
|
61
|
+
|
|
62
|
+
# If we are still here, return the integer comparison of both components.
|
|
63
|
+
return self.component.to_i <=> other.component.to_i
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def empty?
|
|
67
|
+
@component.empty?
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
module Libversion
|
|
72
|
+
VERSIONFLAG_P_IS_PATCH = 1
|
|
73
|
+
VERSIONFLAG_ANY_IS_PATCH = 2
|
|
74
|
+
VERSIONFLAG_LOWER_BOUND = 4
|
|
75
|
+
VERSIONFLAG_UPPER_BOUND = 8
|
|
76
|
+
|
|
77
|
+
def self.version_compare4(v1, v2, v1_flags, v2_flags)
|
|
78
|
+
# Parse the raw version strings into an array of VersionComponents.
|
|
79
|
+
v1_components = parse_version_string(v1, v1_flags)
|
|
80
|
+
v2_components = parse_version_string(v2, v2_flags)
|
|
81
|
+
|
|
82
|
+
# Pad each version so that they are the same length prior to zipping and comparison.
|
|
83
|
+
# We add additional padding to support lower and upper bounds even when the versions have an equal number of components.
|
|
84
|
+
v1_components.fill(VersionComponent.new([nil, nil, nil], v1_flags), v1_components.size, v2_components.size)
|
|
85
|
+
v2_components.fill(VersionComponent.new([nil, nil, nil], v2_flags), v2_components.size, v1_components.size)
|
|
86
|
+
|
|
87
|
+
# Zip the components together for ease of comparison.
|
|
88
|
+
zipped_components = v1_components.zip(v2_components)
|
|
89
|
+
|
|
90
|
+
# Iterate over the zipped components, comparing them and returning the first nonzero result we receive.
|
|
91
|
+
(0...zipped_components.size).each do |i|
|
|
92
|
+
comparison_result = zipped_components[i][0] <=> zipped_components[i][1]
|
|
93
|
+
return comparison_result unless comparison_result.zero?
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# If we got here, every component was equal, and thus the versions are equal.
|
|
97
|
+
return 0
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def self.version_compare2(v1, v2)
|
|
101
|
+
version_compare4(v1, v2, 0, 0)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
private_class_method def self.parse_version_string(version_string, version_flags)
|
|
105
|
+
# Separate the version string into all-alphabetic and all-numeric components, with all other characters treated as separators.
|
|
106
|
+
# Separators are recorded as empty strings, with consecutive separators being squeezed into a single empty string.
|
|
107
|
+
version_raw_components = version_string.scan(/[[:alpha:]]+|[[:digit:]]+|[^[:alnum:]]+/).map { _1.match?(/[^[:alnum:]]/) ? '' : _1 }
|
|
108
|
+
# Pad the raw components with nil values so that every real component gets a turn at the centre of the tuple we pass to VersionComponent.new
|
|
109
|
+
version_raw_components.prepend(nil)
|
|
110
|
+
version_raw_components.append(nil)
|
|
111
|
+
|
|
112
|
+
# Loop over the raw components in groups of 3 (so we have the information for checking letter_suffix), storing the center component
|
|
113
|
+
# and its rank as a VersionComponent in version_components.
|
|
114
|
+
version_components = []
|
|
115
|
+
version_raw_components.each_cons(3) { version_components << VersionComponent.new(_1, version_flags) }
|
|
116
|
+
# Clean up any excess empty version components.
|
|
117
|
+
version_components.reject!(&:empty?)
|
|
118
|
+
|
|
119
|
+
return version_components
|
|
120
|
+
end
|
|
121
|
+
end
|
data/ruby-libversion.gemspec
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Gem::Specification.new do |spec|
|
|
2
2
|
spec.name = 'ruby-libversion'
|
|
3
3
|
spec.summary = 'Ruby bindings for libversion'
|
|
4
|
-
spec.version = '1.
|
|
4
|
+
spec.version = '1.1.0'
|
|
5
5
|
spec.license = 'MIT'
|
|
6
6
|
spec.author = 'Maximilian Downey Twiss'
|
|
7
|
-
spec.email = 'creatorsmithmdt
|
|
7
|
+
spec.email = 'creatorsmithmdt@gmail.com'
|
|
8
8
|
spec.homepage = 'https://github.com/Zopolis4/ruby-libversion'
|
|
9
9
|
spec.files = `git ls-files`.split("\n")
|
|
10
10
|
spec.extensions = 'ext/libversion/extconf.rb'
|
|
@@ -4,7 +4,7 @@ require 'ruby_libversion'
|
|
|
4
4
|
# These test cases are taken from here:
|
|
5
5
|
# https://github.com/repology/libversion/blob/master/tests/compare_test.c
|
|
6
6
|
# The copyright notice from that file is reproduced here:
|
|
7
|
-
# Copyright (c)
|
|
7
|
+
# Copyright (c) 2017-2018 Dmitry Marakasov <amdmi3@amdmi3.ru>
|
|
8
8
|
class RubyLibversionTest < Minitest::Test
|
|
9
9
|
def test_equality
|
|
10
10
|
assert_equal(0, Libversion.version_compare2('0', '0'))
|
metadata
CHANGED
|
@@ -1,36 +1,37 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby-libversion
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Maximilian Downey Twiss
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies: []
|
|
13
|
-
|
|
14
|
-
email: creatorsmithmdt@.com
|
|
12
|
+
email: creatorsmithmdt@gmail.com
|
|
15
13
|
executables: []
|
|
16
14
|
extensions:
|
|
17
15
|
- ext/libversion/extconf.rb
|
|
18
16
|
extra_rdoc_files: []
|
|
19
17
|
files:
|
|
18
|
+
- ".github/workflows/rubocop.yml"
|
|
19
|
+
- ".github/workflows/test.yml"
|
|
20
20
|
- ".gitignore"
|
|
21
|
+
- ".rubocop.yml"
|
|
21
22
|
- LICENSE
|
|
22
23
|
- README.md
|
|
23
24
|
- Rakefile
|
|
24
25
|
- ext/libversion/extconf.rb
|
|
25
26
|
- ext/libversion/libversion.c
|
|
26
27
|
- lib/libversion.rb
|
|
28
|
+
- lib/ruby_libversion.rb
|
|
27
29
|
- ruby-libversion.gemspec
|
|
28
30
|
- test/test_ruby_libversion.rb
|
|
29
31
|
homepage: https://github.com/Zopolis4/ruby-libversion
|
|
30
32
|
licenses:
|
|
31
33
|
- MIT
|
|
32
34
|
metadata: {}
|
|
33
|
-
post_install_message:
|
|
34
35
|
rdoc_options: []
|
|
35
36
|
require_paths:
|
|
36
37
|
- lib
|
|
@@ -45,8 +46,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
45
46
|
- !ruby/object:Gem::Version
|
|
46
47
|
version: '0'
|
|
47
48
|
requirements: []
|
|
48
|
-
rubygems_version: 3.
|
|
49
|
-
signing_key:
|
|
49
|
+
rubygems_version: 3.6.7
|
|
50
50
|
specification_version: 4
|
|
51
51
|
summary: Ruby bindings for libversion
|
|
52
52
|
test_files: []
|