business 2.3.0 → 3.0.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: b251f5b883fe268c312d1d85b129f20244ca8729a427784f8e5c0b87681ff646
4
- data.tar.gz: '05779798d8c21739f31a604b6e46c063f62189b0a7e0a1064e674c1c5fbe9278'
3
+ metadata.gz: c7aab6453e38130641098c102e0b05f1d5c40cd957710c80f3b53f4670175ce6
4
+ data.tar.gz: 2ae585a9a460e340db0821c755a787795e7504914af8febb247c451beb8f37f2
5
5
  SHA512:
6
- metadata.gz: 7d117a929340ee63c4978d6a0869e3e99fb585c002ac609a9d12d047aee7a96f75fc04f7a03bda894591348d23a3d3f43a32c1e33366d2bdb77d2ce9481c7e21
7
- data.tar.gz: b2b9acd515306f0460e3e48aa89a0c0296b8bd9eebf9a4b51a4a3731fd94b7096ca521fd50db9ace4ba97bbcb7bb24e17cc6d38c488e6855bc8b34c1d0cd982f
6
+ metadata.gz: ffe309242e862845535efb526d3f4ec95852bd685f026c97fdac4bcd4eec88051e47481f5d1354b98a9f34af47dd4858b417fe173b6f9498b52c226a6c491bac
7
+ data.tar.gz: 322e9a49e3fcec9078b6c5e1d78eb6ea0d4abc0bc47f95550cbb6069d72715c00d8c5868279bfdfc5e69776e7e85cea03fc3994441522ff7a84abb82411e867f
@@ -0,0 +1,36 @@
1
+ name: tests
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - "master"
7
+ pull_request:
8
+
9
+ jobs:
10
+ rubocop:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v7
14
+ - name: Set up Ruby
15
+ uses: ruby/setup-ruby@v1
16
+ with:
17
+ bundler-cache: true
18
+ # Maintain consistency with the TargetRubyVersion in .rubocop.yml
19
+ ruby-version: "3.3"
20
+ - name: Run rubocop
21
+ run: bundle exec rubocop --parallel --extra-details --display-style-guide
22
+
23
+ tests:
24
+ strategy:
25
+ matrix:
26
+ ruby-version: ["3.3", "3.4", "4.0"]
27
+ runs-on: ubuntu-latest
28
+ steps:
29
+ - uses: actions/checkout@v7
30
+ - name: Set up Ruby
31
+ uses: ruby/setup-ruby@v1
32
+ with:
33
+ bundler-cache: true
34
+ ruby-version: "${{ matrix.ruby-version }}"
35
+ - name: Run tests
36
+ run: bundle exec rspec
data/.rubocop.yml CHANGED
@@ -1,6 +1,10 @@
1
1
  inherit_gem:
2
2
  gc_ruboconfig: rubocop.yml
3
3
 
4
+ AllCops:
5
+ TargetRubyVersion: 3.3
6
+ NewCops: enable
7
+
4
8
  RSpec/NestedGroups:
5
9
  Exclude:
6
10
  - spec/business/calendar_spec.rb
@@ -12,5 +16,5 @@ Naming/AccessorMethodName:
12
16
  Gemspec/RequiredRubyVersion:
13
17
  Enabled: false
14
18
 
15
- Style/HashSyntax:
19
+ RSpec/IndexedLet:
16
20
  Enabled: false
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.1.0
1
+ 4.0.6
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## Upcoming
2
2
 
3
+ # 3.0.0 - Sept 29, 2026
4
+
5
+ - Removed support for Ruby 3.2 and earlier
6
+ - Prevent path traversal when loading calendar files #331
7
+
3
8
  ## 2.3.0 - Jan 31, 2022
4
9
 
5
10
  - Added permitted classes to YAML's `safe_load` #112 - thanks @attack
