diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 30fb44f..d8aea85 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,13 +7,26 @@ on: pull_request: jobs: + rubocop: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + # Maintain consistency with the TargetRubyVersion in .rubocop.yml + ruby-version: "3.3" + - name: Run rubocop + run: bundle exec rubocop --parallel --extra-details --display-style-guide + tests: strategy: matrix: - ruby-version: ["2.6", "2.7", "3.0", "3.1", "3.2"] + ruby-version: ["3.3", "3.4", "4.0"] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v7 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: @@ -21,5 +34,3 @@ jobs: ruby-version: "${{ matrix.ruby-version }}" - name: Run tests run: bundle exec rspec - - name: Run rubocop - run: bundle exec rubocop --parallel --extra-details --display-style-guide diff --git a/.rubocop.yml b/.rubocop.yml index 8c6c390..3bf7dac 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,6 +1,10 @@ inherit_gem: gc_ruboconfig: rubocop.yml +AllCops: + TargetRubyVersion: 3.3 + NewCops: enable + RSpec/NestedGroups: Exclude: - spec/business/calendar_spec.rb @@ -12,5 +16,5 @@ Naming/AccessorMethodName: Gemspec/RequiredRubyVersion: Enabled: false -Style/HashSyntax: +RSpec/IndexedLet: Enabled: false diff --git a/.ruby-version b/.ruby-version index fd2a018..d13e837 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.1.0 +4.0.6 diff --git a/CHANGELOG.md b/CHANGELOG.md index 695f52a..8e902b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ ## Upcoming +# 3.0.0 - Sept 29, 2026 + +- Removed support for Ruby 3.2 and earlier +- Prevent path traversal when loading calendar files #331 + ## 2.3.0 - Jan 31, 2022 - Added permitted classes to YAML's `safe_load` #112 - thanks @attack diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md new file mode 100644 index 0000000..c6435b0 --- /dev/null +++ b/COMPATIBILITY.md @@ -0,0 +1,21 @@ +# Compatibility + +## v2.0.0 breaking changes + +We have removed the bundled calendars as of version 2.0.0, if you need the calendars that were included: + +- Download the calendars you wish to use from [v1.18.0](https://github.com/gocardless/business/tree/b12c186ca6fd4ffdac85175742ff7e4d0a705ef4/lib/business/data) +- Place them in a suitable directory in your project, typically `lib/calendars` +- 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 + +```ruby +Business::Calendar.load_paths = ["lib/calendars"] # your_project/lib/calendars/ contains bacs.yml +Business::Calendar.load("bacs") +``` + +If you wish to stay on the last version that contained bundled calendars, pin `business` to `v1.18.0` + +```ruby +# Gemfile +gem "business", "v1.18.0" +``` diff --git a/Gemfile b/Gemfile index 7f4f5e9..cba5844 100644 --- a/Gemfile +++ b/Gemfile @@ -3,3 +3,9 @@ source 'https://rubygems.org' gemspec + +group :test, :development do + gem "gc_ruboconfig", "~> 6" + gem "rspec", "~> 3.4" + gem "rubocop", "~> 1.91" +end diff --git a/README.md b/README.md index 9eb48ac..a6e275c 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,18 @@ # Business [![Gem version](https://badge.fury.io/rb/business.svg)](http://badge.fury.io/rb/business) -[![CircleCI](https://circleci.com/gh/gocardless/business.svg?style=svg)](https://circleci.com/gh/gocardless/business) Date calculations based on business calendars. -- [v2.0.0 breaking changes](#v200-breaking-changes) - [Getting Started](#getting-started) - [Creating a calendar](#creating-a-calendar) - [Using a calendar file](#use-a-calendar-file) - [Checking for business days](#checking-for-business-days) - [Business day arithmetic](#business-day-arithmetic) - [But other libraries already do this](#but-other-libraries-already-do-this) +- [Compatibility](#compatibility) - [License & Contributing](#license--contributing) -## v2.0.0 breaking changes - -We have removed the bundled calendars as of version 2.0.0, if you need the calendars that were included: - -- Download the calendars you wish to use from [v1.18.0](https://github.com/gocardless/business/tree/b12c186ca6fd4ffdac85175742ff7e4d0a705ef4/lib/business/data) -- Place them in a suitable directory in your project, typically `lib/calendars` -- 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 - -```ruby -Business::Calendar.load_paths = ["lib/calendars"] # your_project/lib/calendars/ contains bacs.yml -Business::Calendar.load("bacs") -``` - -If you wish to stay on the last version that contained bundled calendars, pin `business` to `v1.18.0` - -```ruby -# Gemfile -gem "business", "v1.18.0" -``` - ## Getting started To install business, simply: @@ -45,7 +24,7 @@ gem install business If you are using a Gemfile: ```ruby -gem "business", "~> 2.0" +gem "business", "~> 3.0" ``` ### Creating a calendar @@ -189,6 +168,12 @@ Secondly, business_time supports calculations on times as well as dates. For our

I'm late for business

+# Compatibility + +## v2.0.0 Breaking Changes + +- See [COMPATIBILITY.md](COMPATIBILITY.md#v200-breaking-changes) + ## License & Contributing - business is available as open source under the terms of the [MIT License](LICENSE). - Bug reports and pull requests are welcome on GitHub at https://github.com/gocardless/business. diff --git a/business.gemspec b/business.gemspec index 484af62..4398023 100644 --- a/business.gemspec +++ b/business.gemspec @@ -8,7 +8,7 @@ require "business/version" Gem::Specification.new do |spec| spec.name = "business" spec.version = Business::VERSION - spec.authors = ["Harry Marr"] + spec.authors = ["GoCcardless"] spec.email = ["developers@gocardless.com"] spec.summary = "Date calculations based on business calendars" spec.description = "Date calculations based on business calendars" @@ -18,8 +18,5 @@ Gem::Specification.new do |spec| spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR) spec.require_paths = ["lib"] - spec.add_development_dependency "gc_ruboconfig", "~> 3.6.0" - spec.add_development_dependency "rspec", "~> 3.1" - spec.add_development_dependency "rubocop", "~> 1.48.1" spec.metadata["rubygems_mfa_required"] = "true" end diff --git a/lib/business/calendar.rb b/lib/business/calendar.rb index bba6989..79e7a7c 100644 --- a/lib/business/calendar.rb +++ b/lib/business/calendar.rb @@ -65,7 +65,7 @@ def initialize(name: nil, extra_working_dates: nil, working_days: nil, holidays: set_working_days(working_days) set_holidays(holidays) - unless (@holidays & @extra_working_dates).none? + if @holidays.intersect?(@extra_working_dates) raise ArgumentError, "Holidays cannot be extra working dates" end end @@ -178,7 +178,7 @@ def business_days_between(date1, date2) in_range && on_biz_day end - remaining_range = (date2 - remaining_days...date2) + remaining_range = ((date2 - remaining_days)...date2) # Loop through each day in remaining_range and count if a business day num_biz_days + remaining_range.count { |a| business_day?(a) } end @@ -197,7 +197,7 @@ def set_working_days(working_days) extra_working_dates_names = @extra_working_dates.map do |d| d.strftime("%a").downcase end - return if (extra_working_dates_names & @working_days).none? + return if !extra_working_dates_names.intersect?(@working_days) raise ArgumentError, "Extra working dates cannot be on working days" end diff --git a/lib/business/version.rb b/lib/business/version.rb index 33758e3..5bb2f44 100644 --- a/lib/business/version.rb +++ b/lib/business/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Business - VERSION = "2.3.0" + VERSION = "3.0.0" end