seed_builder 1.3.0 → 1.3.1
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/CHANGELOG.md +13 -1
- data/README.md +45 -28
- data/bin/seed +4 -4
- data/lib/seed_builder/config.rb +2 -2
- data/lib/seed_builder/loader.rb +103 -73
- data/lib/seed_builder.rb +1 -2
- data/lib/tasks/seed.rake +2 -2
- data/seed_builder.gemspec +22 -18
- data/sig/seed_builder/loader.rbs +1 -1
- metadata +111 -74
- data/.editorconfig +0 -14
- data/.github/dependabot.yml +0 -27
- data/.github/workflows/_trunk_check.yml +0 -15
- data/.github/workflows/test.yml +0 -98
- data/.gitignore +0 -25
- data/.ruby-version +0 -1
- data/.standard.yml +0 -22
- data/.trunk/.gitignore +0 -9
- data/.trunk/configs/.markdownlint.yaml +0 -2
- data/.trunk/configs/.shellcheckrc +0 -7
- data/.trunk/configs/.yamllint.yaml +0 -7
- data/.trunk/trunk.yaml +0 -39
- data/.vscode/extensions.json +0 -18
- data/.vscode/settings.json +0 -7
- data/Appraisals +0 -15
- data/Gemfile +0 -3
- data/Gemfile.lock +0 -315
- data/bin/appraisals +0 -99
- data/lib/rails_config.rb +0 -3
- data/spec/fixtures/schema.rb +0 -9
- data/spec/fixtures/seeds/20241206200111_create_users.rb +0 -5
- data/spec/fixtures/seeds.rb +0 -1
- data/spec/generator_spec.rb +0 -50
- data/spec/seed_builder/config_spec.rb +0 -48
- data/spec/seed_builder/loader_spec.rb +0 -299
- data/spec/seed_builder/railtie_spec.rb +0 -118
- data/spec/seed_builder_spec.rb +0 -25
- data/spec/spec_helper.rb +0 -26
- data/spec/support/junit_formatter.rb +0 -6
- data/spec/support/rails_helpers.rb +0 -41
- data/usr/bin/release.sh +0 -35
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6e17c7224d3dede956d465e3d7c81d45fadfae50481fad4f68fc0d5aee8d2936
|
|
4
|
+
data.tar.gz: a0bea568dc1e39af05473f5614ecd7f7337328ab191ce86de7f7ae1632e51615
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7cd7abeb732f00b1a226caa1cc2793c9bb403e416ca85886ee72232b70eac6d33c81f3b1e7df88a3dc8eeecc798c0e0497254e3a5e9ab85eb3aa2d97199dc3b1
|
|
7
|
+
data.tar.gz: 4ea91653aae9ab4216311fbf9da32a649595ced5e128632ed095e7dcd8c8ff1d0b19a79ab0e7fe23354abb2740f9864886fc90e3bc92d970f0fead5216e5ceb3
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 1.3.1 (2026-11-03)
|
|
4
|
+
|
|
5
|
+
- Use updated seed paths after configuration has already been read.
|
|
6
|
+
- Load the application's Rails environment when running the seed command.
|
|
7
|
+
- Exclude development tools and audit records from the installed gem.
|
|
8
|
+
- Cancel release preparation when confirmation input is closed.
|
|
9
|
+
- Run timestamped seed files in numeric timestamp order.
|
|
10
|
+
- Fail `bin/seed` and `bin/rails seed:run` when the seed is missing, ambiguous, invalid, or outside the seeds directory.
|
|
11
|
+
- Reject an invalid or missing seed name before opening a database connection.
|
|
12
|
+
- Warn that the seed directory is missing only when directory loading is enabled.
|
|
13
|
+
- Keep `bin/rails db:seed` on the Rails seed file when `SeedBuilder.config.use_seed_loader` is false.
|
|
14
|
+
|
|
3
15
|
## 1.3.0 (2025-11-04)
|
|
4
16
|
|
|
5
17
|
- Replace `puts` statements with `Rails.logger` for proper logging integration
|
|
@@ -9,7 +21,7 @@
|
|
|
9
21
|
- Logger automatically detects if `Rails.logger` already supports tagging to avoid double-wrapping
|
|
10
22
|
- Add ability to run specific seed files on demand using `bin/rails seed:run[SEED_NAME]`
|
|
11
23
|
- Add `load_seed_file` method to `SeedBuilder::Loader` for loading individual seeds
|
|
12
|
-
- Add ambiguous match detection: when multiple seed files match the same name, the loader
|
|
24
|
+
- Add ambiguous match detection: when multiple seed files match the same name, the loader lists the matches and the command needs the full name with the timestamp
|
|
13
25
|
- Patch `Rails.application.load_seed` to use SeedBuilder loader via Railtie integration
|
|
14
26
|
|
|
15
27
|
## 1.2.1
|
data/README.md
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
# seed_builder.rb
|
|
2
2
|
|
|
3
|
-
[](https://badge.fury.io/rb/seed_builder) [](https://github.com/amkisko/seed_builder.rb/actions/workflows/test.yml) [](https://codecov.io/
|
|
3
|
+
[](https://badge.fury.io/rb/seed_builder) [](https://github.com/amkisko/seed_builder.rb/actions/workflows/test.yml) [](https://app.codecov.io/github/amkisko/seed_builder.rb)
|
|
4
4
|
|
|
5
|
-
Seed
|
|
6
|
-
|
|
7
|
-
Sponsored by [Kisko Labs](https://www.kiskolabs.com).
|
|
5
|
+
Seed loader and generator for ActiveRecord.
|
|
8
6
|
|
|
9
7
|
## Installation
|
|
10
8
|
|
|
@@ -53,7 +51,7 @@ You can specify the seed name in different formats:
|
|
|
53
51
|
- Full name: `20241206200111_create_users`
|
|
54
52
|
- Timestamp: `20241206200111`
|
|
55
53
|
|
|
56
|
-
|
|
54
|
+
If several seed files match the same name, the command writes the matching names to the log and exits with status 1. Run it again with the timestamped name, for example `20241206200111_create_users`. `bin/seed` uses the same names and the same failed status.
|
|
57
55
|
|
|
58
56
|
### Generate seed file
|
|
59
57
|
|
|
@@ -67,7 +65,7 @@ bin/rails g seed create_users
|
|
|
67
65
|
|
|
68
66
|
By default seed file `db/seeds.rb` is loaded.
|
|
69
67
|
|
|
70
|
-
To
|
|
68
|
+
To stop loading `db/seeds.rb`:
|
|
71
69
|
|
|
72
70
|
```ruby
|
|
73
71
|
SeedBuilder.config.load_default_seeds = false
|
|
@@ -75,7 +73,7 @@ SeedBuilder.config.load_default_seeds = false
|
|
|
75
73
|
|
|
76
74
|
### Set seed directory
|
|
77
75
|
|
|
78
|
-
|
|
76
|
+
A relative `seeds_path` is joined to `Rails.root`. An absolute `seeds_path` is used as given. Set `seeds_full_path` to select the directory directly.
|
|
79
77
|
|
|
80
78
|
```ruby
|
|
81
79
|
SeedBuilder.config.seeds_path = "db/seeds"
|
|
@@ -103,7 +101,7 @@ To use a custom logger:
|
|
|
103
101
|
SeedBuilder.config.logger = MyCustomLogger.new
|
|
104
102
|
```
|
|
105
103
|
|
|
106
|
-
|
|
104
|
+
SeedBuilder wraps that logger with `ActiveSupport::TaggedLogging` when the logger has no `tagged` method, so the `[seed]` tag is present.
|
|
107
105
|
|
|
108
106
|
## Specification checklist
|
|
109
107
|
|
|
@@ -112,34 +110,34 @@ The logger will be automatically wrapped with `ActiveSupport::TaggedLogging` if
|
|
|
112
110
|
- [x] User can run all seeds
|
|
113
111
|
- [x] User can run specific seed file
|
|
114
112
|
|
|
115
|
-
## Limitations
|
|
113
|
+
## Limitations
|
|
116
114
|
|
|
117
|
-
-
|
|
118
|
-
- ActiveRecord
|
|
119
|
-
-
|
|
120
|
-
-
|
|
115
|
+
- `bin/rails db:seed` calls `ActiveRecord::Tasks::DatabaseTasks.load_seed`, which calls `Rails.application.load_seed`. The railtie replaces `load_seed` while `use_seed_loader` is on. Set `use_seed_loader = false` in an initializer, before the application finishes booting, to keep the Rails seed file.
|
|
116
|
+
- The ActiveRecord migration generator writes the seed files.
|
|
117
|
+
- A seed run is not reversed. Write seed files so they can run more than once, for example by checking that a record is already present.
|
|
118
|
+
- A seed file is not a migration.
|
|
121
119
|
|
|
122
120
|
## Development
|
|
123
121
|
|
|
124
122
|
```bash
|
|
125
123
|
# Install dependencies
|
|
126
124
|
bundle install
|
|
127
|
-
bundle exec appraisal
|
|
125
|
+
bundle exec appraisal generate
|
|
128
126
|
|
|
129
127
|
# Run tests for current Rails version
|
|
130
|
-
bundle exec rspec
|
|
128
|
+
bundle exec polyrun parallel-rspec --workers 5 --merge-failures
|
|
131
129
|
|
|
132
|
-
# Run tests for
|
|
130
|
+
# Run tests for the configured Rails versions (7.2 and 8.1)
|
|
133
131
|
bin/appraisals
|
|
134
132
|
|
|
135
|
-
# Run tests for
|
|
136
|
-
bin/appraisals
|
|
133
|
+
# Run tests for Rails 7.2
|
|
134
|
+
bin/appraisals rails72
|
|
137
135
|
|
|
138
|
-
# Run tests for
|
|
139
|
-
bin/appraisals
|
|
136
|
+
# Run tests for Rails 7.2 and Rails 8.1 on Ruby 3.4
|
|
137
|
+
bin/appraisals rails72 rails8ruby34
|
|
140
138
|
|
|
141
139
|
# Or use appraisal directly
|
|
142
|
-
bundle exec appraisal
|
|
140
|
+
bundle exec appraisal rails72 rspec
|
|
143
141
|
|
|
144
142
|
# Run linter
|
|
145
143
|
bundle exec standardrb --fix
|
|
@@ -163,7 +161,7 @@ Then run:
|
|
|
163
161
|
bundle install
|
|
164
162
|
```
|
|
165
163
|
|
|
166
|
-
|
|
164
|
+
With `path:` in the Gemfile, Bundler loads this checkout. Edits in the checkout are what the application runs, without a rebuild or reinstall.
|
|
167
165
|
|
|
168
166
|
## Contributing
|
|
169
167
|
|
|
@@ -181,16 +179,35 @@ Review policy:
|
|
|
181
179
|
|
|
182
180
|
## Publishing
|
|
183
181
|
|
|
184
|
-
|
|
182
|
+
From a clean checkout, run:
|
|
185
183
|
|
|
186
184
|
```sh
|
|
187
|
-
|
|
188
|
-
rm seed_builder-*.gem
|
|
189
|
-
gem build seed_builder.gemspec
|
|
190
|
-
gem push seed_builder-$GEM_VERSION.gem
|
|
191
|
-
git tag $GEM_VERSION && git push --tags
|
|
185
|
+
ruby usr/bin/release.rb
|
|
192
186
|
```
|
|
193
187
|
|
|
188
|
+
The script installs dependencies, runs the test suite, requires a clean worktree, checks the changelog heading, and asks before publishing. On confirmation it pushes the gem, tags that version, and opens a GitHub release.
|
|
189
|
+
|
|
190
|
+
## Links
|
|
191
|
+
|
|
192
|
+
- [GitHub](https://github.com/amkisko/seed_builder.rb)
|
|
193
|
+
- [GitLab](https://gitlab.com/amkisko/seed_builder.rb)
|
|
194
|
+
- [RubyGems](https://rubygems.org/gems/seed_builder)
|
|
195
|
+
- [Versions Atom](https://rubygems.org/gems/seed_builder/versions.atom) (feed id `8140233409492`)
|
|
196
|
+
- [libraries.io](https://libraries.io/rubygems/seed_builder)
|
|
197
|
+
- [Deps.dev](https://deps.dev/rubygems/seed_builder)
|
|
198
|
+
- [SonarCloud](https://sonarcloud.io/project/overview?id=amkisko_seed_builder.rb)
|
|
199
|
+
- [Snyk](https://snyk.io/test/github/amkisko/seed_builder.rb)
|
|
200
|
+
- [Codecov](https://app.codecov.io/github/amkisko/seed_builder.rb)
|
|
201
|
+
- [OpenSSF Scorecard](https://scorecard.dev/viewer/?uri=github.com/amkisko/seed_builder.rb)
|
|
202
|
+
|
|
194
203
|
## License
|
|
195
204
|
|
|
196
205
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
206
|
+
|
|
207
|
+
## Sponsors
|
|
208
|
+
|
|
209
|
+
Sponsored by [Kisko Labs](https://www.kiskolabs.com).
|
|
210
|
+
|
|
211
|
+
<a href="https://www.kiskolabs.com">
|
|
212
|
+
<img src="kisko.svg" width="200" alt="Sponsored by Kisko Labs" />
|
|
213
|
+
</a>
|
data/bin/seed
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
environment = File.expand_path("config/environment.rb", Dir.pwd)
|
|
4
|
+
require environment if File.file?(environment)
|
|
5
5
|
|
|
6
6
|
unless defined?(Rails)
|
|
7
7
|
puts "Error: Rails environment not loaded. Please run this from a Rails application root."
|
|
@@ -9,7 +9,7 @@ unless defined?(Rails)
|
|
|
9
9
|
exit 1
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
require "seed_builder"
|
|
13
13
|
|
|
14
14
|
if ARGV.empty?
|
|
15
15
|
puts "Usage: bin/seed SEED_NAME"
|
|
@@ -32,5 +32,5 @@ end
|
|
|
32
32
|
seed_name = ARGV[0]
|
|
33
33
|
|
|
34
34
|
loader = SeedBuilder::Loader.new
|
|
35
|
-
loader.load_seed_file(seed_name)
|
|
35
|
+
exit 1 unless loader.load_seed_file(seed_name)
|
|
36
36
|
|
data/lib/seed_builder/config.rb
CHANGED
|
@@ -7,7 +7,7 @@ module SeedBuilder
|
|
|
7
7
|
|
|
8
8
|
attr_writer :default_seeds_full_path
|
|
9
9
|
def default_seeds_full_path
|
|
10
|
-
@default_seeds_full_path
|
|
10
|
+
@default_seeds_full_path || Rails.root.join(default_seeds_path)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
attr_writer :seeds_path
|
|
@@ -17,7 +17,7 @@ module SeedBuilder
|
|
|
17
17
|
|
|
18
18
|
attr_writer :seeds_full_path
|
|
19
19
|
def seeds_full_path
|
|
20
|
-
@seeds_full_path
|
|
20
|
+
@seeds_full_path || Rails.root.join(seeds_path)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def seeds_path_glob
|
data/lib/seed_builder/loader.rb
CHANGED
|
@@ -1,60 +1,41 @@
|
|
|
1
1
|
module SeedBuilder
|
|
2
2
|
class Loader
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
default_seeds_rb = SeedBuilder.config.default_seeds_full_path
|
|
7
|
-
if File.exist?(default_seeds_rb) && SeedBuilder.config.load_default_seeds?
|
|
8
|
-
started_at = Time.current
|
|
9
|
-
logger.tagged("seed") do
|
|
10
|
-
logger.info "== #{SeedBuilder.config.default_seeds_path}: seeding"
|
|
11
|
-
end
|
|
12
|
-
load default_seeds_rb
|
|
13
|
-
logger.tagged("seed") do
|
|
14
|
-
logger.info "== #{SeedBuilder.config.default_seeds_path}: seeded (#{(Time.current - started_at).round(4)}s)"
|
|
15
|
-
end
|
|
16
|
-
end
|
|
3
|
+
SEED_NAME = /\A[A-Za-z0-9_]+\z/
|
|
4
|
+
private_constant :SEED_NAME
|
|
17
5
|
|
|
6
|
+
def load_seed
|
|
7
|
+
default_path = SeedBuilder.config.default_seeds_full_path
|
|
18
8
|
base_path = SeedBuilder.config.seeds_full_path
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
.each do |seed_path|
|
|
23
|
-
load "#{base_path}/#{seed_path}.rb"
|
|
24
|
-
timestamp, klass_name = seed_path.scan(/^([0-9]+)_(.+)$/).first
|
|
25
|
-
next if klass_name.blank?
|
|
26
|
-
|
|
27
|
-
execute_seed_class(klass_name, timestamp)
|
|
28
|
-
end
|
|
29
|
-
else
|
|
30
|
-
logger.tagged("seed") do
|
|
31
|
-
logger.warn "Seed directory #{base_path} does not exist"
|
|
32
|
-
end
|
|
9
|
+
load_default = SeedBuilder.config.load_default_seeds? && File.file?(default_path.to_s)
|
|
10
|
+
if SeedBuilder.config.load_seeds? && !File.directory?(base_path.to_s)
|
|
11
|
+
warn_seed("Seed directory #{base_path} does not exist")
|
|
33
12
|
end
|
|
34
|
-
|
|
13
|
+
load_directory = SeedBuilder.config.load_seeds? && File.directory?(base_path.to_s)
|
|
14
|
+
return unless load_default || load_directory
|
|
35
15
|
|
|
36
|
-
def load_seed_file(seed_name)
|
|
37
16
|
prepare_active_record
|
|
17
|
+
load_default_seed(default_path) if load_default
|
|
18
|
+
load_directory_seeds(base_path) if load_directory
|
|
19
|
+
end
|
|
38
20
|
|
|
21
|
+
def load_seed_file(seed_name)
|
|
39
22
|
base_path = SeedBuilder.config.seeds_full_path
|
|
40
|
-
unless
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
end
|
|
44
|
-
return
|
|
23
|
+
unless seed_name.is_a?(String) && SEED_NAME.match?(seed_name)
|
|
24
|
+
warn_seed("Seed name '#{seed_name}' is invalid")
|
|
25
|
+
return false
|
|
45
26
|
end
|
|
46
27
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
28
|
+
unless File.directory?(base_path.to_s)
|
|
29
|
+
warn_seed("Seed directory #{base_path} does not exist")
|
|
30
|
+
return false
|
|
31
|
+
end
|
|
50
32
|
|
|
33
|
+
result = locate_seed_file(base_path, seed_name)
|
|
51
34
|
if result.nil?
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
elsif result == :ambiguous
|
|
57
|
-
matches = find_seed_file_matches(base_path, seed_name)
|
|
35
|
+
warn_seed("Seed file '#{seed_name}' not found in #{base_path}")
|
|
36
|
+
return false
|
|
37
|
+
elsif result.is_a?(Array) && result.first == :ambiguous
|
|
38
|
+
matches = result.last
|
|
58
39
|
logger.tagged("seed") do
|
|
59
40
|
logger.warn "Multiple seed files match '#{seed_name}':"
|
|
60
41
|
matches.each do |file|
|
|
@@ -62,23 +43,21 @@ module SeedBuilder
|
|
|
62
43
|
end
|
|
63
44
|
logger.warn "Please be more specific using the full name with timestamp (e.g., 20241206200111_create_users)"
|
|
64
45
|
end
|
|
65
|
-
return
|
|
46
|
+
return false
|
|
66
47
|
end
|
|
67
48
|
|
|
68
49
|
seed_file = result
|
|
69
|
-
|
|
70
50
|
seed_path = File.basename(seed_file, ".*")
|
|
71
|
-
timestamp, klass_name = seed_path
|
|
72
|
-
|
|
51
|
+
timestamp, klass_name = split_seed_basename(seed_path)
|
|
73
52
|
if klass_name.blank?
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
end
|
|
77
|
-
return
|
|
53
|
+
warn_seed("Invalid seed file format: #{seed_path}. Expected format: TIMESTAMP_CLASS_NAME.rb")
|
|
54
|
+
return false
|
|
78
55
|
end
|
|
79
56
|
|
|
57
|
+
prepare_active_record
|
|
80
58
|
load seed_file
|
|
81
59
|
execute_seed_class(klass_name, timestamp, seed_name)
|
|
60
|
+
true
|
|
82
61
|
end
|
|
83
62
|
|
|
84
63
|
private
|
|
@@ -87,6 +66,39 @@ module SeedBuilder
|
|
|
87
66
|
SeedBuilder.logger
|
|
88
67
|
end
|
|
89
68
|
|
|
69
|
+
def warn_seed(message)
|
|
70
|
+
logger.tagged("seed") do
|
|
71
|
+
logger.warn(message)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def load_default_seed(default_path)
|
|
76
|
+
started_at = Time.current
|
|
77
|
+
logger.tagged("seed") do
|
|
78
|
+
logger.info "== #{SeedBuilder.config.default_seeds_path}: seeding"
|
|
79
|
+
end
|
|
80
|
+
load default_path
|
|
81
|
+
logger.tagged("seed") do
|
|
82
|
+
logger.info "== #{SeedBuilder.config.default_seeds_path}: seeded (#{(Time.current - started_at).round(4)}s)"
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def load_directory_seeds(base_path)
|
|
87
|
+
seed_basenames(base_path).each do |seed_path|
|
|
88
|
+
full_path = File.join(base_path, "#{seed_path}.rb")
|
|
89
|
+
unless inside_directory?(base_path, full_path)
|
|
90
|
+
warn_seed("Seed file #{seed_path} was not loaded from #{base_path}")
|
|
91
|
+
next
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
load full_path
|
|
95
|
+
timestamp, klass_name = split_seed_basename(seed_path)
|
|
96
|
+
next if klass_name.blank?
|
|
97
|
+
|
|
98
|
+
execute_seed_class(klass_name, timestamp)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
90
102
|
def prepare_active_record
|
|
91
103
|
ActiveRecord::Base.connection.schema_cache.clear!
|
|
92
104
|
ActiveRecord::Base.descendants.each(&:reset_column_information)
|
|
@@ -121,38 +133,56 @@ module SeedBuilder
|
|
|
121
133
|
raise e
|
|
122
134
|
end
|
|
123
135
|
|
|
124
|
-
def
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
136
|
+
def locate_seed_file(base_path, seed_name)
|
|
137
|
+
exact_path = File.join(base_path, "#{seed_name}.rb")
|
|
138
|
+
if File.file?(exact_path)
|
|
139
|
+
return inside_directory?(base_path, exact_path) ? exact_path : nil
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
matches = seed_basenames(base_path).filter_map { |basename|
|
|
143
|
+
next unless basename == seed_name || basename.end_with?("_#{seed_name}") || basename.start_with?("#{seed_name}_")
|
|
128
144
|
|
|
129
|
-
|
|
130
|
-
|
|
145
|
+
path = File.join(base_path, "#{basename}.rb")
|
|
146
|
+
path if inside_directory?(base_path, path)
|
|
147
|
+
}
|
|
131
148
|
|
|
132
|
-
# Return appropriate result based on number of matches
|
|
133
149
|
case matches.length
|
|
134
150
|
when 0
|
|
135
151
|
nil
|
|
136
152
|
when 1
|
|
137
153
|
matches.first
|
|
138
154
|
else
|
|
139
|
-
:ambiguous
|
|
155
|
+
[:ambiguous, matches]
|
|
140
156
|
end
|
|
141
157
|
end
|
|
142
158
|
|
|
143
|
-
def
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
159
|
+
def seed_basenames(base_path)
|
|
160
|
+
Dir.children(base_path.to_s).filter_map { |entry|
|
|
161
|
+
next if entry.start_with?(".")
|
|
162
|
+
next unless entry.end_with?(".rb")
|
|
163
|
+
|
|
164
|
+
File.basename(entry, ".rb")
|
|
165
|
+
}.sort_by { |name| seed_sort_key(name) }
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def seed_sort_key(name)
|
|
169
|
+
match = name.match(/\A([0-9]+)_/)
|
|
170
|
+
match ? [0, match[1].to_i, name] : [1, 0, name]
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def split_seed_basename(seed_path)
|
|
174
|
+
match = seed_path.match(/\A([0-9]+)_(.+)\z/)
|
|
175
|
+
return [nil, nil] unless match
|
|
176
|
+
|
|
177
|
+
[match[1], match[2]]
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def inside_directory?(base_path, file_path)
|
|
181
|
+
root = File.realpath(base_path.to_s)
|
|
182
|
+
resolved = File.realpath(file_path)
|
|
183
|
+
resolved.start_with?(root + File::SEPARATOR)
|
|
184
|
+
rescue Errno::ENOENT
|
|
185
|
+
false
|
|
156
186
|
end
|
|
157
187
|
end
|
|
158
188
|
end
|
data/lib/seed_builder.rb
CHANGED
|
@@ -3,7 +3,7 @@ require "seed_builder/config"
|
|
|
3
3
|
require "seed_builder/loader"
|
|
4
4
|
|
|
5
5
|
module SeedBuilder
|
|
6
|
-
VERSION = "1.3.
|
|
6
|
+
VERSION = "1.3.1".freeze
|
|
7
7
|
|
|
8
8
|
module_function
|
|
9
9
|
|
|
@@ -35,5 +35,4 @@ module SeedBuilder
|
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
require "rails_config"
|
|
39
38
|
require "seed_builder/railtie" if defined?(Rails::Railtie)
|
data/lib/tasks/seed.rake
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
namespace :seed do
|
|
2
2
|
desc "Run a specific seed file by name"
|
|
3
3
|
task :run, [:seed_name] => :environment do |_task, args|
|
|
4
|
-
if args[:seed_name].
|
|
4
|
+
if args[:seed_name].blank?
|
|
5
5
|
puts "Usage: bin/rails seed:run[SEED_NAME]"
|
|
6
6
|
puts ""
|
|
7
7
|
puts "Run a specific seed file by name."
|
|
@@ -17,6 +17,6 @@ namespace :seed do
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
loader = SeedBuilder::Loader.new
|
|
20
|
-
loader.load_seed_file(args[:seed_name])
|
|
20
|
+
exit 1 unless loader.load_seed_file(args[:seed_name])
|
|
21
21
|
end
|
|
22
22
|
end
|
data/seed_builder.gemspec
CHANGED
|
@@ -2,7 +2,6 @@ Gem::Specification.new do |gem|
|
|
|
2
2
|
gem.name = "seed_builder"
|
|
3
3
|
gem.version = File.read(File.expand_path("../lib/seed_builder.rb", __FILE__)).match(/VERSION\s*=\s*"(.*?)"/)[1]
|
|
4
4
|
|
|
5
|
-
repository_url = "https://github.com/amkisko/seed_builder.rb"
|
|
6
5
|
root_files = %w[CHANGELOG.md LICENSE.md README.md]
|
|
7
6
|
root_files << "#{gem.name}.gemspec"
|
|
8
7
|
|
|
@@ -12,34 +11,39 @@ Gem::Specification.new do |gem|
|
|
|
12
11
|
|
|
13
12
|
gem.authors = ["Andrei Makarov"]
|
|
14
13
|
gem.email = ["contact@kiskolabs.com"]
|
|
15
|
-
gem.homepage =
|
|
14
|
+
gem.homepage = "https://github.com/amkisko/seed_builder.rb"
|
|
16
15
|
gem.summary = "Seed builder with loader and generator"
|
|
17
|
-
gem.description = "
|
|
16
|
+
gem.description = "Organize ActiveRecord seeds in a directory and generate seed files"
|
|
18
17
|
gem.metadata = {
|
|
19
|
-
"homepage" =>
|
|
20
|
-
"source_code_uri" =>
|
|
21
|
-
"bug_tracker_uri" => "
|
|
22
|
-
"changelog_uri" => "
|
|
18
|
+
"homepage" => "https://github.com/amkisko/seed_builder.rb",
|
|
19
|
+
"source_code_uri" => "https://github.com/amkisko/seed_builder.rb",
|
|
20
|
+
"bug_tracker_uri" => "https://github.com/amkisko/seed_builder.rb/issues",
|
|
21
|
+
"changelog_uri" => "https://github.com/amkisko/seed_builder.rb/blob/main/CHANGELOG.md",
|
|
23
22
|
"rubygems_mfa_required" => "true"
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
gem.files =
|
|
27
|
-
gem.
|
|
28
|
-
gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
|
25
|
+
gem.files = Dir["lib/**/*", "sig/**/*.rbs"].select { |file| File.file?(file) } + ["bin/seed"] + root_files
|
|
26
|
+
gem.executables = ["seed"]
|
|
29
27
|
|
|
30
|
-
gem.required_ruby_version = ">= 3"
|
|
28
|
+
gem.required_ruby_version = ">= 3.4"
|
|
31
29
|
gem.require_paths = ["lib"]
|
|
32
30
|
|
|
33
31
|
gem.add_dependency "rails", ">= 6.1", "< 8.2"
|
|
34
32
|
gem.add_dependency "activerecord", ">= 6.1", "< 8.2"
|
|
35
33
|
|
|
36
|
-
gem.add_development_dependency "bundler", "
|
|
34
|
+
gem.add_development_dependency "bundler", ">= 2"
|
|
37
35
|
gem.add_development_dependency "rspec", "~> 3"
|
|
38
|
-
gem.add_development_dependency "
|
|
39
|
-
gem.add_development_dependency "
|
|
40
|
-
gem.add_development_dependency "simplecov-cobertura", "~> 2"
|
|
36
|
+
gem.add_development_dependency "polyrun", ">= 2.2.0"
|
|
37
|
+
gem.add_development_dependency "prosopite", "~> 2.0"
|
|
41
38
|
gem.add_development_dependency "sqlite3", "~> 2.4"
|
|
42
|
-
gem.add_development_dependency "standard", "~> 1.
|
|
43
|
-
gem.add_development_dependency "
|
|
44
|
-
gem.add_development_dependency "
|
|
39
|
+
gem.add_development_dependency "standard", "~> 1.52"
|
|
40
|
+
gem.add_development_dependency "standard-custom", "~> 1.0"
|
|
41
|
+
gem.add_development_dependency "standard-performance", "~> 1.8"
|
|
42
|
+
gem.add_development_dependency "standard-rails", "~> 1.5"
|
|
43
|
+
gem.add_development_dependency "standard-rspec", "~> 0.3"
|
|
44
|
+
gem.add_development_dependency "rubocop-rails", "~> 2.33"
|
|
45
|
+
gem.add_development_dependency "rubocop-rspec", "~> 3.8"
|
|
46
|
+
gem.add_development_dependency "rubocop-thread_safety", "~> 0.7"
|
|
47
|
+
gem.add_development_dependency "rbs", "~> 3"
|
|
48
|
+
gem.add_development_dependency "appraisal", "~> 2"
|
|
45
49
|
end
|