sec_id 4.0.0 → 4.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 374eb5eb544fd34d09e5d5008473b5516c3b9ac13e720dd7ea01062478da5248
4
- data.tar.gz: 6b785b97c0bd99c56feb8a500f1376f228077f0d58503cb823af3d2abc790ae6
3
+ metadata.gz: 58a56c99692f66ae9ff3be10064ab29e729f34d6877456a6c998ee1a3509478d
4
+ data.tar.gz: ed1ead1827a544b8c48894739916781ea62337aa75e26f7263dd54c08f70b074
5
5
  SHA512:
6
- metadata.gz: ca697d5bf5326587d437f6206e91d419ad11aad3166f6d2c75f423afae1fcaf3736860b313545d85761f9575bf85f56120f5d3d74e92158fa3c1ed9fc4d5be5d
7
- data.tar.gz: 1c46330ecd6e07192eaf083dc28e41e7b3edbb83a1ee226f76817df4c3182fc20f4e42415350da9bf343b5e89445e1545d79cf1ca02dea15a380fe94f07bef82
6
+ metadata.gz: 437a5b95d0e14cead4d0392dbaa2da4fbc7c3325a01252f17032ca50e9dc3609a6dfe8e73947535de2e2fe228c460c33847635f90c0d99fddf6ff32c66117fbb
7
+ data.tar.gz: d2e44281f824c033add9074633432291794789b4f1b89e50b5977b1dfd34efd68e5dd2883c7c9076cf5e30316b6a8e487853185824f988827cad61e44e2c38c9
data/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.2.0] - 2025-01-12
4
+
5
+ ### Added
6
+
7
+ - OCC support ([@wtn](https://github.com/wtn), [#93](https://github.com/svyatov/sec_id/pull/93))
8
+
9
+ ### Fixed
10
+
11
+ - CUSIP#cins? usage example in README ([@wtn](https://github.com/wtn), [#91](https://github.com/svyatov/sec_id/pull/91))
12
+
13
+ ### Updated
14
+
15
+ - Separate CIK from Base for cleaner architecture ([@wtn](https://github.com/wtn), [#92](https://github.com/svyatov/sec_id/pull/92))
16
+ - Use rubocop-rspec plugin ([@wtn](https://github.com/wtn), [#90](https://github.com/svyatov/sec_id/pull/90))
17
+ - Replace CodeClimate with Codecov
18
+ - Add permissions to CI workflow
19
+ - Clean up gemspec: update description and simplify files list
20
+
21
+ ## [4.1.0] - 2024-09-23
22
+
23
+ ### Added
24
+
25
+ - FIGI support ([@wtn](https://github.com/wtn), [#84](https://github.com/svyatov/sec_id/pull/84))
26
+ - CIK support ([@wtn](https://github.com/wtn), [#85](https://github.com/svyatov/sec_id/pull/85))
27
+ - Convert between CUSIPs and ISINs ([@wtn](https://github.com/wtn), [#86](https://github.com/svyatov/sec_id/pull/86), [#88](https://github.com/svyatov/sec_id/pull/88))
28
+ - CINS check method for CUSIPs ([@wtn](https://github.com/wtn), [#87](https://github.com/svyatov/sec_id/pull/87))
29
+
30
+ ### Updated
31
+
32
+ - Small internal refactorings
33
+
3
34
  ## [4.0.0] - 2024-07-09
4
35
 
5
36
  ### Breaking changes
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
1
  # SecId
2
2
  [![Gem Version](https://badge.fury.io/rb/sec_id.svg)](https://badge.fury.io/rb/sec_id)
3
+ [![codecov](https://codecov.io/gh/svyatov/sec_id/graph/badge.svg)](https://codecov.io/gh/svyatov/sec_id)
3
4
  ![Build Status](https://github.com/svyatov/sec_id/actions/workflows/main.yml/badge.svg?branch=main)
4
- [![Maintainability](https://api.codeclimate.com/v1/badges/a4759963a5ddc4d55b24/maintainability)](https://codeclimate.com/github/svyatov/sec_id/maintainability)
5
- [![Test Coverage](https://api.codeclimate.com/v1/badges/a4759963a5ddc4d55b24/test_coverage)](https://codeclimate.com/github/svyatov/sec_id/test_coverage)
6
5
 
7
6
  Validate securities identification numbers with ease!
8
7
 
@@ -11,7 +10,10 @@ Check-digit calculation is also available.
11
10
  Currently supported standards:
12
11
  [ISIN](https://en.wikipedia.org/wiki/International_Securities_Identification_Number),
13
12
  [CUSIP](https://en.wikipedia.org/wiki/CUSIP),
14
- [SEDOL](https://en.wikipedia.org/wiki/SEDOL)
13
+ [SEDOL](https://en.wikipedia.org/wiki/SEDOL),
14
+ [FIGI](https://en.wikipedia.org/wiki/Financial_Instrument_Global_Identifier),
15
+ [CIK](https://en.wikipedia.org/wiki/Central_Index_Key),
16
+ [OCC](https://en.wikipedia.org/wiki/Option_symbol#The_OCC_Option_Symbol).
15
17
 
16
18
  Work in progress:
17
19
  [IBAN](https://en.wikipedia.org/wiki/International_Bank_Account_Number).
@@ -21,7 +23,7 @@ Work in progress:
21
23
  Add this line to your application's Gemfile:
22
24
 
23
25
  ```ruby
24
- gem 'sec_id', '~> 4.0'
26
+ gem 'sec_id', '~> 4.2'
25
27
  ```
26
28
 
27
29
  And then execute:
@@ -115,6 +117,7 @@ isin.valid? # => true
115
117
  isin.valid_format? # => true
116
118
  isin.restore! # => 'US5949181045'
117
119
  isin.calculate_check_digit # => 5
120
+ isin.to_cusip # => #<SecId::CUSIP>
118
121
  ```
119
122
 
120
123
  ### SecId::CUSIP full example
@@ -136,6 +139,8 @@ cusip.valid? # => true
136
139
  cusip.valid_format? # => true
137
140
  cusip.restore! # => '594918104'
138
141
  cusip.calculate_check_digit # => 4
142
+ cusip.to_isin('US') # => #<SecId::ISIN>
143
+ cusip.cins? # => false
139
144
  ```
140
145
 
141
146
  ### SecId::SEDOL full example
@@ -157,6 +162,83 @@ cusip.restore! # => 'B0Z52W5'
157
162
  cusip.calculate_check_digit # => 5
158
163
  ```
159
164
 
165
+ ### SecId::FIGI full example
166
+
167
+ ```ruby
168
+ # class level
169
+ SecId::FIGI.valid?('BBG000DMBXR2') # => true
170
+ SecId::FIGI.valid_format?('BBG000DMBXR2') # => true
171
+ SecId::FIGI.restore!('BBG000DMBXR') # => 'BBG000DMBXR2'
172
+ SecId::FIGI.check_digit('BBG000DMBXR') # => 2
173
+
174
+ # instance level
175
+ figi = SecId::FIGI.new('BBG000DMBXR2')
176
+ figi.full_number # => 'BBG000DMBXR2'
177
+ figi.prefix # => 'BB'
178
+ figi.random_part # => '000DMBXR'
179
+ figi.check_digit # => 2
180
+ figi.valid? # => true
181
+ figi.valid_format? # => true
182
+ figi.restore! # => 'BBG000DMBXR2'
183
+ figi.calculate_check_digit # => 2
184
+ ```
185
+
186
+ ### SecId::CIK full example
187
+
188
+ ```ruby
189
+ # class level
190
+ SecId::CIK.valid?('0001094517') # => true
191
+ SecId::CIK.valid_format?('0001094517') # => true
192
+ SecId::CIK.normalize!('1094517') # => '0001094517'
193
+
194
+ # instance level
195
+ cik = SecId::CIK.new('0001094517')
196
+ cik.full_number # => '0001094517'
197
+ cik.padding # => '000'
198
+ cik.identifier # => '1094517'
199
+ cik.valid? # => true
200
+ cik.valid_format? # => true
201
+ cik.normalize! # => '0001094517'
202
+ cik.to_s # => '0001094517'
203
+ ```
204
+
205
+ ### SecId::OCC full example
206
+
207
+ ```ruby
208
+ # class level
209
+ SecId::OCC.valid?('BRKB 100417C00090000') # => true
210
+ SecId::OCC.valid_format?('BRKB 100417C00090000') # => true
211
+ SecId::OCC.normalize!('BRKB100417C00090000') # => 'BRKB 100417C00090000'
212
+ SecId::OCC.build(
213
+ underlying: 'BRKB',
214
+ date: Date.new(2010, 4, 17),
215
+ type: 'C',
216
+ strike: 90,
217
+ ) # => #<SecId::OCC>
218
+
219
+ # instance level
220
+ occ = SecId::OCC.new('BRKB 100417C00090000')
221
+ occ.full_symbol # => 'BRKB 100417C00090000'
222
+ occ.underlying # => 'BRKB'
223
+ occ.date_str # => '100417'
224
+ occ.date_obj # => #<Date: 2010-04-17>
225
+ occ.type # => 'C'
226
+ occ.strike # => 90.0
227
+ occ.valid? # => true
228
+ occ.valid_format? # => true
229
+ occ.normalize! # => 'BRKB 100417C00090000'
230
+
231
+ occ = SecId::OCC.new('BRKB 2010-04-17C00090000')
232
+ occ.valid_format? # => false
233
+ occ.normalize! # raises SecId::InvalidFormatError
234
+
235
+ occ = SecId::OCC.new('X 250620C00050000')
236
+ occ.full_symbol # => 'X 250620C00050000'
237
+ occ.valid? # => true
238
+ occ.normalize! # => 'X 250620C00050000'
239
+ occ.full_symbol # => 'X 250620C00050000'
240
+ ```
241
+
160
242
  ## Development
161
243
 
162
244
  After checking out the repo, run `bin/setup` to install dependencies.
data/lib/sec_id/cik.rb ADDED
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SecId
4
+ # https://en.wikipedia.org/wiki/Central_Index_Key
5
+ class CIK
6
+ ID_REGEX = /\A
7
+ (?=\d{1,10}\z)(?<padding>0*)(?<identifier>[1-9]\d{0,9})
8
+ \z/x
9
+
10
+ attr_reader :full_number, :identifier, :padding
11
+
12
+ class << self
13
+ def valid?(id)
14
+ new(id).valid?
15
+ end
16
+
17
+ def valid_format?(id)
18
+ new(id).valid_format?
19
+ end
20
+
21
+ def normalize!(id)
22
+ new(id).normalize!
23
+ end
24
+ end
25
+
26
+ def initialize(cik)
27
+ cik_parts = parse(cik)
28
+ @padding = cik_parts[:padding]
29
+ @identifier = cik_parts[:identifier]
30
+ end
31
+
32
+ def valid?
33
+ valid_format?
34
+ end
35
+
36
+ def valid_format?
37
+ !identifier.nil?
38
+ end
39
+
40
+ def normalize!
41
+ raise InvalidFormatError, "CIK '#{full_number}' is invalid and cannot be normalized!" unless valid_format?
42
+
43
+ @padding = '0' * (10 - @identifier.length)
44
+ @full_number = @identifier.rjust(10, '0')
45
+ end
46
+
47
+ def to_s
48
+ full_number
49
+ end
50
+ alias to_str to_s
51
+
52
+ private
53
+
54
+ def parse(cik_number)
55
+ @full_number = cik_number.to_s.strip
56
+ @full_number.match(ID_REGEX) || {}
57
+ end
58
+ end
59
+ end
data/lib/sec_id/cusip.rb CHANGED
@@ -21,27 +21,41 @@ module SecId
21
21
  end
22
22
 
23
23
  def calculate_check_digit
24
- return mod10(modified_luhn_sum) if valid_format?
24
+ unless valid_format?
25
+ raise InvalidFormatError, "CUSIP '#{full_number}' is invalid and check-digit cannot be calculated!"
26
+ end
27
+
28
+ mod10(modified_luhn_sum)
29
+ end
30
+
31
+ def to_isin(country_code)
32
+ unless ISIN::CGS_COUNTRY_CODES.include?(country_code)
33
+ raise(InvalidFormatError, "'#{country_code}' is not a CGS country code!")
34
+ end
25
35
 
26
- raise InvalidFormatError, "CUSIP '#{full_number}' is invalid and check-digit cannot be calculated!"
36
+ restore!
37
+ isin = ISIN.new(country_code + full_number)
38
+ isin.restore!
39
+ isin
40
+ end
41
+
42
+ # CUSIP International Numbering System
43
+ def cins?
44
+ cusip6[0] < '0' || cusip6[0] > '9'
27
45
  end
28
46
 
29
47
  private
30
48
 
31
49
  # https://en.wikipedia.org/wiki/Luhn_algorithm
32
50
  def modified_luhn_sum
33
- sum = 0
34
-
35
- id_digits.reverse.each_slice(2) do |even, odd|
51
+ reversed_id_digits.each_slice(2).reduce(0) do |sum, (even, odd)|
36
52
  double_even = (even || 0) * 2
37
- sum += div10mod10(double_even) + div10mod10(odd || 0)
53
+ sum + div10mod10(double_even) + div10mod10(odd || 0)
38
54
  end
39
-
40
- sum
41
55
  end
42
56
 
43
- def id_digits
44
- @id_digits ||= identifier.each_char.map(&method(:char_to_digit))
57
+ def reversed_id_digits
58
+ identifier.each_char.map(&method(:char_to_digit)).reverse!
45
59
  end
46
60
  end
47
61
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'set'
4
+
5
+ module SecId
6
+ class FIGI < Base
7
+ ID_REGEX = /\A
8
+ (?<identifier>
9
+ (?<prefix>[B-DF-HJ-NP-TV-Z0-9]{2})
10
+ G
11
+ (?<random_part>[B-DF-HJ-NP-TV-Z0-9]{8}))
12
+ (?<check_digit>\d)?
13
+ \z/x
14
+
15
+ RESTRICTED_PREFIXES = Set.new %w[BS BM GG GB GH KY VG]
16
+
17
+ attr_reader :prefix, :random_part
18
+
19
+ def initialize(figi)
20
+ figi_parts = parse figi
21
+ @identifier = figi_parts[:identifier]
22
+ @prefix = figi_parts[:prefix]
23
+ @random_part = figi_parts[:random_part]
24
+ @check_digit = figi_parts[:check_digit]&.to_i
25
+ end
26
+
27
+ def valid_format?
28
+ !identifier.nil? && !RESTRICTED_PREFIXES.include?(prefix)
29
+ end
30
+
31
+ def calculate_check_digit
32
+ unless valid_format?
33
+ raise InvalidFormatError, "FIGI '#{full_number}' is invalid and check-digit cannot be calculated!"
34
+ end
35
+
36
+ mod10(modified_luhn_sum)
37
+ end
38
+
39
+ private
40
+
41
+ # https://en.wikipedia.org/wiki/Luhn_algorithm
42
+ def modified_luhn_sum
43
+ reversed_id_digits.each_with_index.reduce(0) do |sum, (digit, index)|
44
+ digit *= 2 if index.odd?
45
+ sum + digit.divmod(10).sum
46
+ end
47
+ end
48
+
49
+ def reversed_id_digits
50
+ identifier.each_char.map(&method(:char_to_digit)).reverse!
51
+ end
52
+ end
53
+ end
data/lib/sec_id/isin.rb CHANGED
@@ -10,6 +10,14 @@ module SecId
10
10
  (?<check_digit>\d)?
11
11
  \z/x
12
12
 
13
+ CGS_COUNTRY_CODES = Set.new(
14
+ %w[
15
+ US CA AG AI AN AR AS AW BB BL BM BO BQ BR BS BZ CL CO CR CW DM DO EC FM
16
+ GD GS GU GY HN HT JM KN KY LC MF MH MP MX NI PA PE PH PR PW PY SR SV SX
17
+ TT UM UY VC VE VG VI YT
18
+ ]
19
+ ).freeze
20
+
13
21
  attr_reader :country_code, :nsin
14
22
 
15
23
  def initialize(isin)
@@ -21,28 +29,37 @@ module SecId
21
29
  end
22
30
 
23
31
  def calculate_check_digit
24
- return mod10(luhn_sum) if valid_format?
32
+ unless valid_format?
33
+ raise InvalidFormatError, "ISIN '#{full_number}' is invalid and check-digit cannot be calculated!"
34
+ end
25
35
 
26
- raise InvalidFormatError, "ISIN '#{full_number}' is invalid and check-digit cannot be calculated!"
36
+ mod10(luhn_sum)
37
+ end
38
+
39
+ # CUSIP Global Services
40
+ def cgs?
41
+ CGS_COUNTRY_CODES.include?(country_code)
42
+ end
43
+
44
+ def to_cusip
45
+ raise InvalidFormatError, "'#{country_code}' is not a CGS country code!" unless cgs?
46
+
47
+ CUSIP.new(nsin)
27
48
  end
28
49
 
29
50
  private
30
51
 
31
52
  # https://en.wikipedia.org/wiki/Luhn_algorithm
32
53
  def luhn_sum
33
- sum = 0
34
-
35
- id_digits.reverse.each_slice(2) do |even, odd|
54
+ reversed_id_digits.each_slice(2).reduce(0) do |sum, (even, odd)|
36
55
  double_even = (even || 0) * 2
37
56
  double_even -= 9 if double_even > 9
38
- sum += double_even + (odd || 0)
57
+ sum + double_even + (odd || 0)
39
58
  end
40
-
41
- sum
42
59
  end
43
60
 
44
- def id_digits
45
- @id_digits ||= identifier.each_char.flat_map(&method(:char_to_digits))
61
+ def reversed_id_digits
62
+ identifier.each_char.flat_map(&method(:char_to_digits)).reverse!
46
63
  end
47
64
  end
48
65
  end
data/lib/sec_id/occ.rb ADDED
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+
5
+ module SecId
6
+ # https://en.wikipedia.org/wiki/Option_symbol#The_OCC_Option_Symbol
7
+ # https://web.archive.org/web/20120507220143/http://www.theocc.com/components/docs/initiatives/symbology/symbology_initiative_v1_8.pdf
8
+ class OCC
9
+ ID_REGEX = /\A
10
+ (?<initial>
11
+ (?=.{1,6})(?<underlying>\d?[A-Z]{1,5}\d?)(?<padding>[ ]*))
12
+ (?<date>\d{6})
13
+ (?<type>[CP])
14
+ (?<strike_mills>\d{8})
15
+ \z/x
16
+
17
+ attr_reader :full_symbol, :underlying, :date_str, :type
18
+
19
+ def initialize(symbol)
20
+ symbol_parts = parse symbol
21
+ @initial = symbol_parts[:initial]
22
+ @underlying = symbol_parts[:underlying]
23
+ @date_str = symbol_parts[:date]
24
+ @type = symbol_parts[:type]
25
+ @strike_mills = symbol_parts[:strike_mills]
26
+ end
27
+
28
+ def date
29
+ return @date if @date
30
+
31
+ @date = Date.strptime(date_str, '%y%m%d') if date_str
32
+ rescue Date::Error
33
+ nil
34
+ end
35
+ alias date_obj date
36
+
37
+ def strike
38
+ @strike ||= @strike_mills.to_i / 1000.0
39
+ end
40
+
41
+ def valid?
42
+ valid_format? && !date.nil?
43
+ end
44
+
45
+ def valid_format?
46
+ !@initial.nil?
47
+ end
48
+
49
+ def normalize!
50
+ raise InvalidFormatError, "OCC '#{full_symbol}' is invalid and cannot be normalized!" unless valid?
51
+
52
+ @strike_mills.length > 8 && @strike_mills = format('%08d', @strike_mills.to_i)
53
+ @initial.length < 6 && @initial = underlying.ljust(6, "\s")
54
+
55
+ @full_symbol = "#{@initial}#{date_str}#{type}#{@strike_mills}"
56
+ end
57
+
58
+ def to_s
59
+ full_symbol
60
+ end
61
+ alias to_str to_s
62
+
63
+ class << self
64
+ def valid?(id)
65
+ new(id).valid?
66
+ end
67
+
68
+ def valid_format?(id)
69
+ new(id).valid_format?
70
+ end
71
+
72
+ def normalize!(id)
73
+ new(id).normalize!
74
+ end
75
+
76
+ # rubocop:disable Metrics/MethodLength
77
+ def build(underlying:, date:, type:, strike:)
78
+ initial = underlying.to_s.ljust(6, "\s")
79
+ date = Date.parse(date.to_s) unless date.is_a?(Date)
80
+
81
+ case strike
82
+ when Numeric
83
+ strike_mills = format('%08d', (strike * 1000).to_i)
84
+ when /\A\d{8}\z/
85
+ strike_mills = strike
86
+ else
87
+ raise ArgumentError, 'Strike must be numeric or an 8-char string!'
88
+ end
89
+
90
+ symbol = "#{initial}#{date.strftime('%y%m%d')}#{type}#{strike_mills}"
91
+ new(symbol)
92
+ end
93
+ # rubocop:enable Metrics/MethodLength
94
+ end
95
+
96
+ private
97
+
98
+ def parse(symbol)
99
+ @full_symbol = symbol.to_s.strip
100
+ @full_symbol.match(ID_REGEX) || {}
101
+ end
102
+ end
103
+ end
data/lib/sec_id/sedol.rb CHANGED
@@ -17,9 +17,11 @@ module SecId
17
17
  end
18
18
 
19
19
  def calculate_check_digit
20
- return mod10(weighted_sum) if valid_format?
20
+ unless valid_format?
21
+ raise InvalidFormatError, "SEDOL '#{full_number}' is invalid and check-digit cannot be calculated!"
22
+ end
21
23
 
22
- raise InvalidFormatError, "SEDOL '#{full_number}' is invalid and check-digit cannot be calculated!"
24
+ mod10(weighted_sum)
23
25
  end
24
26
 
25
27
  private
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SecId
4
- VERSION = '4.0.0'
4
+ VERSION = '4.2.0'
5
5
  end
data/lib/sec_id.rb CHANGED
@@ -6,6 +6,9 @@ require 'sec_id/base'
6
6
  require 'sec_id/isin'
7
7
  require 'sec_id/cusip'
8
8
  require 'sec_id/sedol'
9
+ require 'sec_id/figi'
10
+ require 'sec_id/cik'
11
+ require 'sec_id/occ'
9
12
 
10
13
  module SecId
11
14
  Error = Class.new(StandardError)
data/sec_id.gemspec CHANGED
@@ -11,16 +11,14 @@ Gem::Specification.new do |spec|
11
11
  spec.email = ['leonid@svyatov.ru']
12
12
 
13
13
  spec.summary = 'Validate securities identification numbers with ease!'
14
- spec.description = %(#{spec.summary} Currently supported standards: ISIN, CUSIP, SEDOL.)
14
+ spec.description = %(#{spec.summary} Currently supported standards: ISIN, CUSIP, SEDOL, FIGI, CIK, OCC.)
15
15
  spec.homepage = 'https://github.com/svyatov/sec_id'
16
16
  spec.license = 'MIT'
17
17
 
18
18
  spec.required_ruby_version = '>= 3.1.0'
19
19
 
20
20
  spec.require_paths = ['lib']
21
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
22
- f.match(%r{^(test|spec|features)/})
23
- end
21
+ spec.files = Dir['lib/**/*.rb'] + %w[CHANGELOG.md LICENSE.txt README.md sec_id.gemspec]
24
22
 
25
23
  spec.metadata['rubygems_mfa_required'] = 'true'
26
24
  end
metadata CHANGED
@@ -1,39 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sec_id
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leonid Svyatov
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-07-09 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies: []
13
12
  description: 'Validate securities identification numbers with ease! Currently supported
14
- standards: ISIN, CUSIP, SEDOL.'
13
+ standards: ISIN, CUSIP, SEDOL, FIGI, CIK, OCC.'
15
14
  email:
16
15
  - leonid@svyatov.ru
17
16
  executables: []
18
17
  extensions: []
19
18
  extra_rdoc_files: []
20
19
  files:
21
- - ".github/dependabot.yml"
22
- - ".github/workflows/main.yml"
23
- - ".gitignore"
24
- - ".rspec"
25
- - ".rubocop.yml"
26
20
  - CHANGELOG.md
27
- - Gemfile
28
21
  - LICENSE.txt
29
22
  - README.md
30
- - Rakefile
31
- - bin/console
32
- - bin/setup
33
23
  - lib/sec_id.rb
34
24
  - lib/sec_id/base.rb
25
+ - lib/sec_id/cik.rb
35
26
  - lib/sec_id/cusip.rb
27
+ - lib/sec_id/figi.rb
36
28
  - lib/sec_id/isin.rb
29
+ - lib/sec_id/occ.rb
37
30
  - lib/sec_id/sedol.rb
38
31
  - lib/sec_id/version.rb
39
32
  - sec_id.gemspec
@@ -42,7 +35,6 @@ licenses:
42
35
  - MIT
43
36
  metadata:
44
37
  rubygems_mfa_required: 'true'
45
- post_install_message:
46
38
  rdoc_options: []
47
39
  require_paths:
48
40
  - lib
@@ -57,8 +49,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
57
49
  - !ruby/object:Gem::Version
58
50
  version: '0'
59
51
  requirements: []
60
- rubygems_version: 3.5.14
61
- signing_key:
52
+ rubygems_version: 4.0.3
62
53
  specification_version: 4
63
54
  summary: Validate securities identification numbers with ease!
64
55
  test_files: []
@@ -1,11 +0,0 @@
1
- # To get started with Dependabot version updates, you'll need to specify which
2
- # package ecosystems to update and where the package manifests are located.
3
- # Please see the documentation for all configuration options:
4
- # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
5
-
6
- version: 2
7
- updates:
8
- - package-ecosystem: "bundler" # See documentation for possible values
9
- directory: "/" # Location of package manifests
10
- schedule:
11
- interval: "weekly"
@@ -1,39 +0,0 @@
1
- name: CI
2
-
3
- concurrency:
4
- group: ${{ github.workflow }}-${{ github.ref }}
5
- cancel-in-progress: true
6
-
7
- on:
8
- push:
9
- branches: ["main"]
10
- pull_request:
11
- branches: ["main"]
12
-
13
- jobs:
14
- build:
15
- runs-on: ubuntu-latest
16
- name: Ruby ${{ matrix.ruby_version }}
17
- strategy:
18
- matrix:
19
- ruby_version: [ruby-head, '3.3', '3.2', '3.1']
20
-
21
- env:
22
- COVERAGE: true
23
- CC_TEST_REPORTER_ID: ${{ vars.CC_TEST_REPORTER_ID }}
24
-
25
- steps:
26
- - uses: actions/checkout@v4
27
-
28
- - uses: ruby/setup-ruby@v1
29
- with:
30
- ruby-version: ${{ matrix.ruby_version }}
31
- bundler-cache: true
32
- continue-on-error: ${{ matrix.ruby_version == 'ruby-head' }}
33
-
34
- - run: bundle exec rake
35
- continue-on-error: ${{ matrix.ruby_version == 'ruby-head' }}
36
-
37
- - uses: paambaati/codeclimate-action@v8.0.0
38
- # Only upload coverage for the latest Ruby
39
- if: ${{ matrix.ruby_version == '3.3' }}
data/.gitignore DELETED
@@ -1,12 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
-
11
- # rspec failure tracking
12
- .rspec_status
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
data/.rubocop.yml DELETED
@@ -1,39 +0,0 @@
1
- require:
2
- - rubocop-rspec
3
-
4
- AllCops:
5
- TargetRubyVersion: 3.1
6
- DisplayCopNames: true
7
- DisplayStyleGuide: true
8
- ExtraDetails: true
9
- SuggestExtensions: false
10
- NewCops: enable
11
-
12
- Layout/LineLength:
13
- Max: 120
14
-
15
- Style/Documentation:
16
- Enabled: false
17
-
18
- Style/HashEachMethods:
19
- Enabled: true
20
-
21
- Style/HashTransformKeys:
22
- Enabled: true
23
-
24
- Style/HashTransformValues:
25
- Enabled: true
26
-
27
- Metrics/BlockLength:
28
- Exclude:
29
- - 'spec/**/*'
30
-
31
- Lint/MissingSuper:
32
- AllowedParentClasses:
33
- - Base
34
-
35
- RSpec/MultipleExpectations:
36
- Max: 5
37
-
38
- RSpec/ExampleLength:
39
- Max: 10
data/Gemfile DELETED
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source 'https://rubygems.org'
4
-
5
- git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
-
7
- # Specify your gem's dependencies in sec_id.gemspec
8
- gemspec
9
-
10
- # Specify your gem's development dependencies below
11
- gem 'rake', '>= 13'
12
-
13
- gem 'rspec', '~> 3.9'
14
- gem 'rspec_junit_formatter'
15
-
16
- gem 'rubocop', '~> 1.64'
17
- gem 'rubocop-rspec', '~> 3.0'
18
-
19
- gem 'simplecov', '~> 0.22', require: false
20
- gem 'simplecov_json_formatter', require: false
data/Rakefile DELETED
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
5
- require 'rubocop/rake_task'
6
-
7
- RSpec::Core::RakeTask.new(:spec)
8
-
9
- RuboCop::RakeTask.new do |task|
10
- task.requires << 'rubocop-rspec'
11
- end
12
-
13
- task default: %i[rubocop spec]
data/bin/console DELETED
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'bundler/setup'
5
- require 'sec_id'
6
-
7
- # You can add fixtures and/or initialization code here to make experimenting
8
- # with your gem easier. You can also use a different console, if you like.
9
-
10
- # (If you use this, don't forget to add pry to your Gemfile!)
11
- # require "pry"
12
- # Pry.start
13
-
14
- require 'irb'
15
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here