oaken 0.2.0 → 0.5.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 +4 -4
- data/README.md +121 -7
- data/lib/generators/oaken/convert/fixtures_generator.rb +114 -0
- data/lib/oaken/entry.rb +60 -0
- data/lib/oaken/railtie.rb +25 -0
- data/lib/oaken/seeds.rb +41 -0
- data/lib/oaken/stored/active_record.rb +40 -0
- data/lib/oaken/version.rb +1 -1
- data/lib/oaken.rb +63 -2
- metadata +10 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f7a49242a569f0460aab42af0102a0aeec30095909c6362310b45e9ce0638c43
|
4
|
+
data.tar.gz: 218c22c32d91b4deaf4f3524f4a19daea964df126c3018b048a2a1119c679297
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 40f50f45dd4bfc45b326aacc111792b30a178446e3f51b1db9b0e9c0f95f91d6b3269a28fc3aaf8d797d5def0c6a6f1dad0ae6d61e4d1fe44aed7b994fb66dda
|
7
|
+
data.tar.gz: 9c21c825239bf7bb910632abe86d6672f63dcf9fe50d0cdf42270f03aed09ff9cad3268e6e5ec70957717996193791a43c67d2cab803ad4e16efce313f29fed6
|
data/README.md
CHANGED
@@ -1,22 +1,119 @@
|
|
1
1
|
# Oaken
|
2
2
|
|
3
|
-
|
3
|
+
Oaken is an alternative to fixtures and/or factories to manage your development, test and some production data using data scripts.
|
4
4
|
|
5
|
-
##
|
5
|
+
## Setup
|
6
|
+
|
7
|
+
### Starting in development
|
8
|
+
|
9
|
+
You can set it up in `db/seeds.rb`, like this:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
Oaken.prepare do
|
13
|
+
seed :accounts, :data
|
14
|
+
end
|
15
|
+
```
|
16
|
+
|
17
|
+
This will look for deeply nested files to load in `db/seeds` and `db/seeds/#{Rails.env}` within the `accounts` and `data` directories.
|
18
|
+
|
19
|
+
Here's what they could look like.
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
# db/seeds/accounts/kaspers_donuts.rb
|
23
|
+
donuts = accounts.create :kaspers_donuts, name: "Kasper's Donuts"
|
24
|
+
|
25
|
+
kasper = users.create :kasper, name: "Kasper", accounts: [donuts]
|
26
|
+
coworker = users.create :coworker, name: "Coworker", accounts: [donuts]
|
27
|
+
|
28
|
+
menu = menus.create account: donuts
|
29
|
+
plain_donut = menu_items.create menu: menu, name: "Plain", price_cents: 10_00
|
30
|
+
sprinkled_donut = menu_items.create menu: menu, name: "Sprinkled", price_cents: 10_10
|
31
|
+
|
32
|
+
supporter = users.create name: "Super Supporter"
|
33
|
+
orders.insert_all [user_id: supporter.id, item_id: plain_donut.id] * 10
|
34
|
+
|
35
|
+
orders.insert_all \
|
36
|
+
10.times.map { { user_id: users.create(name: "Customer #{_1}").id, item_id: menu.items.sample.id } }
|
37
|
+
```
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
# db/seeds/data/plans.rb
|
41
|
+
plans.insert :basic, title: "Basic", price_cents: 10_00
|
42
|
+
```
|
43
|
+
|
44
|
+
Seed files will generally use `create` and/or `insert`. Passing a symbol to name the record is useful when reusing the data in tests.
|
45
|
+
|
46
|
+
Now you can run `bin/rails db:seed` — plus Oaken skips executing a seed file if it knows the file hasn't been changed since the last seeding. Speedy!
|
47
|
+
|
48
|
+
### Interlude: Directory Naming Conventions
|
49
|
+
|
50
|
+
Oaken has some chosen directory conventions to help strengthen your understanding of your object graph:
|
51
|
+
|
52
|
+
- Have a directory for your top-level model, like `Account`, `Team`, `Organization`, that's why we have `db/seeds/accounts` above.
|
53
|
+
- `db/seeds/data` for any data tables, like the plans a SaaS app has.
|
54
|
+
- `db/seeds/tests/cases` for any specific cases that are only used in some tests, like `pagination.rb`.
|
55
|
+
|
56
|
+
### Reusing data in tests
|
57
|
+
|
58
|
+
With the setup above, Oaken can reuse the same data in tests like so:
|
6
59
|
|
7
|
-
|
60
|
+
```ruby
|
61
|
+
# test/test_helper.rb
|
62
|
+
class ActiveSupport::TestCase
|
63
|
+
include Oaken.seeds
|
64
|
+
|
65
|
+
# Override Minitest::Test#run to wrap each test in a transaction.
|
66
|
+
def run
|
67
|
+
result = nil
|
68
|
+
ActiveRecord::Base.transaction(requires_new: true) do
|
69
|
+
result = super
|
70
|
+
raise ActiveRecord::Rollback
|
71
|
+
end
|
72
|
+
result
|
73
|
+
end
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
Now tests have access to `accounts.kaspers_donuts` and `users.kasper` etc. that were setup in the data scripts.
|
78
|
+
|
79
|
+
You can also load a specific seed, like this:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
class PaginationTest < ActionDispatch::IntegrationTest
|
83
|
+
seed "cases/pagination"
|
84
|
+
end
|
85
|
+
```
|
86
|
+
|
87
|
+
### Resetting cache
|
88
|
+
|
89
|
+
Oaken is still early days, so you may need to reset the cache that skips seed files. Pass `OAKEN_RESET` to clear it:
|
90
|
+
|
91
|
+
```sh
|
92
|
+
OAKEN_RESET=1 bin/rails db:seed
|
93
|
+
OAKEN_RESET=1 bin/rails test
|
94
|
+
```
|
95
|
+
|
96
|
+
### Fixtures Converter
|
97
|
+
|
98
|
+
You can convert your Rails fixtures to Oaken's seeds by running:
|
99
|
+
|
100
|
+
$ bin/rails generate oaken:convert:fixtures
|
101
|
+
|
102
|
+
This will convert anything in test/fixtures to db/seeds. E.g. `test/fixtures/users.yml` becomes `db/seeds/users.rb`.
|
103
|
+
|
104
|
+
## Installation
|
8
105
|
|
9
106
|
Install the gem and add to the application's Gemfile by executing:
|
10
107
|
|
11
|
-
$ bundle add
|
108
|
+
$ bundle add oaken
|
12
109
|
|
13
110
|
If bundler is not being used to manage dependencies, install the gem by executing:
|
14
111
|
|
15
|
-
$ gem install
|
112
|
+
$ gem install oaken
|
16
113
|
|
17
114
|
## Development
|
18
115
|
|
19
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
116
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `cd test/dummy` and `bin/rails test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
20
117
|
|
21
118
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
22
119
|
|
@@ -30,4 +127,21 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
30
127
|
|
31
128
|
## Code of Conduct
|
32
129
|
|
33
|
-
Everyone interacting in the Oaken project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/kaspth/oaken/blob/main/CODE_OF_CONDUCT.md).
|
130
|
+
Everyone interacting in the Oaken project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the [code of conduct](https://github.com/kaspth/oaken/blob/main/CODE_OF_CONDUCT.md).
|
131
|
+
|
132
|
+
## Support
|
133
|
+
|
134
|
+
Initial development is supported in part by:
|
135
|
+
|
136
|
+
<a href="https://arrows.to">
|
137
|
+
<img src="https://user-images.githubusercontent.com/56947/258236465-06c692a7-738e-44bd-914e-fecc697317ce.png" />
|
138
|
+
</a>
|
139
|
+
|
140
|
+
And by:
|
141
|
+
|
142
|
+
- [Alexandre Ruban](https://github.com/alexandreruban)
|
143
|
+
- [Lars Kronfält](https://github.com/larkro)
|
144
|
+
- [Manuel Costa Reis](https://github.com/manuelfcreis)
|
145
|
+
- [Thomas Cannon](https://github.com/tcannonfodder)
|
146
|
+
|
147
|
+
As a sponsor you're welcome to submit a pull request to add your own name here.
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators/base"
|
4
|
+
require "yaml"
|
5
|
+
|
6
|
+
module Oaken::Convert; end
|
7
|
+
class Oaken::Convert::Fixture
|
8
|
+
attr_reader :model_name, :name
|
9
|
+
|
10
|
+
def initialize(model_name, name, attributes)
|
11
|
+
@model_name, @name, @attributes = model_name.tr("/", "_"), name, attributes
|
12
|
+
@plural = @model_name
|
13
|
+
@singular = @model_name.singularize
|
14
|
+
end
|
15
|
+
|
16
|
+
def extract_dependents(fixtures)
|
17
|
+
@dependents = fixtures.select { _1.reference(plural, singular) == name }
|
18
|
+
fixtures.replace fixtures - dependents
|
19
|
+
|
20
|
+
dependents.each { _1.extract_dependents fixtures }
|
21
|
+
end
|
22
|
+
|
23
|
+
def reference(plural, singular)
|
24
|
+
@referenced = [plural, :plural] if attributes[plural]
|
25
|
+
@referenced = [singular, :singular] if attributes[singular]
|
26
|
+
attributes[@referenced&.first]
|
27
|
+
end
|
28
|
+
|
29
|
+
def render(delimiter: "\n")
|
30
|
+
[render_self, dependents&.map { _1.render delimiter: nil }].join(delimiter)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
attr_reader :attributes, :dependents
|
35
|
+
attr_reader :plural, :singular
|
36
|
+
|
37
|
+
def render_self
|
38
|
+
"#{model_name}.create :#{name}, #{convert_hash(attributes)}\n".tap do
|
39
|
+
_1.prepend "#{name} = " if dependents&.any?
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def convert_hash(hash)
|
44
|
+
hash.map { |k, v| "#{k}: #{recursive_convert(v, key: k)}" }.join(", ")
|
45
|
+
end
|
46
|
+
|
47
|
+
def recursive_convert(input, key: nil)
|
48
|
+
case input
|
49
|
+
when Hash then "{ #{convert_hash(input)} }"
|
50
|
+
when Array then input.map { recursive_convert _1 }.join(", ")
|
51
|
+
when Integer then input
|
52
|
+
else
|
53
|
+
if key == @referenced&.first
|
54
|
+
@referenced.last == :plural ? "[#{input}]" : input
|
55
|
+
else
|
56
|
+
"\"#{input}\""
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class Oaken::Convert::FixturesGenerator < Rails::Generators::Base
|
63
|
+
desc "Converts fixtures to Oaken seeds in db/seeds/test"
|
64
|
+
source_root File.expand_path("templates", __dir__)
|
65
|
+
|
66
|
+
class_option :root_model, required: true
|
67
|
+
class_option :keeps, type: :boolean, default: true
|
68
|
+
|
69
|
+
def prepare
|
70
|
+
@root_model = ActiveModel::Name.new(options[:root_model].constantize)
|
71
|
+
empty_directory_with_keep_file "db/seeds/data"
|
72
|
+
empty_directory_with_keep_file "db/seeds/test/cases"
|
73
|
+
end
|
74
|
+
|
75
|
+
def parse
|
76
|
+
@fixtures = Dir.glob("test/fixtures/**/*.yml").to_h do |path|
|
77
|
+
model_name = path.delete_prefix("test/fixtures/").chomp(".yml")
|
78
|
+
[model_name, YAML.load_file(path).presence&.map { Oaken::Convert::Fixture.new(model_name, _1, _2) }]
|
79
|
+
rescue Psych::SyntaxError
|
80
|
+
say "Skipped #{path} due to ERB content or other YAML parsing issues.", :yellow
|
81
|
+
end.tap(&:compact_blank!)
|
82
|
+
end
|
83
|
+
|
84
|
+
def prepend_prepare_to_seeds
|
85
|
+
namespaces = @fixtures.keys.filter_map { _1.classify if _1.include?("/") }.uniq.sort
|
86
|
+
|
87
|
+
code = +"Oaken.prepare do\n"
|
88
|
+
code << " register #{namespaces.join(", ")}\n\n" if namespaces.any?
|
89
|
+
code << " load :#{@root_model.plural}, :data\n"
|
90
|
+
code << "end\n"
|
91
|
+
|
92
|
+
inject_into_file "db/seeds.rb", code, before: /\A/
|
93
|
+
end
|
94
|
+
|
95
|
+
def convert_all
|
96
|
+
roots = @fixtures.delete(@root_model.collection)
|
97
|
+
@fixtures = @fixtures.values.flatten
|
98
|
+
|
99
|
+
roots.each do |fixture|
|
100
|
+
fixture.extract_dependents @fixtures
|
101
|
+
create_file "db/seeds/test/#{@root_model.plural}/#{fixture.name}.rb", fixture.render.chomp
|
102
|
+
end
|
103
|
+
|
104
|
+
@fixtures.group_by(&:model_name).each do |model_name, fixtures|
|
105
|
+
create_file "db/seeds/test/data/#{model_name}.rb", fixtures.map(&:render).join.chomp
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
def empty_directory_with_keep_file(name)
|
111
|
+
empty_directory name
|
112
|
+
create_file "#{name}/.keep" if options[:keeps]
|
113
|
+
end
|
114
|
+
end
|
data/lib/oaken/entry.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require "digest/md5"
|
2
|
+
require "pstore"
|
3
|
+
|
4
|
+
class Oaken::Entry < DelegateClass(PStore)
|
5
|
+
def self.store_accessor(name)
|
6
|
+
define_method(name) { self[name] } and define_method("#{name}=") { |value| self[name] = value }
|
7
|
+
end
|
8
|
+
store_accessor :checksum
|
9
|
+
store_accessor :readers
|
10
|
+
|
11
|
+
def self.within(directory)
|
12
|
+
Pathname.glob("#{directory}{,/**/*}.{rb,sql}").sort.map { new _1 }
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(pathname)
|
16
|
+
@file, @pathname = pathname.to_s, pathname
|
17
|
+
@computed_checksum = Digest::MD5.hexdigest(@pathname.read)
|
18
|
+
|
19
|
+
prepared_store_path = Oaken.store_path.join(pathname).tap { _1.dirname.mkpath }
|
20
|
+
super PStore.new(prepared_store_path)
|
21
|
+
end
|
22
|
+
|
23
|
+
def load_onto(seeds)
|
24
|
+
transaction do
|
25
|
+
if replay?
|
26
|
+
puts "Replaying #{@file}…"
|
27
|
+
readers.each do |key, *args|
|
28
|
+
define_reader(seeds.send(key), *args)
|
29
|
+
end
|
30
|
+
else
|
31
|
+
reset
|
32
|
+
|
33
|
+
case @pathname.extname
|
34
|
+
in ".rb" then seeds.class_eval @pathname.read, @file
|
35
|
+
in ".sql" then ActiveRecord::Base.connection.execute @pathname.read
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def transaction(&block)
|
42
|
+
super do
|
43
|
+
Oaken.transaction(&block)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def replay?
|
48
|
+
checksum == @computed_checksum
|
49
|
+
end
|
50
|
+
|
51
|
+
def reset
|
52
|
+
self.checksum = @computed_checksum
|
53
|
+
self.readers = Set.new
|
54
|
+
end
|
55
|
+
|
56
|
+
def define_reader(stored, name, id, lineno)
|
57
|
+
stored.instance_eval "def #{name}; find #{id}; end", @file, lineno
|
58
|
+
readers << [stored.key, name, id, lineno]
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Oaken::Railtie < Rails::Railtie
|
2
|
+
initializer "oaken.defaults" do
|
3
|
+
Oaken.lookup_paths << "db/seeds/#{Rails.env}"
|
4
|
+
Oaken.store_path = Oaken.store_path.join(Rails.env)
|
5
|
+
end
|
6
|
+
|
7
|
+
rake_tasks do
|
8
|
+
namespace :oaken do
|
9
|
+
task("reset") { Oaken.store_path.rmtree }
|
10
|
+
task("reset:all") { Oaken.store_path.dirname.rmtree }
|
11
|
+
|
12
|
+
task "reset:include_test" do
|
13
|
+
# Some db: tasks in development also manipulate the test database.
|
14
|
+
Oaken.store_path.sub("development", "test").rmtree if Rails.env.development?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
task "db:drop" => ["oaken:reset", "oaken:reset:include_test"]
|
19
|
+
task "db:purge" => ["oaken:reset", "oaken:reset:include_test"]
|
20
|
+
task "db:purge:all" => ["oaken:reset:all"]
|
21
|
+
|
22
|
+
# db:seed:replant runs trunacte_all, after trial-and-error we need to hook into that and not the replant task.
|
23
|
+
task "db:truncate_all" => "oaken:purge"
|
24
|
+
end
|
25
|
+
end
|
data/lib/oaken/seeds.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
module Oaken::Seeds
|
2
|
+
extend self
|
3
|
+
|
4
|
+
def self.respond_to_missing?(name, ...)
|
5
|
+
Oaken.inflector.classify(name).safe_constantize || super
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.method_missing(meth, ...)
|
9
|
+
name = meth.to_s
|
10
|
+
if type = Oaken.inflector.classify(name).safe_constantize
|
11
|
+
register type, name
|
12
|
+
public_send(name, ...)
|
13
|
+
else
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.register(type, key = nil)
|
19
|
+
stored = provider.new(type, key) and define_method(stored.key) { stored }
|
20
|
+
end
|
21
|
+
def self.provider = Oaken::Stored::ActiveRecord
|
22
|
+
|
23
|
+
singleton_class.attr_reader :loader
|
24
|
+
delegate :entry, to: :loader
|
25
|
+
|
26
|
+
module Loading
|
27
|
+
def seed(*directories)
|
28
|
+
Oaken.lookup_paths.each do |path|
|
29
|
+
directories.each do |directory|
|
30
|
+
@loader = Oaken::Loader.new Pathname(path).join(directory.to_s)
|
31
|
+
@loader.load_onto Oaken::Seeds
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
extend Loading
|
37
|
+
|
38
|
+
def self.included(klass)
|
39
|
+
klass.extend Loading
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class Oaken::Stored::ActiveRecord < Struct.new(:type, :key)
|
2
|
+
def initialize(type, key = nil)
|
3
|
+
super(type, key || Oaken.inflector.tableize(type.name))
|
4
|
+
@attributes = {}
|
5
|
+
end
|
6
|
+
delegate :transaction, to: :type # For multi-db setups to help open a transaction on secondary connections.
|
7
|
+
delegate :find, :insert_all, :pluck, to: :type
|
8
|
+
|
9
|
+
def defaults(**attributes)
|
10
|
+
@attributes = @attributes.merge(attributes)
|
11
|
+
@attributes
|
12
|
+
end
|
13
|
+
|
14
|
+
def create(reader = nil, **attributes)
|
15
|
+
lineno = caller_locations(1, 1).first.lineno
|
16
|
+
|
17
|
+
attributes = @attributes.merge(attributes)
|
18
|
+
attributes.transform_values! { _1.respond_to?(:call) ? _1.call : _1 }
|
19
|
+
|
20
|
+
type.create!(**attributes).tap do |record|
|
21
|
+
define_reader reader, record.id, lineno if reader
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def insert(reader = nil, **attributes)
|
26
|
+
lineno = caller_locations(1, 1).first.lineno
|
27
|
+
|
28
|
+
attributes = @attributes.merge(attributes)
|
29
|
+
attributes.transform_values! { _1.respond_to?(:call) ? _1.call : _1 }
|
30
|
+
|
31
|
+
type.new(attributes).validate!
|
32
|
+
type.insert(attributes).tap do
|
33
|
+
define_reader reader, type.where(attributes).pick(:id), lineno if reader
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def define_reader(...)
|
38
|
+
Oaken::Seeds.entry.define_reader(self, ...)
|
39
|
+
end
|
40
|
+
end
|
data/lib/oaken/version.rb
CHANGED
data/lib/oaken.rb
CHANGED
@@ -1,8 +1,69 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require "oaken/version"
|
4
|
+
require "pathname"
|
4
5
|
|
5
6
|
module Oaken
|
6
7
|
class Error < StandardError; end
|
7
|
-
|
8
|
+
|
9
|
+
autoload :Seeds, "oaken/seeds"
|
10
|
+
autoload :Entry, "oaken/entry"
|
11
|
+
|
12
|
+
module Stored
|
13
|
+
autoload :ActiveRecord, "oaken/stored/active_record"
|
14
|
+
end
|
15
|
+
|
16
|
+
class Inflector
|
17
|
+
def tableize(string)
|
18
|
+
string.gsub(/(?<=[a-z])(?=[A-Z])/, "_").gsub("::", "_").tap(&:downcase!) << "s"
|
19
|
+
end
|
20
|
+
|
21
|
+
def classify(string)
|
22
|
+
string.chomp("s").gsub(/_([a-z])/) { $1.upcase }.sub(/^\w/, &:upcase)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
singleton_class.attr_accessor :inflector
|
27
|
+
@inflector = Inflector.new
|
28
|
+
|
29
|
+
singleton_class.attr_reader :lookup_paths
|
30
|
+
@lookup_paths = ["db/seeds"]
|
31
|
+
|
32
|
+
singleton_class.attr_accessor :store_path
|
33
|
+
@store_path = Pathname.new "tmp/oaken/store"
|
34
|
+
|
35
|
+
class Loader
|
36
|
+
attr_reader :entry
|
37
|
+
|
38
|
+
def initialize(path)
|
39
|
+
@entries, @entry = Entry.within(path), nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def load_onto(seeds)
|
43
|
+
@entries.each do |entry|
|
44
|
+
@entry = entry
|
45
|
+
@entry.load_onto seeds
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.transaction(&block)
|
51
|
+
ActiveRecord::Base.transaction(&block)
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.prepare(&block)
|
55
|
+
store_path.rmtree if ENV["OAKEN_RESET"]
|
56
|
+
Seeds.instance_eval(&block)
|
57
|
+
Seeds
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.seeds
|
61
|
+
unless defined?(@loaded)
|
62
|
+
@loaded = true
|
63
|
+
Rails.application.load_seed
|
64
|
+
end
|
65
|
+
Seeds
|
66
|
+
end
|
8
67
|
end
|
68
|
+
|
69
|
+
require_relative "oaken/railtie" if defined?(Rails::Railtie)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oaken
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kasper Timm Hansen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -22,14 +22,19 @@ files:
|
|
22
22
|
- LICENSE.txt
|
23
23
|
- README.md
|
24
24
|
- Rakefile
|
25
|
+
- lib/generators/oaken/convert/fixtures_generator.rb
|
25
26
|
- lib/oaken.rb
|
27
|
+
- lib/oaken/entry.rb
|
28
|
+
- lib/oaken/railtie.rb
|
29
|
+
- lib/oaken/seeds.rb
|
30
|
+
- lib/oaken/stored/active_record.rb
|
26
31
|
- lib/oaken/version.rb
|
27
|
-
homepage: https://
|
32
|
+
homepage: https://github.com/kaspth/oaken
|
28
33
|
licenses:
|
29
34
|
- MIT
|
30
35
|
metadata:
|
31
36
|
allowed_push_host: https://rubygems.org
|
32
|
-
homepage_uri: https://
|
37
|
+
homepage_uri: https://github.com/kaspth/oaken
|
33
38
|
source_code_uri: https://github.com/kaspth/oaken
|
34
39
|
changelog_uri: https://github.com/kaspth/oaken/blob/main/CHANGELOG.md
|
35
40
|
post_install_message:
|
@@ -47,7 +52,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
47
52
|
- !ruby/object:Gem::Version
|
48
53
|
version: '0'
|
49
54
|
requirements: []
|
50
|
-
rubygems_version: 3.4.
|
55
|
+
rubygems_version: 3.4.19
|
51
56
|
signing_key:
|
52
57
|
specification_version: 4
|
53
58
|
summary: Oaken aims to blend your Fixtures/Factories and levels up your database seeds.
|