From 703c0a057bc78d19485a2cc772c3f503aa80efde Mon Sep 17 00:00:00 2001 From: Stephen Hulme Date: Thu, 30 Apr 2026 09:54:24 +0100 Subject: [PATCH 1/8] docs: update changelog for 1.0.1 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 456086b..17f6ea1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ Keeps track of notable changes. Please remember to add new behaviours to the Unreleased section to make new releases easy. Follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.0.1] + +- [Removed] Remove support for Ruby 3.0 - 3.2 +- [Changed] Update Psych dependency to explicitly use unsafe loading + ## [1.0.0] - [Changed] Version numbering to follow [Ruby Gem versioning guidelines](https://guides.rubygems.org/patterns/) From ab7a241deee8b374fdd448275206a32779fd19cf Mon Sep 17 00:00:00 2001 From: Stephen Hulme Date: Wed, 29 Apr 2026 23:24:43 +0100 Subject: [PATCH 2/8] docs: add version comptibility table --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c74d5f7..d63cb61 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ If using with Rails: | Rails Version | RecordLoader Version | | ------------- | -------------------- | +| 7.x and above | 1.x | | 6.x and below | 0.3.0\*, 1.0.0 | _\* Pin psych < 4_ From ad0f38ae3181bd3a5a1e1f48dba0599335b16ca7 Mon Sep 17 00:00:00 2001 From: Stephen Hulme Date: Thu, 30 Apr 2026 10:15:07 +0100 Subject: [PATCH 3/8] build: update minimum ruby version to 3.3 --- .github/workflows/ruby_test.yml | 2 +- .rubocop.yml | 2 +- .ruby-version | 2 +- README.md | 2 +- record_loader.gemspec | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ruby_test.yml b/.github/workflows/ruby_test.yml index fac765f..732db35 100644 --- a/.github/workflows/ruby_test.yml +++ b/.github/workflows/ruby_test.yml @@ -16,7 +16,7 @@ jobs: fail-fast: false matrix: # Due to https://github.com/actions/runner/issues/849, we have to use quotes for '3.0' - ruby: [ "3.0", "3.1", "3.2", "3.3", "3.4", "4.0" ] + ruby: [ "3.3", "3.4", "4.0" ] steps: - name: Checkout Repository uses: sanger/.github/.github/actions/setup/checkout@master diff --git a/.rubocop.yml b/.rubocop.yml index bde0f27..332b959 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -19,7 +19,7 @@ plugins: AllCops: NewCops: enable - TargetRubyVersion: 3.0 + TargetRubyVersion: 3.3 Gemspec/DevelopmentDependencies: EnforcedStyle: gemspec diff --git a/.ruby-version b/.ruby-version index 818bd47..b9b3b0d 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.0.6 +3.3.11 diff --git a/README.md b/README.md index d63cb61..ae86105 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # RecordLoader -[![Ruby](https://img.shields.io/badge/ruby-3.0-e2242a?logo=ruby)](https://ruby-doc.org/3.0.6/) +[![Ruby](https://img.shields.io/badge/ruby-3.3%20|%203.4%20|%204.0-e2242a?logo=ruby)](https://www.ruby-lang.org/en/) [![Test Coverage](https://codecov.io/gh/sanger/record_loader/graph/badge.svg?token=AO7PUU5SB0)](https://codecov.io/gh/sanger/record_loader) [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](https://rubydoc.info/github/sanger/record_loader) diff --git a/record_loader.gemspec b/record_loader.gemspec index 047acd5..f66b888 100644 --- a/record_loader.gemspec +++ b/record_loader.gemspec @@ -14,7 +14,7 @@ Gem::Specification.new do |spec| spec.homepage = 'https://github.com/sanger/record_loader' spec.license = 'MIT' - spec.required_ruby_version = '>= 3.0.6' + spec.required_ruby_version = '>= 3.3.11' # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host' # to allow pushing to a single host or delete this section to allow pushing to any host. From 9e76d06456665c838eba3a4df672d24a338c6995 Mon Sep 17 00:00:00 2001 From: Stephen Hulme Date: Thu, 30 Apr 2026 08:22:22 +0100 Subject: [PATCH 4/8] fix: use Psych v5 with unsafe load --- Gemfile.lock | 8 ++++++-- lib/record_loader/base.rb | 2 +- record_loader.gemspec | 3 ++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 6b85389..865e207 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,13 +2,14 @@ PATH remote: . specs: record_loader (1.0.0) - psych (~> 3.0) + psych (~> 5.0) GEM remote: https://rubygems.org/ specs: ast (2.4.3) coderay (1.1.3) + date (3.5.1) diff-lcs (1.5.0) docile (1.4.1) json (2.19.4) @@ -27,7 +28,9 @@ GEM pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - psych (3.3.4) + psych (5.3.1) + date + stringio racc (1.8.1) rainbow (3.1.1) rake (13.0.6) @@ -74,6 +77,7 @@ GEM simplecov-lcov (0.9.0) simplecov_json_formatter (0.1.4) sorbet-runtime (0.6.13169) + stringio (3.2.0) unicode-display_width (3.2.0) unicode-emoji (~> 4.1) unicode-emoji (4.2.0) diff --git a/lib/record_loader/base.rb b/lib/record_loader/base.rb index 470ae6c..dc36be6 100644 --- a/lib/record_loader/base.rb +++ b/lib/record_loader/base.rb @@ -133,7 +133,7 @@ def default_path # def load_config @config = @files.each_with_object({}) do |file, store| - latest_file = Psych.load_file(file) + latest_file = Psych.unsafe_load_file(file) duplicate_keys = store.keys & latest_file.keys adapter.logger.warn "Duplicate keys in #{@path}: #{duplicate_keys}" unless duplicate_keys.empty? store.merge!(latest_file) diff --git a/record_loader.gemspec b/record_loader.gemspec index f66b888..c069d71 100644 --- a/record_loader.gemspec +++ b/record_loader.gemspec @@ -35,7 +35,8 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } spec.require_paths = ['lib'] - spec.add_dependency 'psych', '~> 3.0' + # Runtime dependencies + spec.add_dependency 'psych', '~> 5.0' # Development dependencies spec.add_development_dependency 'bundler', '~> 2.5' From 7004d73b4344e24e5d98c3e17f780cd36dffa7e6 Mon Sep 17 00:00:00 2001 From: Stephen Hulme Date: Thu, 30 Apr 2026 00:19:43 +0100 Subject: [PATCH 5/8] style: add Style/HashSyntax --- .rubocop.yml | 4 ++++ lib/record_loader/base.rb | 2 +- lib/record_loader/filter.rb | 2 +- spec/record_loader/filter/standard_spec.rb | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 332b959..83967be 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -42,3 +42,7 @@ RSpec/NestedGroups: # The single-line syntax can be clearer than the multi-line version for multiple definitions Style/EmptyClassDefinition: Enabled: false + +# Only use shorthand hash syntax when all keys match the variables for better readability +Style/HashSyntax: + EnforcedShorthandSyntax: consistent diff --git a/lib/record_loader/base.rb b/lib/record_loader/base.rb index dc36be6..169aeb7 100644 --- a/lib/record_loader/base.rb +++ b/lib/record_loader/base.rb @@ -66,7 +66,7 @@ def adapter(adapter = nil) def initialize(files: nil, directory: default_path, dev: adapter.development?) @path = directory.is_a?(Pathname) ? directory : Pathname.new(directory) - list = Filter.create(files: files, dev: dev, wip_list: wip_list) + list = Filter.create(files:, dev:, wip_list:) @files = @path.glob("*#{RecordFile::EXTENSION}") .select { |child| list.include?(RecordFile.new(child)) } load_config diff --git a/lib/record_loader/filter.rb b/lib/record_loader/filter.rb index 17ffade..df13078 100644 --- a/lib/record_loader/filter.rb +++ b/lib/record_loader/filter.rb @@ -39,7 +39,7 @@ module Filter # @return [RecordLoader::Filter::Standard, RecordLoader::Filter::FileList] An appropriate filter def self.create(files: nil, dev: false, wip_list: []) if files.nil? - RecordLoader::Filter::Standard.new(dev: dev, wip_list: wip_list) + RecordLoader::Filter::Standard.new(dev:, wip_list:) else RecordLoader::Filter::FileList.new(files) end diff --git a/spec/record_loader/filter/standard_spec.rb b/spec/record_loader/filter/standard_spec.rb index d772d8a..e122e5c 100644 --- a/spec/record_loader/filter/standard_spec.rb +++ b/spec/record_loader/filter/standard_spec.rb @@ -3,7 +3,7 @@ require 'record_loader/filter/standard' RSpec.describe RecordLoader::Filter::Standard, type: :model do - subject(:filter) { described_class.new(dev: dev, wip_list: wip_list) } + subject(:filter) { described_class.new(dev:, wip_list:) } def record_file(name) RecordLoader::RecordFile.new(Pathname.new(name)) From 1849082ef19fb607059e56a4c805ce0ae939f8b4 Mon Sep 17 00:00:00 2001 From: Stephen Hulme Date: Thu, 30 Apr 2026 00:20:12 +0100 Subject: [PATCH 6/8] test: add config loading spec --- spec/record_loader/base_spec.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/spec/record_loader/base_spec.rb b/spec/record_loader/base_spec.rb index 5223bd0..c452962 100644 --- a/spec/record_loader/base_spec.rb +++ b/spec/record_loader/base_spec.rb @@ -50,6 +50,22 @@ def create_or_update_called end end + describe '#initialize' do + let(:dev) { false } + + context 'when loading a string' do + let(:selected_files) { ['000_example'] } + + it 'loads the config from the specified file' do + expect(record_loader.instance_variable_get(:@config)) + .to eq({ + 'Example a' => { 'key_a' => 'value a' }, + 'Example b' => { 'key_a' => 'value b' } + }) + end + end + end + describe '#create' do before { record_loader.create! } From 9d5fd4c2211705760e78da420eaa10a4355b8830 Mon Sep 17 00:00:00 2001 From: Stephen Hulme Date: Thu, 30 Apr 2026 10:31:02 +0100 Subject: [PATCH 7/8] style: lint --- lib/record_loader/adapter/rails.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/record_loader/adapter/rails.rb b/lib/record_loader/adapter/rails.rb index 5880ac1..b352f06 100644 --- a/lib/record_loader/adapter/rails.rb +++ b/lib/record_loader/adapter/rails.rb @@ -16,8 +16,8 @@ def logger # Wraps the ActiveRecord::Base.transaction method. # @see https://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html # @return [Void] - def transaction(&block) - ActiveRecord::Base.transaction(&block) + def transaction(&) + ActiveRecord::Base.transaction(&) end # From cbd59574d1090a0a81a770478a6b4042fa882f6a Mon Sep 17 00:00:00 2001 From: Stephen Hulme Date: Thu, 30 Apr 2026 10:40:38 +0100 Subject: [PATCH 8/8] docs: add note on using trusted data --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ae86105..8b6adaa 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ RecordLoader provides a simple and standardized way of populating databases from information described in a series of organized yaml files. It is intended to be used to generate a number of idempotent tasks, which can be run in both -your production and development environments. +your production and development environments. It should only be used with trusted data. While written with ActiveRecord/Rails in mind, it is possible to use RecordLoader in different environments.