shivers 0.6.0.pre.2 → 0.6.0.pre.3
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/Gemfile +2 -0
- data/Gemfile.lock +77 -43
- data/Rakefile +70 -47
- data/bin/console +1 -0
- data/lib/shivers/format.rb +21 -0
- data/lib/shivers/library_version.rb +3 -0
- data/lib/shivers/matchers/child.rb +21 -0
- data/lib/shivers/matchers/parent.rb +21 -0
- data/lib/shivers/matchers/recursive.rb +21 -0
- data/lib/shivers/matchers.rb +10 -0
- data/lib/shivers/parts/alphanumeric.rb +43 -0
- data/lib/shivers/parts/alphanumeric_or_hyphen.rb +43 -0
- data/lib/shivers/parts/mixins/multivaluable.rb +29 -0
- data/lib/shivers/parts/numeric.rb +41 -0
- data/lib/shivers/parts/static.rb +39 -0
- data/lib/shivers/parts.rb +11 -0
- data/lib/shivers/value_equality.rb +15 -0
- data/lib/shivers/version.rb +29 -1
- data/lib/shivers/version2.rb +17 -0
- data/lib/shivers/version_definition.rb +45 -0
- data/lib/shivers/visitors/extract_visitor.rb +121 -0
- data/lib/shivers/visitors/matcher_visitor.rb +122 -0
- data/lib/shivers/visitors.rb +9 -0
- data/lib/shivers.rb +7 -27
- data/shivers.gemspec +32 -17
- metadata +108 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef585fce1c9a709b6be59c8ec024e9b571dd9f9bf9a93f1e40ac7fea0d99af30
|
4
|
+
data.tar.gz: 25eb7d476ee1baf3fbd1df9430733de393555bc237e2243c9f0aca9e6e0ee6a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee2027a2e57acec384d68bf3ea5610cdece6b90a45888d9b2cc078fc6e352602eeea1f4069c11e4e1d68d1b4ed3df25517db04ed9ce68d90416508af5af5d85e
|
7
|
+
data.tar.gz: e485203e86ad45a75e54538f0194ae841d285df52fb7c4248f84690918750aceb2e4bc746621c2c986bcbaf82151976346e3329793da0258d882702063b23ec4
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,54 +1,68 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
shivers (0.6.0.pre.
|
4
|
+
shivers (0.6.0.pre.3)
|
5
5
|
semantic (~> 1.6)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
activesupport (
|
10
|
+
activesupport (7.0.2.3)
|
11
11
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
12
12
|
i18n (>= 1.6, < 2)
|
13
13
|
minitest (>= 5.1)
|
14
14
|
tzinfo (~> 2.0)
|
15
|
-
|
16
|
-
addressable (2.7.0)
|
15
|
+
addressable (2.8.0)
|
17
16
|
public_suffix (>= 2.0.2, < 5.0)
|
17
|
+
ast (2.4.2)
|
18
18
|
colored2 (3.1.2)
|
19
|
-
concurrent-ruby (1.1.
|
20
|
-
diff-lcs (1.
|
19
|
+
concurrent-ruby (1.1.9)
|
20
|
+
diff-lcs (1.5.0)
|
21
21
|
docile (1.4.0)
|
22
|
-
excon (0.
|
23
|
-
fakefs (
|
24
|
-
faraday (1.
|
22
|
+
excon (0.92.0)
|
23
|
+
fakefs (1.4.1)
|
24
|
+
faraday (1.10.0)
|
25
25
|
faraday-em_http (~> 1.0)
|
26
26
|
faraday-em_synchrony (~> 1.0)
|
27
27
|
faraday-excon (~> 1.1)
|
28
|
+
faraday-httpclient (~> 1.0)
|
29
|
+
faraday-multipart (~> 1.0)
|
28
30
|
faraday-net_http (~> 1.0)
|
29
|
-
faraday-net_http_persistent (~> 1.
|
30
|
-
|
31
|
+
faraday-net_http_persistent (~> 1.0)
|
32
|
+
faraday-patron (~> 1.0)
|
33
|
+
faraday-rack (~> 1.0)
|
34
|
+
faraday-retry (~> 1.0)
|
31
35
|
ruby2_keywords (>= 0.0.4)
|
32
36
|
faraday-em_http (1.0.0)
|
33
37
|
faraday-em_synchrony (1.0.0)
|
34
38
|
faraday-excon (1.1.0)
|
39
|
+
faraday-httpclient (1.0.1)
|
40
|
+
faraday-multipart (1.0.3)
|
41
|
+
multipart-post (>= 1.2, < 3)
|
35
42
|
faraday-net_http (1.0.1)
|
36
|
-
faraday-net_http_persistent (1.
|
43
|
+
faraday-net_http_persistent (1.2.0)
|
44
|
+
faraday-patron (1.0.0)
|
45
|
+
faraday-rack (1.0.0)
|
46
|
+
faraday-retry (1.0.3)
|
37
47
|
gem-release (2.2.2)
|
38
48
|
hamster (3.0.0)
|
39
49
|
concurrent-ruby (~> 1.0)
|
40
|
-
i18n (1.
|
50
|
+
i18n (1.10.0)
|
41
51
|
concurrent-ruby (~> 1.0)
|
42
52
|
lino (3.0.0)
|
43
53
|
hamster (~> 3.0)
|
44
54
|
open4 (~> 1.3)
|
45
|
-
minitest (5.
|
55
|
+
minitest (5.15.0)
|
46
56
|
multipart-post (2.1.1)
|
47
|
-
octokit (4.
|
57
|
+
octokit (4.22.0)
|
48
58
|
faraday (>= 0.9)
|
49
59
|
sawyer (~> 0.8.0, >= 0.5.3)
|
50
60
|
open4 (1.3.4)
|
61
|
+
parallel (1.21.0)
|
62
|
+
parser (3.1.1.0)
|
63
|
+
ast (~> 2.4.1)
|
51
64
|
public_suffix (4.0.6)
|
65
|
+
rainbow (3.1.1)
|
52
66
|
rake (13.0.6)
|
53
67
|
rake_circle_ci (0.9.0)
|
54
68
|
colored2 (~> 3.1)
|
@@ -58,7 +72,7 @@ GEM
|
|
58
72
|
rake_factory (0.29.0)
|
59
73
|
activesupport (>= 4)
|
60
74
|
rake (~> 13.0)
|
61
|
-
rake_github (0.
|
75
|
+
rake_github (0.9.0)
|
62
76
|
colored2 (~> 3.1)
|
63
77
|
octokit (~> 4.16)
|
64
78
|
rake_factory (~> 0.23)
|
@@ -70,20 +84,38 @@ GEM
|
|
70
84
|
colored2 (~> 3.1)
|
71
85
|
rake_factory (~> 0.23)
|
72
86
|
sshkey (~> 2.0)
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
rspec-
|
77
|
-
|
78
|
-
rspec-
|
79
|
-
rspec-
|
87
|
+
regexp_parser (2.2.1)
|
88
|
+
rexml (3.2.5)
|
89
|
+
rspec (3.11.0)
|
90
|
+
rspec-core (~> 3.11.0)
|
91
|
+
rspec-expectations (~> 3.11.0)
|
92
|
+
rspec-mocks (~> 3.11.0)
|
93
|
+
rspec-core (3.11.0)
|
94
|
+
rspec-support (~> 3.11.0)
|
95
|
+
rspec-expectations (3.11.0)
|
80
96
|
diff-lcs (>= 1.2.0, < 2.0)
|
81
|
-
rspec-support (~> 3.
|
82
|
-
rspec-mocks (3.
|
97
|
+
rspec-support (~> 3.11.0)
|
98
|
+
rspec-mocks (3.11.0)
|
83
99
|
diff-lcs (>= 1.2.0, < 2.0)
|
84
|
-
rspec-support (~> 3.
|
85
|
-
rspec-support (3.
|
86
|
-
|
100
|
+
rspec-support (~> 3.11.0)
|
101
|
+
rspec-support (3.11.0)
|
102
|
+
rubocop (1.26.0)
|
103
|
+
parallel (~> 1.10)
|
104
|
+
parser (>= 3.1.0.0)
|
105
|
+
rainbow (>= 2.2.2, < 4.0)
|
106
|
+
regexp_parser (>= 1.8, < 3.0)
|
107
|
+
rexml
|
108
|
+
rubocop-ast (>= 1.16.0, < 2.0)
|
109
|
+
ruby-progressbar (~> 1.7)
|
110
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
111
|
+
rubocop-ast (1.16.0)
|
112
|
+
parser (>= 3.1.1.0)
|
113
|
+
rubocop-rake (0.6.0)
|
114
|
+
rubocop (~> 1.0)
|
115
|
+
rubocop-rspec (2.9.0)
|
116
|
+
rubocop (~> 1.19)
|
117
|
+
ruby-progressbar (1.11.0)
|
118
|
+
ruby2_keywords (0.0.5)
|
87
119
|
ruby_gpg2 (0.8.0)
|
88
120
|
lino (>= 1.5)
|
89
121
|
sawyer (0.8.2)
|
@@ -95,29 +127,31 @@ GEM
|
|
95
127
|
simplecov-html (~> 0.11)
|
96
128
|
simplecov_json_formatter (~> 0.1)
|
97
129
|
simplecov-html (0.12.3)
|
98
|
-
simplecov_json_formatter (0.1.
|
130
|
+
simplecov_json_formatter (0.1.4)
|
99
131
|
sshkey (2.0.0)
|
100
132
|
tzinfo (2.0.4)
|
101
133
|
concurrent-ruby (~> 1.0)
|
102
|
-
|
134
|
+
unicode-display_width (2.1.0)
|
103
135
|
|
104
136
|
PLATFORMS
|
105
|
-
|
106
|
-
x86_64-darwin-19
|
137
|
+
arm64-darwin-21
|
107
138
|
x86_64-linux
|
108
139
|
|
109
140
|
DEPENDENCIES
|
110
|
-
bundler
|
111
|
-
fakefs
|
112
|
-
gem-release
|
113
|
-
rake
|
114
|
-
rake_circle_ci
|
115
|
-
rake_github
|
116
|
-
rake_gpg
|
117
|
-
rake_ssh
|
118
|
-
rspec
|
141
|
+
bundler
|
142
|
+
fakefs
|
143
|
+
gem-release
|
144
|
+
rake
|
145
|
+
rake_circle_ci
|
146
|
+
rake_github
|
147
|
+
rake_gpg
|
148
|
+
rake_ssh
|
149
|
+
rspec
|
150
|
+
rubocop
|
151
|
+
rubocop-rake
|
152
|
+
rubocop-rspec
|
119
153
|
shivers!
|
120
|
-
simplecov
|
154
|
+
simplecov
|
121
155
|
|
122
156
|
BUNDLED WITH
|
123
|
-
2.
|
157
|
+
2.3.9
|
data/Rakefile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'yaml'
|
2
4
|
require 'fileutils'
|
3
5
|
require 'rake_circle_ci'
|
@@ -6,18 +8,20 @@ require 'rake_ssh'
|
|
6
8
|
require 'rake_gpg'
|
7
9
|
require 'securerandom'
|
8
10
|
require 'rspec/core/rake_task'
|
11
|
+
require 'rubocop/rake_task'
|
9
12
|
|
10
|
-
task :
|
11
|
-
|
12
|
-
|
13
|
+
task default: %i[
|
14
|
+
library:fix
|
15
|
+
test:unit
|
16
|
+
]
|
13
17
|
|
14
18
|
namespace :encryption do
|
15
19
|
namespace :passphrase do
|
20
|
+
desc 'Generate encryption passphrase for CI GPG key'
|
16
21
|
task :generate do
|
17
|
-
FileUtils.mkdir_p(
|
18
|
-
File.
|
19
|
-
|
20
|
-
end
|
22
|
+
FileUtils.mkdir_p('config/secrets/ci/')
|
23
|
+
File.write('config/secrets/ci/encryption.passphrase',
|
24
|
+
SecureRandom.base64(36))
|
21
25
|
end
|
22
26
|
end
|
23
27
|
end
|
@@ -25,83 +29,102 @@ end
|
|
25
29
|
namespace :keys do
|
26
30
|
namespace :deploy do
|
27
31
|
RakeSSH.define_key_tasks(
|
28
|
-
|
29
|
-
|
32
|
+
path: 'config/secrets/ci/',
|
33
|
+
comment: 'maintainers@infrablocks.io'
|
34
|
+
)
|
30
35
|
end
|
31
36
|
|
32
37
|
namespace :gpg do
|
33
38
|
RakeGPG.define_generate_key_task(
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
+
output_directory: 'config/secrets/ci',
|
40
|
+
name_prefix: 'gpg',
|
41
|
+
owner_name: 'InfraBlocks Maintainers',
|
42
|
+
owner_email: 'maintainers@infrablocks.io',
|
43
|
+
owner_comment: 'shivers CI Key'
|
44
|
+
)
|
39
45
|
end
|
40
46
|
end
|
41
47
|
|
48
|
+
RuboCop::RakeTask.new
|
49
|
+
|
50
|
+
namespace :library do
|
51
|
+
desc 'Run all checks of the library'
|
52
|
+
task check: [:rubocop]
|
53
|
+
|
54
|
+
desc 'Attempt to automatically fix issues with the library'
|
55
|
+
task fix: [:'rubocop:auto_correct']
|
56
|
+
end
|
57
|
+
|
58
|
+
namespace :test do
|
59
|
+
RSpec::Core::RakeTask.new(:unit)
|
60
|
+
end
|
61
|
+
|
42
62
|
RakeCircleCI.define_project_tasks(
|
43
|
-
|
44
|
-
|
63
|
+
namespace: :circle_ci,
|
64
|
+
project_slug: 'github/infrablocks/shivers'
|
45
65
|
) do |t|
|
46
66
|
circle_ci_config =
|
47
|
-
|
67
|
+
YAML.load_file('config/secrets/circle_ci/config.yaml')
|
48
68
|
|
49
|
-
t.api_token = circle_ci_config[
|
69
|
+
t.api_token = circle_ci_config['circle_ci_api_token']
|
50
70
|
t.environment_variables = {
|
51
|
-
|
52
|
-
|
53
|
-
|
71
|
+
ENCRYPTION_PASSPHRASE:
|
72
|
+
File.read('config/secrets/ci/encryption.passphrase')
|
73
|
+
.chomp
|
54
74
|
}
|
55
75
|
t.checkout_keys = []
|
56
76
|
t.ssh_keys = [
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
77
|
+
{
|
78
|
+
hostname: 'github.com',
|
79
|
+
private_key: File.read('config/secrets/ci/ssh.private')
|
80
|
+
}
|
61
81
|
]
|
62
82
|
end
|
63
83
|
|
64
84
|
RakeGithub.define_repository_tasks(
|
65
|
-
|
66
|
-
|
67
|
-
) do |t|
|
85
|
+
namespace: :github,
|
86
|
+
repository: 'infrablocks/shivers'
|
87
|
+
) do |t, args|
|
68
88
|
github_config =
|
69
|
-
|
89
|
+
YAML.load_file('config/secrets/github/config.yaml')
|
70
90
|
|
71
|
-
t.access_token = github_config[
|
91
|
+
t.access_token = github_config['github_personal_access_token']
|
72
92
|
t.deploy_keys = [
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
93
|
+
{
|
94
|
+
title: 'CircleCI',
|
95
|
+
public_key: File.read('config/secrets/ci/ssh.public')
|
96
|
+
}
|
77
97
|
]
|
98
|
+
t.branch_name = args.branch_name
|
99
|
+
t.commit_message = args.commit_message
|
78
100
|
end
|
79
101
|
|
80
102
|
namespace :pipeline do
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
103
|
+
desc 'Prepare CircleCI Pipeline'
|
104
|
+
task prepare: %i[
|
105
|
+
circle_ci:project:follow
|
106
|
+
circle_ci:env_vars:ensure
|
107
|
+
circle_ci:checkout_keys:ensure
|
108
|
+
circle_ci:ssh_keys:ensure
|
109
|
+
github:deploy_keys:ensure
|
87
110
|
]
|
88
111
|
end
|
89
112
|
|
90
113
|
namespace :version do
|
91
|
-
desc
|
114
|
+
desc 'Bump version for specified type (pre, major, minor, patch)'
|
92
115
|
task :bump, [:type] do |_, args|
|
93
116
|
bump_version_for(args.type)
|
94
117
|
end
|
95
118
|
end
|
96
119
|
|
97
|
-
desc
|
120
|
+
desc 'Release gem'
|
98
121
|
task :release do
|
99
|
-
sh
|
122
|
+
sh 'gem release --tag --push'
|
100
123
|
end
|
101
124
|
|
102
125
|
def bump_version_for(version_type)
|
103
|
-
sh "gem bump --version #{version_type} "
|
104
|
-
|
105
|
-
|
106
|
-
|
126
|
+
sh "gem bump --file lib/shivers/library_version.rb --version #{version_type} " \
|
127
|
+
'&& bundle install ' \
|
128
|
+
'&& export LAST_MESSAGE="$(git log -1 --pretty=%B)" ' \
|
129
|
+
'&& git commit -a --amend -m "${LAST_MESSAGE} [ci skip]"'
|
107
130
|
end
|
data/bin/console
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'value_equality'
|
4
|
+
|
5
|
+
module Shivers
|
6
|
+
class Format
|
7
|
+
include ValueEquality
|
8
|
+
|
9
|
+
def initialize(formatter)
|
10
|
+
@formatter = formatter
|
11
|
+
end
|
12
|
+
|
13
|
+
def visit(visitor)
|
14
|
+
@formatter.call(visitor)
|
15
|
+
end
|
16
|
+
|
17
|
+
def state
|
18
|
+
[@formatter]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shivers
|
4
|
+
module Matchers
|
5
|
+
class Child
|
6
|
+
include ValueEquality
|
7
|
+
|
8
|
+
attr_reader :matcher, :capturer, :child
|
9
|
+
|
10
|
+
def initialize(matcher, capturer, child)
|
11
|
+
@matcher = matcher
|
12
|
+
@capturer = capturer
|
13
|
+
@child = child
|
14
|
+
end
|
15
|
+
|
16
|
+
def state
|
17
|
+
[@matcher, @capturer, @child]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shivers
|
4
|
+
module Matchers
|
5
|
+
class Parent
|
6
|
+
include ValueEquality
|
7
|
+
|
8
|
+
attr_reader :matcher, :capturer, :children
|
9
|
+
|
10
|
+
def initialize(matcher, capturer, children)
|
11
|
+
@matcher = matcher
|
12
|
+
@capturer = capturer
|
13
|
+
@children = children
|
14
|
+
end
|
15
|
+
|
16
|
+
def state
|
17
|
+
[@matcher, @capturer, @children]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shivers
|
4
|
+
module Matchers
|
5
|
+
class Recursive
|
6
|
+
include ValueEquality
|
7
|
+
|
8
|
+
attr_reader :capture_group, :first, :rest
|
9
|
+
|
10
|
+
def initialize(capture_group, first, rest)
|
11
|
+
@capture_group = capture_group
|
12
|
+
@first = first
|
13
|
+
@rest = rest
|
14
|
+
end
|
15
|
+
|
16
|
+
def state
|
17
|
+
[@capture_group, @first, @rest]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'mixins/multivaluable'
|
4
|
+
require_relative '../value_equality'
|
5
|
+
|
6
|
+
module Shivers
|
7
|
+
module Parts
|
8
|
+
class Alphanumeric
|
9
|
+
include ValueEquality
|
10
|
+
include Mixins::Multivaluable
|
11
|
+
|
12
|
+
def initialize(data = {})
|
13
|
+
@traits = data[:traits] || []
|
14
|
+
end
|
15
|
+
|
16
|
+
def matcher
|
17
|
+
/[a-zA-Z0-9]+/
|
18
|
+
end
|
19
|
+
|
20
|
+
def convert(value)
|
21
|
+
value
|
22
|
+
end
|
23
|
+
|
24
|
+
def capturable?
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
def ==(other)
|
29
|
+
other.class == self.class && other.state == state
|
30
|
+
end
|
31
|
+
|
32
|
+
alias eql? ==
|
33
|
+
|
34
|
+
def hash
|
35
|
+
self.class.hash ^ state.hash
|
36
|
+
end
|
37
|
+
|
38
|
+
def state
|
39
|
+
[@traits]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'mixins/multivaluable'
|
4
|
+
require_relative '../value_equality'
|
5
|
+
|
6
|
+
module Shivers
|
7
|
+
module Parts
|
8
|
+
class AlphanumericOrHyphen
|
9
|
+
include ValueEquality
|
10
|
+
include Mixins::Multivaluable
|
11
|
+
|
12
|
+
def initialize(data = {})
|
13
|
+
@traits = data[:traits] || []
|
14
|
+
end
|
15
|
+
|
16
|
+
def matcher
|
17
|
+
/[a-zA-Z0-9-]+/
|
18
|
+
end
|
19
|
+
|
20
|
+
def convert(value)
|
21
|
+
value
|
22
|
+
end
|
23
|
+
|
24
|
+
def capturable?
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
def ==(other)
|
29
|
+
other.class == self.class && other.state == state
|
30
|
+
end
|
31
|
+
|
32
|
+
alias eql? ==
|
33
|
+
|
34
|
+
def hash
|
35
|
+
self.class.hash ^ state.hash
|
36
|
+
end
|
37
|
+
|
38
|
+
def state
|
39
|
+
[@traits]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shivers
|
4
|
+
module Parts
|
5
|
+
module Mixins
|
6
|
+
module Multivaluable
|
7
|
+
def multivalued?
|
8
|
+
@traits.include?(:multivalued)
|
9
|
+
end
|
10
|
+
|
11
|
+
def merge(first, second)
|
12
|
+
multivalued? ? concatable(first).concat(concatable(second)) : second
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def concatable(value)
|
18
|
+
if value.nil?
|
19
|
+
[]
|
20
|
+
elsif value.is_a?(Array)
|
21
|
+
value
|
22
|
+
else
|
23
|
+
[value]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'mixins/multivaluable'
|
4
|
+
require_relative '../value_equality'
|
5
|
+
|
6
|
+
module Shivers
|
7
|
+
module Parts
|
8
|
+
class Numeric
|
9
|
+
include ValueEquality
|
10
|
+
include Mixins::Multivaluable
|
11
|
+
|
12
|
+
def initialize(_ = {}); end
|
13
|
+
|
14
|
+
def matcher
|
15
|
+
/0|[1-9]\d*/
|
16
|
+
end
|
17
|
+
|
18
|
+
def convert(value)
|
19
|
+
value&.to_i
|
20
|
+
end
|
21
|
+
|
22
|
+
def capturable?
|
23
|
+
true
|
24
|
+
end
|
25
|
+
|
26
|
+
def ==(other)
|
27
|
+
other.class == self.class && other.state == state
|
28
|
+
end
|
29
|
+
|
30
|
+
alias eql? ==
|
31
|
+
|
32
|
+
def hash
|
33
|
+
self.class.hash ^ state.hash
|
34
|
+
end
|
35
|
+
|
36
|
+
def state
|
37
|
+
[]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|