rb-db-setup 0.1.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6af744ad5a2ffc7e175c38eeeb461941c0836b8e6b23f2d6be493018214899f0
4
+ data.tar.gz: f757f955460f894ab0e67bd278345bf5b562f3ecc6d0e110d26ffa434acf4c08
5
+ SHA512:
6
+ metadata.gz: 0b3ad20c6a45160f633cd91fd4d1f69f8c857341e6d97e9700a810b10fc1ff18d775db701fece66b09355a99620dd183fa838ea6d9471b3e6dc2dfae9c0d7fa4
7
+ data.tar.gz: 4ee011658c0f273368bfd649812611b7f8d6c14b9e5c46236745515afe353149035120863ea90833c5644104e267eaeccfc8db10714f5ccb8bd27afa1fb2d182
data/README.md ADDED
@@ -0,0 +1,127 @@
1
+ # RbDbSetup 🚀
2
+
3
+ > [!NOTE]
4
+ > This is a **personal scaffolding personal setup** created to automate the database infrastructure for my own Ruby projects. It is tailored for my specific workflow but is open for public use!
5
+
6
+ ## Features
7
+
8
+ - **Class-Based Seeders**: Organize your seeding logic into clean, reusable classes.
9
+ - **Central Orchestration**: Uses a `DatabaseSeeder.rb` entry point, just like Laravel's `DatabaseSeeder`.
10
+ - **Hardened Migrations**: Automated migration scripts with fail-safe checks and naming consistency.
11
+ - **Convenient Generators**:
12
+ - `rb-db-setup`: Scaffolds the entire infrastructure.
13
+ - `ruby make_migration.rb <name>`: Generates sanitized migration templates.
14
+ - `ruby make_seeder.rb <Name>`: Generates class-based seeder templates.
15
+ - **Atomic Seeding**: Seeding runs within database transactions to ensure data integrity.
16
+ - **Cross-Platform**: Works perfectly on Linux, macOS, and Windows.
17
+
18
+ ## Installation
19
+
20
+ ### Standard Installation
21
+ If you've installed it as a RubyGem:
22
+ ```bash
23
+ gem install rb-db-setup
24
+ ```
25
+
26
+ ### Alternative: Clone & Run (Local)
27
+ If you have cloned the repository, you can run the tool directly from the project root:
28
+ ```bash
29
+ ruby bin/rb-db-setup
30
+ ```
31
+
32
+ ### Alternative: Manual Setup (Copy & Run)
33
+ If you just want the logic without installing a gem or cloning the whole repo, you can simply grab the `setup_db_tools.rb` script:
34
+ 1. Copy [setup_db_tools.rb](setup_db_tools.rb) to your project.
35
+ 2. Run it:
36
+ ```bash
37
+ ruby setup_db_tools.rb
38
+ ```
39
+ *Note: You can delete the script after it generates the infrastructure.*
40
+
41
+ ### GitHub One-Liner (Fastest)
42
+ Run the latest version directly from GitHub without downloading anything:
43
+ ```bash
44
+ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/LanceDanielG/rb-db-scaffold-setup/main/setup_db_tools.rb)"
45
+ ```
46
+
47
+ ## Global Local Setup (Command Anywhere)
48
+
49
+ If you want the `rb-db-setup` command to work in **any folder** on your machine without publishing a gem, use the included installer scripts.
50
+
51
+ ### Linux / macOS
52
+ Run the installer to copy the script to `~/.local/bin` and update your PATH:
53
+ ```bash
54
+ bash install.sh && source ~/.bashrc
55
+ ```
56
+
57
+ ### Windows (PowerShell)
58
+ Run the PowerShell installer to set up a permanent command and update your User PATH:
59
+ ```powershell
60
+ powershell -ExecutionPolicy Bypass -File install.ps1
61
+ ```
62
+
63
+ Once installed, you can simply type `rb-db-setup` in any terminal window.
64
+
65
+ ## Usage
66
+
67
+ In any new Ruby project folder, simply run:
68
+ ```bash
69
+ rb-db-setup
70
+ ```
71
+
72
+ This will automatically create the following structure:
73
+ ```text
74
+ .
75
+ ├── db/
76
+ │ ├── migrations/ # Your SQL/Sequel migrations
77
+ │ └── seeds/ # Class-based seeder files
78
+ │ └── DatabaseSeeder.rb
79
+ ├── migrate.rb # Hardened migration runner
80
+ ├── seed.rb # Laravel-style seeder runner
81
+ ├── make_migration.rb # Migration generator
82
+ └── make_seeder.rb # Seeder generator
83
+ ```
84
+
85
+ ### Running Migrations
86
+ ```bash
87
+ ruby migrate.rb
88
+ ```
89
+
90
+ ### Running Seeders
91
+ To run all seeders (via `DatabaseSeeder.rb`):
92
+ ```bash
93
+ ruby seed.rb
94
+ ```
95
+
96
+ To run a specific seeder class:
97
+ ```bash
98
+ ruby seed.rb AdminSeeder
99
+ ```
100
+
101
+ ## Configuration
102
+
103
+ The generated scripts expect a `DATABASE_URL` environment variable. They automatically handle `.env` files if the `dotenv` gem is present in your project's `Gemfile`.
104
+
105
+ ## Dependencies
106
+
107
+ The generated infrastructure requires:
108
+ - `sequel`
109
+ - `pg` (or your preferred database driver)
110
+ - `dotenv` (optional but recommended)
111
+
112
+ ## Automated Publishing with GitHub Actions 🤖
113
+
114
+ I've included a GitHub Action to automate the publishing of this gem to RubyGems.org.
115
+
116
+ ### How to set it up:
117
+ 1. **Get your API Key**: Go to [RubyGems.org Settings](https://rubygems.org/profile/edit) and generate a new API key with "Push rubygem" permissions.
118
+ 2. **Add to GitHub Secrets**:
119
+ - Go to your repository on GitHub.
120
+ - Click **Settings** > **Secrets and variables** > **Actions**.
121
+ - Create a **New repository secret** named `RUBYGEMS_API_KEY` and paste your key.
122
+ 3. **Trigger a Release**:
123
+ - Every time you push a **tag** starting with `v` (e.g., `git tag v0.1.0 && git push origin v0.1.0`), GitHub will automatically build and publish the gem for you!
124
+
125
+ ## License
126
+
127
+ MIT License. See [LICENSE](LICENSE) for more information.
data/bin/rb-db-setup ADDED
@@ -0,0 +1,284 @@
1
+ #!/usr/bin/env ruby
2
+ require 'fileutils'
3
+
4
+ def create_file(path, content)
5
+ if File.exist?(path)
6
+ puts "Skipping: #{path} (already exists)"
7
+ else
8
+ File.write(path, content)
9
+ puts "Created: #{path}"
10
+ end
11
+ end
12
+
13
+ puts "--- Ruby Database Infrastructure Scaffolder ---"
14
+
15
+ # 1. Create Directories
16
+ ['db/migrations', 'db/seeds'].each do |dir|
17
+ unless Dir.exist?(dir)
18
+ FileUtils.mkdir_p(dir)
19
+ puts "Created directory: #{dir}"
20
+ end
21
+ end
22
+
23
+ # 2. Templates
24
+ MIGRATE_TEMPLATE = <<~RUBY
25
+ require 'sequel'
26
+ require 'dotenv'
27
+
28
+ # Load environment variables
29
+ Dotenv.load if defined?(Dotenv)
30
+
31
+ DATABASE_URL = ENV['DATABASE_URL']
32
+ MIGRATIONS_DIR = File.expand_path('db/migrations', __dir__)
33
+
34
+ unless DATABASE_URL
35
+ puts "Error: DATABASE_URL environment variable is not set."
36
+ exit 1
37
+ end
38
+
39
+ begin
40
+ unless Dir.exist?(MIGRATIONS_DIR)
41
+ puts "Error: Migrations directory not found at \#{MIGRATIONS_DIR}"
42
+ exit 1
43
+ end
44
+
45
+ if Dir.empty?(MIGRATIONS_DIR)
46
+ puts "Warning: Migrations directory is empty. Nothing to do."
47
+ exit 0
48
+ end
49
+
50
+ puts "Connecting to database..."
51
+ DB = Sequel.connect(DATABASE_URL)
52
+ Sequel.extension :migration
53
+
54
+ # Check for mixed naming styles (Integer vs Timestamp)
55
+ files = Dir.children(MIGRATIONS_DIR).select { |f| f.end_with?('.rb') }
56
+ has_integers = files.any? { |f| f =~ /^\\d{3}_/ }
57
+ has_timestamps = files.any? { |f| f =~ /^\\d{14}_/ }
58
+
59
+ if has_integers && has_timestamps
60
+ puts "FATAL ERROR: Mixed naming styles detected in db/migrations!"
61
+ puts "You have both 001_ style and 2026..._ style files."
62
+ puts "Sequel requires you to use only ONE style. Please delete or rename the timestamped files."
63
+ exit 1
64
+ end
65
+
66
+ # This runs the migrator. IntegerMigrator is used by default for 001_ style files.
67
+ # If a VERSION env var or argument is provided, target that version.
68
+ target = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
69
+
70
+ if target
71
+ puts "Migrating to version \#{target}..."
72
+ Sequel::Migrator.run(DB, MIGRATIONS_DIR, target: target)
73
+ else
74
+ puts "Migrating to latest version..."
75
+ Sequel::Migrator.run(DB, MIGRATIONS_DIR)
76
+ end
77
+
78
+ puts "Database is up to date!"
79
+ rescue => e
80
+ puts "Migration failed: \#{e.message}"
81
+ puts e.backtrace.join("\\n")
82
+ end
83
+ RUBY
84
+
85
+ SEED_TEMPLATE = <<~RUBY
86
+ require 'sequel'
87
+ require 'dotenv'
88
+
89
+ # Load environment variables
90
+ Dotenv.load if defined?(Dotenv)
91
+
92
+ DATABASE_URL = ENV['DATABASE_URL']
93
+ SEEDS_DIR = File.expand_path('db/seeds', __dir__)
94
+
95
+ unless DATABASE_URL
96
+ puts "Error: DATABASE_URL environment variable is not set."
97
+ exit 1
98
+ end
99
+
100
+ # Laravel-style Seeder Runner
101
+ module SeederRunner
102
+ def self.call(db, seeder_class_name)
103
+ # Convert string to class if needed, or handle class directly
104
+ klass = Object.const_get(seeder_class_name)
105
+ instance = klass.new
106
+ instance.run(db)
107
+ rescue NameError
108
+ puts "Error: Seeder class '\#{seeder_class_name}' not found."
109
+ rescue => e
110
+ puts "Error running seeder '\#{seeder_class_name}': \#{e.message}"
111
+ puts e.backtrace.join("\\n")
112
+ end
113
+ end
114
+
115
+ begin
116
+ unless Dir.exist?(SEEDS_DIR)
117
+ puts "Error: Seeds directory not found at \#{SEEDS_DIR}"
118
+ puts "Creating directory structure..."
119
+ Dir.mkdir(SEEDS_DIR)
120
+ end
121
+
122
+ puts "Connecting to database..."
123
+ DB = Sequel.connect(DATABASE_URL)
124
+
125
+ target_argument = ARGV[0] # Optional: ruby seed.rb UserSeeder
126
+
127
+ DB.transaction do
128
+ if target_argument
129
+ # Run a specific seeder class
130
+ file_path = File.join(SEEDS_DIR, "\#{target_argument}.rb")
131
+ if File.exist?(file_path)
132
+ load file_path
133
+ SeederRunner.call(DB, target_argument)
134
+ else
135
+ puts "Error: Seeder file '\#{target_argument}.rb' not found in \#{SEEDS_DIR}"
136
+ exit 1
137
+ end
138
+ else
139
+ # Default behavior: Run DatabaseSeeder (Laravel style)
140
+ db_seeder_path = File.join(SEEDS_DIR, "DatabaseSeeder.rb")
141
+ if File.exist?(db_seeder_path)
142
+ load db_seeder_path
143
+ SeederRunner.call(DB, "DatabaseSeeder")
144
+ else
145
+ # If no DatabaseSeeder, run all files in the folder (backup behavior)
146
+ puts "No DatabaseSeeder.rb found. Running all seeders in db/seeds/..."
147
+ seed_files = Dir.glob(File.join(SEEDS_DIR, '*.rb')).sort
148
+ seed_files.each do |file|
149
+ class_name = File.basename(file, '.rb')
150
+ next if class_name == 'DatabaseSeeder' # prevent double run if it exists but wasn't found (unlikely)
151
+ load file
152
+ SeederRunner.call(DB, class_name)
153
+ end
154
+ end
155
+ end
156
+ end
157
+
158
+ puts "\\nSeeding completed successfully!"
159
+
160
+ rescue => e
161
+ puts "Seeding failed: \#{e.message}"
162
+ puts e.backtrace.join("\\n")
163
+ exit 1
164
+ end
165
+ RUBY
166
+
167
+ MAKE_MIGRATION_TEMPLATE = <<~RUBY
168
+ if ARGV[0].nil?
169
+ puts "Usage: ruby make_migration.rb <name>"
170
+ exit 1
171
+ end
172
+
173
+ migration_name = ARGV[0].gsub(/[^a-zA-Z0-9_]/, '').downcase
174
+
175
+ # Find the next available version number
176
+ migrations_dir = 'db/migrations'
177
+ Dir.mkdir(migrations_dir) unless Dir.exist?(migrations_dir)
178
+
179
+ existing_migrations = Dir.children(migrations_dir).select { |f| f =~ /^\\d{3}_/ }
180
+ max_version = existing_migrations.map { |f| f.split('_').first.to_i }.max || 0
181
+ next_version = format('%03d', max_version + 1)
182
+
183
+ filename = "\#{migrations_dir}/\#{next_version}_\#{migration_name}.rb"
184
+
185
+ content = <<~TEMPLATE
186
+ Sequel.migration do
187
+ up do
188
+ # create_table(:table_name) do
189
+ # primary_key :id
190
+ # end
191
+ end
192
+
193
+ down do
194
+ # drop_table(:table_name)
195
+ end
196
+ end
197
+ TEMPLATE
198
+
199
+ File.write(filename, content)
200
+ puts "Successfully created: \#{filename}"
201
+ RUBY
202
+
203
+ MAKE_SEEDER_TEMPLATE = <<~RUBY
204
+ if ARGV[0].nil?
205
+ puts "Usage: ruby make_seeder.rb <NameSeeder>"
206
+ puts "Example: ruby make_seeder.rb InitialRbacSeeder"
207
+ exit 1
208
+ end
209
+
210
+ # Sanitize the seeder name (remove non-alphanumeric chars, CamelCase it)
211
+ seeder_name = ARGV[0].gsub(/[^a-zA-Z0-9_]/, '').split('_').map(&:capitalize).join
212
+
213
+ # Ensure it ends with Seeder for consistency
214
+ seeder_name += "Seeder" unless seeder_name.end_with?("Seeder")
215
+
216
+ # Ensure the seeds directory exists
217
+ seeds_dir = 'db/seeds'
218
+ Dir.mkdir(seeds_dir) unless Dir.exist?(seeds_dir)
219
+
220
+ filename = "\#{seeds_dir}/\#{seeder_name}.rb"
221
+
222
+ if File.exist?(filename)
223
+ puts "Error: Seeder \#{seeder_name} already exists!"
224
+ exit 1
225
+ end
226
+
227
+ content = <<~TEMPLATE
228
+ class \#{seeder_name}
229
+ def run(db)
230
+ puts "Running seeder: \#{seeder_name}..."
231
+
232
+ # Use the db connection passed to insert data
233
+ # db[:table_name].find_or_create(
234
+ # column: 'value'
235
+ # )
236
+
237
+ puts "Finished seeder: \#{seeder_name}"
238
+ end
239
+ end
240
+ TEMPLATE
241
+
242
+ File.write(filename, content)
243
+ puts "Successfully created: \#{filename}"
244
+ RUBY
245
+
246
+ DATABASE_SEEDER_TEMPLATE = <<~RUBY
247
+ class DatabaseSeeder
248
+ def run(db)
249
+ puts "Starting Database Seeder..."
250
+
251
+ # Pattern: run_seeder(db, 'YourSeederName')
252
+ # run_seeder(db, 'InitialDataSeeder')
253
+
254
+ puts "Database seeding completed!"
255
+ end
256
+
257
+ private
258
+
259
+ def run_seeder(db, class_name)
260
+ file_path = File.join(__dir__, "\#{class_name}.rb")
261
+ if File.exist?(file_path)
262
+ load file_path
263
+ klass = Object.const_get(class_name)
264
+ klass.new.run(db)
265
+ else
266
+ puts "Warning: Seeder file '\#{class_name}.rb' not found."
267
+ end
268
+ end
269
+ end
270
+ RUBY
271
+
272
+ # 3. Write Files
273
+ create_file('migrate.rb', MIGRATE_TEMPLATE)
274
+ create_file('seed.rb', SEED_TEMPLATE)
275
+ create_file('make_migration.rb', MAKE_MIGRATION_TEMPLATE)
276
+ create_file('make_seeder.rb', MAKE_SEEDER_TEMPLATE)
277
+ create_file('db/seeds/DatabaseSeeder.rb', DATABASE_SEEDER_TEMPLATE)
278
+
279
+ puts "\\nSetup complete! You can now use:"
280
+ puts " - ruby make_migration.rb create_users"
281
+ puts " - ruby make_seeder.rb User"
282
+ puts " - ruby migrate.rb"
283
+ puts " - ruby seed.rb"
284
+ puts "\\nEnsure you have 'sequel' and 'dotenv' gems in your Gemfile."
@@ -0,0 +1,3 @@
1
+ module RbDbSetup
2
+ VERSION = "0.1.2"
3
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rb-db-setup
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Lance Daniel Gallos
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-01-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sequel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: dotenv
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Instantly adds hardened Sequel migrations and modular seeders to any
42
+ Ruby project.
43
+ email:
44
+ - lancedanielgallos4@gmail.com
45
+ executables:
46
+ - rb-db-setup
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - README.md
51
+ - bin/rb-db-setup
52
+ - lib/rb_db_setup/version.rb
53
+ homepage: https://github.com/LanceDanielG/rb-db-scaffold-setup
54
+ licenses:
55
+ - MIT
56
+ metadata:
57
+ allowed_push_host: https://rubygems.org
58
+ homepage_uri: https://github.com/LanceDanielG/rb-db-scaffold-setup
59
+ source_code_uri: https://github.com/LanceDanielG/rb-db-scaffold-setup
60
+ changelog_uri: https://github.com/LanceDanielG/rb-db-scaffold-setup/blob/main/CHANGELOG.md
61
+ bug_tracker_uri: https://github.com/LanceDanielG/rb-db-scaffold-setup/issues
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubygems_version: 3.4.19
78
+ signing_key:
79
+ specification_version: 4
80
+ summary: A Laravel-style database infrastructure scaffolder for Ruby.
81
+ test_files: []