Skip to content

Commit

Permalink
Raise when seed finds no files.
Browse files Browse the repository at this point in the history
In case users pass a typo'ed name/path to `seed` we won't give them any indication of what's going on.

Running a test fails silently.

Now we raise when we can't find any files.
  • Loading branch information
kaspth committed Jan 9, 2025
1 parent fafa951 commit d885686
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 14 deletions.
31 changes: 28 additions & 3 deletions lib/oaken.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,41 @@ module Stored
singleton_class.attr_reader :lookup_paths
@lookup_paths = ["db/seeds"]

def self.lookups_from(paths)
lookup_paths.product(paths).map(&File.method(:join))
end

class NoSeedsFoundError < ArgumentError; end

class Loader
def initialize(path)
@entries = Pathname.glob("#{path}{,/**/*}.rb").sort
def self.from(paths)
new Path.expand(paths).sort
end

def initialize(paths)
@paths = paths
end

def load_onto(seeds) = @entries.each do |path|
def load_onto(seeds) = @paths.each do |path|
ActiveRecord::Base.transaction do
seeds.class_eval path.read, path.to_s
end
end

class Path
def self.expand(paths)
patterns = Oaken.lookups_from(paths).map { new _1 }
patterns.flat_map(&:to_a).tap do |found|
raise Oaken::NoSeedsFoundError, "found no seed files for #{paths.map(&:inspect).join(", ")} when searching with #{patterns.join(", ")}" if found.none?
end
end

def initialize(path)
@pattern = "#{path}{,/**/*}.rb"
end
def to_s = @pattern
def to_a = Pathname.glob(@pattern)
end
end

def self.prepare(&block) = Seeds.instance_eval(&block)
Expand Down
13 changes: 2 additions & 11 deletions lib/oaken/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,8 @@ class << self
# class PaginationTest < ActionDispatch::IntegrationTest
# setup { seed "cases/pagination" }
# end
def seed(*directories)
Oaken.lookup_paths.product(directories).each do |path, directory|
load_from Pathname(path).join(directory.to_s)
end
end

private def load_from(path)
@loader = Oaken::Loader.new path
@loader.load_onto self
ensure
@loader = nil
def seed(*paths)
Oaken::Loader.from(paths.map(&:to_s)).load_onto self
end

# `section` is purely for decorative purposes to carve up `Oaken.prepare` and seed files.
Expand Down
12 changes: 12 additions & 0 deletions test/dummy/test/models/oaken_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,16 @@ def self.column_names = []
assert mod.respond_to?(:users) # Now respond_to_missing? hits.
refute mod.respond_to?(:hmhm)
end

test "raises when no files found to seed" do
assert_raise(Oaken::NoSeedsFoundError) { seed "missing" }.tap do |error|
assert_match "db/seeds/missing{", error.message
assert_match "db/seeds/test/missing{", error.message
end

assert_raise(Oaken::NoSeedsFoundError) { seed "test/cases/missing" }.tap do |error|
assert_match "db/seeds/test/cases/missing{", error.message
assert_match "db/seeds/test/test/cases/missing{", error.message
end
end
end

0 comments on commit d885686

Please sign in to comment.