data/COMPATIBILITY.md ADDED
@@ -0,0 +1,21 @@
1
+ # Compatibility
2
+
3
+ ## v2.0.0 breaking changes
4
+
5
+ We have removed the bundled calendars as of version 2.0.0, if you need the calendars that were included:
6
+
7
+ - Download the calendars you wish to use from [v1.18.0](https://github.com/gocardless/business/tree/b12c186ca6fd4ffdac85175742ff7e4d0a705ef4/lib/business/data)
8
+ - Place them in a suitable directory in your project, typically `lib/calendars`
9
+ - Add this directory path to your instance of `Business::Calendar` using the `load_paths` method.dd the directory to where you placed the yml files before you load the calendar
10
+
11
+ ```ruby
12
+ Business::Calendar.load_paths = ["lib/calendars"] # your_project/lib/calendars/ contains bacs.yml
13
+ Business::Calendar.load("bacs")
14
+ ```
15
+
16
+ If you wish to stay on the last version that contained bundled calendars, pin `business` to `v1.18.0`
17
+
18
+ ```ruby
19
+ # Gemfile
20
+ gem "business", "v1.18.0"
21
+ ```
data/Gemfile CHANGED
@@ -3,3 +3,9 @@
3
3
  source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
+
7
+ group :test, :development do
8
+ gem "gc_ruboconfig", "~> 6"
9
+ gem "rspec", "~> 3.4"
10
+ gem "rubocop", "~> 1.91"
11
+ end
data/README.md CHANGED
@@ -1,39 +1,18 @@
1
1
  # Business
2
2
 
3
3
  [![Gem version](https://badge.fury.io/rb/business.svg)](http://badge.fury.io/rb/business)
4
- [![CircleCI](https://circleci.com/gh/gocardless/business.svg?style=svg)](https://circleci.com/gh/gocardless/business)
5
4
 
6
5
  Date calculations based on business calendars.
7
6
 
8
- - [v2.0.0 breaking changes](#v200-breaking-changes)
9
7
  - [Getting Started](#getting-started)
10
8
  - [Creating a calendar](#creating-a-calendar)
11
9
  - [Using a calendar file](#use-a-calendar-file)
12
10
  - [Checking for business days](#checking-for-business-days)
13
11
  - [Business day arithmetic](#business-day-arithmetic)
14
12
  - [But other libraries already do this](#but-other-libraries-already-do-this)
13
+ - [Compatibility](#compatibility)
15
14
  - [License & Contributing](#license--contributing)
16
15
 
17
- ## v2.0.0 breaking changes
18
-
19
- We have removed the bundled calendars as of version 2.0.0, if you need the calendars that were included:
20
-
21
- - Download the calendars you wish to use from [v1.18.0](https://github.com/gocardless/business/tree/b12c186ca6fd4ffdac85175742ff7e4d0a705ef4/lib/business/data)
22
- - Place them in a suitable directory in your project, typically `lib/calendars`
23
- - Add this directory path to your instance of `Business::Calendar` using the `load_paths` method.dd the directory to where you placed the yml files before you load the calendar
24
-
25
- ```ruby
26
- Business::Calendar.load_paths = ["lib/calendars"] # your_project/lib/calendars/ contains bacs.yml
27
- Business::Calendar.load("bacs")
28
- ```
29
-
30
- If you wish to stay on the last version that contained bundled calendars, pin `business` to `v1.18.0`
31
-
32
- ```ruby
33
- # Gemfile
34
- gem "business", "v1.18.0"
35
- ```
36
-
37
16
  ## Getting started
38
17
 
39
18
  To install business, simply:
@@ -45,7 +24,7 @@ gem install business
45
24
  If you are using a Gemfile:
46
25
 
47
26
  ```ruby
48
- gem "business", "~> 2.0"
27
+ gem "business", "~> 3.0"
49
28
  ```
50
29
 
51
30
  ### Creating a calendar
@@ -189,6 +168,12 @@ Secondly, business_time supports calculations on times as well as dates. For our
189
168
 
190
169
  <p align="center"><img src="http://3.bp.blogspot.com/-aq4iOz2OZzs/Ty8xaQwMhtI/AAAAAAAABrM/-vn4tcRA9-4/s1600/daily-morning-awesomeness-243.jpeg" alt="I'm late for business" width="250"/></p>
191
170
 
171
+ # Compatibility
172
+
173
+ ## v2.0.0 Breaking Changes
174
+
175
+ - See [COMPATIBILITY.md](COMPATIBILITY.md#v200-breaking-changes)
176
+
192
177
  ## License & Contributing
193
178
  - business is available as open source under the terms of the [MIT License](LICENSE).
194
179
  - Bug reports and pull requests are welcome on GitHub at https://github.com/gocardless/business.
data/business.gemspec CHANGED
@@ -8,7 +8,7 @@ require "business/version"
8
8
  Gem::Specification.new do |spec|
9
9
  spec.name = "business"
10
10
  spec.version = Business::VERSION
11
- spec.authors = ["Harry Marr"]
11
+ spec.authors = ["GoCcardless"]
12
12
  spec.email = ["developers@gocardless.com"]
13
13
  spec.summary = "Date calculations based on business calendars"
14
14
  spec.description = "Date calculations based on business calendars"
@@ -16,12 +16,7 @@ Gem::Specification.new do |spec|
16
16
  spec.licenses = ["MIT"]
17
17
 
18
18
  spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
19
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
19
  spec.require_paths = ["lib"]
22
20
 
23
- spec.add_development_dependency "gc_ruboconfig", "~> 2.31.0"
24
- spec.add_development_dependency "rspec", "~> 3.1"
25
- spec.add_development_dependency "rspec_junit_formatter", "~> 0.5.1"
26
- spec.add_development_dependency "rubocop", "~> 1.25.0"
21
+ spec.metadata["rubygems_mfa_required"] = "true"
27
22
  end
@@ -8,6 +8,11 @@ module Business
8
8
  class Calendar
9
9
  VALID_KEYS = %w[holidays working_days extra_working_dates].freeze
10
10
 
11
+ # Calendar names are interpolated into a filesystem path, so restrict them to
12
+ # plain identifiers: anything containing path separators, "..", or an absolute
13
+ # path would otherwise load a file from outside the configured load_paths.
14
+ CALENDAR_NAME_FORMAT = /\A[a-zA-Z0-9_-]+\z/
15
+
11
16
  class << self
12
17
  attr_accessor :load_paths
13
18
  end
@@ -38,7 +43,7 @@ module Business
38
43
  if path.is_a?(Hash)
39
44
  break path[calendar_name] if path[calendar_name]
40
45
  else
41
- calendar_path = Pathname.new(path).join("#{calendar_name}.yml")
46
+ calendar_path = calendar_path_for(path, calendar_name)
42
47
  next unless calendar_path.exist?
43
48
 
44
49
  break YAML.safe_load(calendar_path.read, permitted_classes: [Date])
@@ -46,6 +51,17 @@ module Business
46
51
  end
47
52
  end
48
53
 
54
+ # Only applied to directory load_paths; hash load_paths are a plain key
55
+ # lookup and cannot escape anywhere, so their keys stay unrestricted.
56
+ def self.calendar_path_for(directory, calendar_name)
57
+ unless calendar_name.to_s.match?(CALENDAR_NAME_FORMAT)
58
+ raise ArgumentError, "invalid calendar name: #{calendar_name.inspect}"
59
+ end
60
+
61
+ Pathname.new(directory).join("#{calendar_name}.yml")
62
+ end
63
+ private_class_method :calendar_path_for
64
+
49
65
  @lock = Mutex.new
50
66
  def self.load_cached(calendar)
51
67
  @lock.synchronize do
@@ -65,7 +81,7 @@ module Business
65
81
  set_working_days(working_days)
66
82
  set_holidays(holidays)
67
83
 
68
- unless (@holidays & @extra_working_dates).none?
84
+ if @holidays.intersect?(@extra_working_dates)
69
85
  raise ArgumentError, "Holidays cannot be extra working dates"
70
86
  end
71
87
  end
@@ -129,10 +145,7 @@ module Business
129
145
  def add_business_days(date, delta)
130
146
  date = roll_forward(date)
131
147
  delta.times do
132
- loop do
133
- date += day_interval_for(date)
134
- break date if business_day?(date)
135
- end
148
+ date = next_business_day(date)
136
149
  end
137
150
  date
138
151
  end
@@ -145,10 +158,7 @@ module Business
145
158
  def subtract_business_days(date, delta)
146
159
  date = roll_backward(date)
147
160
  delta.times do
148
- loop do
149
- date -= day_interval_for(date)
150
- break date if business_day?(date)
151
- end
161
+ date = previous_business_day(date)
152
162
  end
153
163
  date
154
164
  end
@@ -184,7 +194,7 @@ module Business
184
194
  in_range && on_biz_day
185
195
  end
186
196
 
187
- remaining_range = (date2 - remaining_days...date2)
197
+ remaining_range = ((date2 - remaining_days)...date2)
188
198
  # Loop through each day in remaining_range and count if a business day
189
199
  num_biz_days + remaining_range.count { |a| business_day?(a) }
190
200
  end
@@ -203,7 +213,7 @@ module Business
203
213
  extra_working_dates_names = @extra_working_dates.map do |d|
204
214
  d.strftime("%a").downcase
205
215
  end
206
- return if (extra_working_dates_names & @working_days).none?
216
+ return if !extra_working_dates_names.intersect?(@working_days)
207
217
 
208
218
  raise ArgumentError, "Extra working dates cannot be on working days"
209
219
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Business
4
- VERSION = "2.3.0"
4
+ VERSION = "3.0.0"
5
5
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "business/calendar"
4
4
  require "time"
5
+ require "fileutils"
5
6
 
6
7
  RSpec.configure do |config|
7
8
  config.mock_with(:rspec) { |mocks| mocks.verify_partial_doubles = true }
@@ -57,6 +58,71 @@ RSpec.describe Business::Calendar do
57
58
  specify { expect { load_calendar }.to raise_error(/No such calendar/) }
58
59
  end
59
60
 
61
+ context "when given a calendar name that escapes the load path" do
62
+ before do
63
+ outside = File.join(File.dirname(__FILE__), "../fixtures")
64
+ FileUtils.mkdir_p(File.join(outside, "outside"))
65
+ File.write(
66
+ File.join(outside, "outside", "escaped.yml"),
67
+ { "working_days" => ["monday"] }.to_yaml,
68
+ )
69
+ end
70
+
71
+ after do
72
+ FileUtils.rm_rf(File.join(File.dirname(__FILE__), "../fixtures", "outside"))
73
+ end
74
+
75
+ context "with a relative traversal" do
76
+ let(:calendar) { "../outside/escaped" }
77
+
78
+ specify do
79
+ expect { load_calendar }.
80
+ to raise_error(ArgumentError, /invalid calendar name/)
81
+ end
82
+ end
83
+
84
+ context "with an absolute path" do
85
+ let(:calendar) do
86
+ File.join(File.dirname(__FILE__), "../fixtures", "outside", "escaped")
87
+ end
88
+
89
+ specify do
90
+ expect { load_calendar }.
91
+ to raise_error(ArgumentError, /invalid calendar name/)
92
+ end
93
+ end
94
+
95
+ context "with a bare path separator" do
96
+ let(:calendar) { "outside/escaped" }
97
+
98
+ specify do
99
+ expect { load_calendar }.
100
+ to raise_error(ArgumentError, /invalid calendar name/)
101
+ end
102
+ end
103
+
104
+ context "with a name that is only dots" do
105
+ let(:calendar) { ".." }
106
+
107
+ specify do
108
+ expect { load_calendar }.
109
+ to raise_error(ArgumentError, /invalid calendar name/)
110
+ end
111
+ end
112
+
113
+ context "when the escaping name is a key in a hash load path" do
114
+ before do
115
+ described_class.load_paths = [{ "../outside/escaped" => dummy_calendar }]
116
+ end
117
+
118
+ let(:calendar) { "../outside/escaped" }
119
+
120
+ it "still resolves, since hash lookups touch no filesystem" do
121
+ expect(load_calendar).to be_a described_class
122
+ end
123
+ end
124
+ end
125
+
60
126
  context "when given a calendar that has invalid keys" do
61
127
  let(:calendar) { "invalid-keys" }
62
128
 
@@ -340,7 +406,7 @@ RSpec.describe Business::Calendar do
340
406
  context "followed by another non-business day" do
341
407
  let(:date) { date_class.parse("Saturday 5th Jan, 2013") }
342
408
 
343
- it { is_expected.to eq(date + 2 * day_interval) }
409
+ it { is_expected.to eq(date + (2 * day_interval)) }
344
410
  end
345
411
  end
346
412
  end
@@ -368,7 +434,7 @@ RSpec.describe Business::Calendar do
368
434
  context "preceeded by another non-business day" do
369
435
  let(:date) { date_class.parse("Sunday 6th Jan, 2013") }
370
436
 
371
- it { is_expected.to eq(date - 2 * day_interval) }
437
+ it { is_expected.to eq(date - (2 * day_interval)) }
372
438
  end
373
439
  end
374
440
  end
@@ -396,7 +462,7 @@ RSpec.describe Business::Calendar do
396
462
  context "followed by another non-business day" do
397
463
  let(:date) { date_class.parse("Saturday 5th Jan, 2013") }
398
464
 
399
- it { is_expected.to eq(date + 2 * day_interval) }
465
+ it { is_expected.to eq(date + (2 * day_interval)) }
400
466
  end
401
467
  end
402
468
  end
@@ -424,7 +490,7 @@ RSpec.describe Business::Calendar do
424
490
  context "preceeded by another non-business day" do
425
491
  let(:date) { date_class.parse("Sunday 6th Jan, 2013") }
426
492
 
427
- it { is_expected.to eq(date - 2 * day_interval) }
493
+ it { is_expected.to eq(date - (2 * day_interval)) }
428
494
  end
429
495
  end
430
496
  end
@@ -444,33 +510,33 @@ RSpec.describe Business::Calendar do
444
510
  context "and a period that includes only business days" do
445
511
  let(:date) { date_class.parse("Wednesday 2nd Jan, 2013") }
446
512
 
447
- it { is_expected.to eq(date + delta * day_interval) }
513
+ it { is_expected.to eq(date + (delta * day_interval)) }
448
514
  end
449
515
 
450
516
  context "and a period that includes a weekend" do
451
517
  let(:date) { date_class.parse("Friday 4th Jan, 2013") }
452
518
 
453
- it { is_expected.to eq(date + (delta + 2) * day_interval) }
519
+ it { is_expected.to eq(date + ((delta + 2) * day_interval)) }
454
520
  end
455
521
 
456
522
  context "and a period that includes a working date weekend" do
457
523
  let(:extra_working_dates) { ["Sunday 6th Jan, 2013"] }
458
524
  let(:date) { date_class.parse("Friday 4th Jan, 2013") }
459
525
 
460
- it { is_expected.to eq(date + (delta + 1) * day_interval) }
526
+ it { is_expected.to eq(date + ((delta + 1) * day_interval)) }
461
527
  end
462
528
 
463
529
  context "and a period that includes a holiday day" do
464
530
  let(:date) { date_class.parse("Monday 31st Dec, 2012") }
465
531
 
466
- it { is_expected.to eq(date + (delta + 1) * day_interval) }
532
+ it { is_expected.to eq(date + ((delta + 1) * day_interval)) }
467
533
  end
468
534
  end
469
535
 
470
536
  context "given a non-business day" do
471
537
  let(:date) { date_class.parse("Tuesday 1st Jan, 2013") }
472
538
 
473
- it { is_expected.to eq(date + (delta + 1) * day_interval) }
539
+ it { is_expected.to eq(date + ((delta + 1) * day_interval)) }
474
540
  end
475
541
  end
476
542
 
@@ -489,33 +555,33 @@ RSpec.describe Business::Calendar do
489
555
  context "and a period that includes only business days" do
490
556
  let(:date) { date_class.parse("Wednesday 2nd Jan, 2013") }
491
557
 
492
- it { is_expected.to eq(date - delta * day_interval) }
558
+ it { is_expected.to eq(date - (delta * day_interval)) }
493
559
  end
494
560
 
495
561
  context "and a period that includes a weekend" do
496
562
  let(:date) { date_class.parse("Monday 31st Dec, 2012") }
497
563
 
498
- it { is_expected.to eq(date - (delta + 2) * day_interval) }
564
+ it { is_expected.to eq(date - ((delta + 2) * day_interval)) }
499
565
  end
500
566
 
501
567
  context "and a period that includes a working date weekend" do
502
568
  let(:extra_working_dates) { ["Saturday 29th Dec, 2012"] }
503
569
  let(:date) { date_class.parse("Monday 31st Dec, 2012") }
504
570
 
505
- it { is_expected.to eq(date - (delta + 1) * day_interval) }
571
+ it { is_expected.to eq(date - ((delta + 1) * day_interval)) }
506
572
  end
507
573
 
508
574
  context "and a period that includes a holiday day" do
509
575
  let(:date) { date_class.parse("Friday 4th Jan, 2013") }
510
576
 
511
- it { is_expected.to eq(date - (delta + 1) * day_interval) }
577
+ it { is_expected.to eq(date - ((delta + 1) * day_interval)) }
512
578
  end
513
579
  end
514
580
 
515
581
  context "given a non-business day" do
516
582
  let(:date) { date_class.parse("Thursday 3rd Jan, 2013") }
517
583
 
518
- it { is_expected.to eq(date - (delta + 1) * day_interval) }
584
+ it { is_expected.to eq(date - ((delta + 1) * day_interval)) }
519
585
  end
520
586
  end
521
587
 
metadata CHANGED
@@ -1,71 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: business
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
- - Harry Marr
8
- autorequire:
7
+ - GoCcardless
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2022-01-31 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: gc_ruboconfig
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: 2.31.0
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: 2.31.0
27
- - !ruby/object:Gem::Dependency
28
- name: rspec
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '3.1'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '3.1'
41
- - !ruby/object:Gem::Dependency
42
- name: rspec_junit_formatter
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: 0.5.1
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: 0.5.1
55
- - !ruby/object:Gem::Dependency
56
- name: rubocop
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: 1.25.0
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: 1.25.0
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
69
12
  description: Date calculations based on business calendars
70
13
  email:
71
14
  - developers@gocardless.com
@@ -73,12 +16,13 @@ executables: []
73
16
  extensions: []
74
17
  extra_rdoc_files: []
75
18
  files:
76
- - ".circleci/config.yml"
77
19
  - ".github/dependabot.yml"
20
+ - ".github/workflows/tests.yml"
78
21
  - ".gitignore"
79
22
  - ".rubocop.yml"
80
23
  - ".ruby-version"
81
24
  - CHANGELOG.md
25
+ - COMPATIBILITY.md
82
26
  - Gemfile
83
27
  - LICENSE
84
28
  - README.md
@@ -93,8 +37,8 @@ files:
93
37
  homepage: https://github.com/gocardless/business
94
38
  licenses:
95
39
  - MIT
96
- metadata: {}
97
- post_install_message:
40
+ metadata:
41
+ rubygems_mfa_required: 'true'
98
42
  rdoc_options: []
99
43
  require_paths:
100
44
  - lib
@@ -109,12 +53,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
53
  - !ruby/object:Gem::Version
110
54
  version: '0'
111
55
  requirements: []
112
- rubygems_version: 3.3.3
113
- signing_key:
56
+ rubygems_version: 4.0.16
114
57
  specification_version: 4
115
58
  summary: Date calculations based on business calendars
116
- test_files:
117
- - spec/business/calendar_spec.rb
118
- - spec/fixtures/calendars/bacs.yml
119
- - spec/fixtures/calendars/ecb.yml
120
- - spec/fixtures/calendars/invalid-keys.yml
59
+ test_files: []
data/.circleci/config.yml DELETED
@@ -1,37 +0,0 @@
1
- version: 2.1
2
-
3
- jobs:
4
- test:
5
- docker:
6
- - image: cimg/ruby:<< parameters.ruby-version >>
7
- parameters:
8
- ruby-version:
9
- type: string
10
- steps:
11
- - checkout
12
- - restore_cache:
13
- keys:
14
- - bundle-v1-<< parameters.ruby-version >>-{{ checksum "business.gemspec" }}
15
- - bundle-v1-<< parameters.ruby-version >>-
16
- - run:
17
- name: Install dependencies
18
- command: bundle install --clean --no-cache --path vendor/bundle --jobs=4 --retry=3
19
- - save_cache:
20
- key: bundle-v1-<< parameters.ruby-version >>-{{ checksum "business.gemspec" }}
21
- paths:
22
- - vendor/bundle
23
- - run:
24
- name: Run tests
25
- command: bundle exec rspec
26
- - run:
27
- name: Run rubocop
28
- command: bundle exec rubocop --parallel --extra-details --display-style-guide
29
-
30
- workflows:
31
- default:
32
- jobs:
33
- - test:
34
- name: Ruby << matrix.ruby-version >>
35
- matrix:
36
- parameters:
37
- ruby-version: ["2.6.7", "2.7.3", "3.0.1", "3.1.0"]