hyraft-rule 0.1.0.alpha1

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: 7354edfc544227b3eb8c6dfdfa552f8ccc4764a763e975028d423657a851c417
4
+ data.tar.gz: 02cb548060b83aa6f3516826d08cfc649663733fdf4469155b59608a31089279
5
+ SHA512:
6
+ metadata.gz: c9c71f2963cf91e915bfcde8531985e4105dee516e8ffd472f83d64956add49536a149bb14678285fc5e22e75e0d34b891668f4dfcbbd28ee612f657d8b2346e
7
+ data.tar.gz: 361550c41628c903ee91f16c491e6bacf106b4ebf5f001e6b1be9310e8369ce37a1a08aca4e95e8cd930f06208e5d37c75540ef5e986421c57c9c62e4336fce9
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2025-11-12
4
+
5
+ - Initial release
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Hyraft-rule Demjhon Silver
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,239 @@
1
+
2
+ <div align="center">
3
+
4
+ # Hyraft Rule
5
+
6
+ [![Gem Version](https://badge.fury.io/rb/hyraft-rule.svg?icon=si%3Arubygems&icon_color=%23ffffff)](https://badge.fury.io/rb/hyraft-rule)
7
+ ![Downloads](https://img.shields.io/gem/dt/hyraft-rule)
8
+ ![License](https://img.shields.io/github/license/demjhonsilver/hyraft-rule)
9
+ ![Ruby Version](https://img.shields.io/badge/ruby-%3E%3D%203.4.0-red)
10
+
11
+ </div>
12
+
13
+
14
+
15
+
16
+ # Hyraft Rule - ( CLI ) Command system for Hyraft applications
17
+
18
+
19
+ A standalone command system (cli) for Hyraft applications.
20
+
21
+ ## Installation
22
+
23
+ Open Gemfile:
24
+ put:
25
+
26
+ ```bash
27
+ gem 'hyraft-rule'
28
+ ```
29
+
30
+ Install the gem and add to the application's Gemfile by executing:
31
+
32
+ ```bash
33
+ bundle install
34
+ ```
35
+
36
+ ## Usage ( Assemble / Disassemble )
37
+ - hyr-rule
38
+
39
+ Package setup:
40
+
41
+ ```bash
42
+ # Default web-app
43
+ hyr-rule assemble articles
44
+ hyr-rule disassemble articles
45
+
46
+ # Specific app folders
47
+
48
+ hyr-rule assemble {any-folder-name}/users
49
+
50
+
51
+ hyr-rule assemble admin-app/users
52
+ hyr-rule disassemble admin-app/users
53
+
54
+ hyr-rule assemble api_app/products
55
+ hyr-rule disassemble api_app/products
56
+ ```
57
+
58
+
59
+
60
+ ## Usage ( Engine )
61
+ - hyr-rule
62
+
63
+ Generate:
64
+
65
+ ```bash
66
+
67
+ hyr-rule circuit articles
68
+
69
+ hyr-rule port articles
70
+
71
+ hyr-rule source article
72
+
73
+ ```
74
+
75
+ ## Usage ( Web Adapter )
76
+ - hyr-rule
77
+
78
+ Generate:
79
+
80
+ ```bash
81
+ hyr-rule web-adapter articles
82
+ hyr-rule web-adapter admin-app/products
83
+ ```
84
+
85
+ ## Usage ( data-gateway )
86
+ - hyr-rule
87
+
88
+ Generate:
89
+
90
+ ```bash
91
+ hyr-rule data-gateway articles
92
+ hyr-rule data-gateway admin-app/products
93
+ ```
94
+
95
+
96
+
97
+
98
+ ## Usage ( Templates )
99
+ - hyr-rule
100
+
101
+ Generate:
102
+
103
+ ```bash
104
+
105
+ hyr-rule template articles
106
+ hyraft-rule template articles
107
+
108
+ hyr-rule template admin-app/users
109
+ hyraft-rule template admin-app/users
110
+ ```
111
+
112
+ ## Usage ( For Help )
113
+ - hyr-rule
114
+
115
+ Generate:
116
+
117
+ ```bash
118
+
119
+ hyr-rule h
120
+
121
+ hyr-rule help
122
+
123
+ hyr-rule -h
124
+
125
+ hyraft-rule h
126
+
127
+ hyraft-rule help
128
+
129
+ hyraft-rule -h
130
+
131
+ ```
132
+
133
+
134
+ ## Usage ( Database )
135
+ - hyr-rule-db
136
+
137
+
138
+ Schema:
139
+
140
+
141
+ ```bash
142
+ hyr-rule-db generate create_users
143
+ hyr-rule-db generate add_email_to_users
144
+
145
+ - Migration Generation Schema Examples:
146
+
147
+ hyr-rule-db generate create_users
148
+ hyr-rule-db generate create_articles
149
+ hyr-rule-db generate create_products
150
+ hyr-rule-db generate create_categories
151
+ hyr-rule-db generate add_image_file_to_articles
152
+ hyr-rule-db generate add_price_to_products
153
+ hyr-rule-db generate remove_status_from_posts
154
+ hyr-rule-db generate drop_old_tables
155
+
156
+
157
+ Examples:
158
+ hyr-rule-db generate create_articles title content:text
159
+
160
+ hyr-rule-db generate create_products name:string price:decimal description:text user_id:int
161
+ hyr-rule-db generate create_users username:string age:int email:string active:bool created_at:datetime
162
+
163
+ hyr-rule-db generate create_products name:string price:decimal description:text user_id:int
164
+ hyr-rule-db generate create_users username age:int email active:bool
165
+ hyr-rule-db generate create_articles title content:text published_at:datetime views:int
166
+
167
+
168
+ ```
169
+ Migrations:
170
+
171
+ ```bash
172
+ Hyraft Rule Database Commands
173
+
174
+ Commands:
175
+
176
+ migrate, up - Run all pending migrations
177
+ rollback, down - Rollback all migrations
178
+ status - Show migration status
179
+ reset - Rollback and re-run all migrations
180
+ generate <name> - Create a new migration file
181
+ help - Show this help
182
+
183
+ Examples:
184
+
185
+ hyr-rule-db migrate
186
+ hyr-rule-db status
187
+ hyr-rule-db rollback
188
+ hyr-rule-db reset
189
+ hyr-rule-db help
190
+
191
+ Environment Usage:
192
+
193
+ hyr-rule-db migrate # Current environment (run: hyr s thin)
194
+ APP_ENV=test hyr-rule-db migrate # Test environment (run: APP_ENV=test hyr s thin)
195
+ APP_ENV=development hyr-rule-db migrate # Development environment (run: APP_ENV=development hyr s thin)
196
+ APP_ENV=production hyr-rule-db migrate # Production environment (run: APP_ENV=production hyr s thin)
197
+
198
+ Quick Reference:
199
+
200
+ # Generate and run migrations for a new table
201
+ hyr-rule-db generate create_users
202
+ hyr-rule-db migrate
203
+
204
+ # Add a column to existing table
205
+ hyr-rule-db generate add_email_to_users
206
+ hyr-rule-db migrate
207
+
208
+ # Check what needs to be applied
209
+ hyr-rule-db status
210
+
211
+ # Rollback if something went wrong
212
+ hyr-rule-db rollback
213
+
214
+ ```
215
+
216
+
217
+
218
+
219
+
220
+
221
+
222
+
223
+ ## Development
224
+
225
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
226
+
227
+ 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).
228
+
229
+ ## Contributing
230
+
231
+ Bug reports and pull requests are welcome on GitHub at https://github.com/demjhonsilver/hyraft-rule. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/demjhonsilver/hyraft-rule/blob/master/CODE_OF_CONDUCT.md).
232
+
233
+ ## License
234
+
235
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
236
+
237
+ ## Code of Conduct
238
+
239
+ Everyone interacting in the Hyraft::Rule project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/demjhonsilver/hyraft-rule/blob/master/CODE_OF_CONDUCT.md).
data/exe/hyr-rule ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Short alias for hyraft-rule
4
+ exec("hyraft-rule", *ARGV)
data/exe/hyr-rule-db ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Short alias for hyraft-rule-db
4
+ exec("hyraft-rule-db", *ARGV)
data/exe/hyraft-rule ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "hyraft/rule"
5
+
6
+ Hyraft::Rule::Command.start(ARGV)
@@ -0,0 +1,404 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'fileutils'
5
+ require 'sequel'
6
+
7
+ # -------------------------------
8
+ # Helper: find application root
9
+ # -------------------------------
10
+ def find_app_root
11
+ dir = Dir.pwd
12
+ while dir != '/'
13
+ boot_path = File.join(dir, 'boot.rb')
14
+ return dir if File.exist?(boot_path)
15
+ dir = File.dirname(dir)
16
+ end
17
+ nil
18
+ end
19
+
20
+ APP_ROOT = find_app_root
21
+
22
+ if APP_ROOT.nil?
23
+ puts "❌ Error: Could not find boot.rb"
24
+ puts "Please run from your Hyraft application directory"
25
+ exit 1
26
+ end
27
+
28
+ $LOAD_PATH.unshift(APP_ROOT) unless $LOAD_PATH.include?(APP_ROOT)
29
+
30
+ begin
31
+ require File.join(APP_ROOT, 'boot')
32
+ require File.join(APP_ROOT, 'infra', 'database', 'sequel_connection')
33
+ rescue LoadError => e
34
+ puts "❌ Error loading dependencies: #{e.message}"
35
+ exit 1
36
+ end
37
+
38
+ begin
39
+ Sequel.extension :migration
40
+ DB = SequelConnection.db
41
+ DB.test_connection
42
+ rescue => e
43
+ puts "❌ Database connection failed: #{e.message}"
44
+ exit 1
45
+ end
46
+
47
+ MIGRATIONS_DIR = File.join(APP_ROOT, 'infra', 'database', 'migrations')
48
+
49
+ # -------------------------------
50
+ # Generate Migration Methods
51
+ # -------------------------------
52
+ def generate_migration(migration_name, *columns)
53
+ timestamp = Time.now.strftime("%Y%m%d%H%M%S")
54
+ filename = "#{timestamp}_#{migration_name}.rb"
55
+ full_path = File.join(MIGRATIONS_DIR, filename)
56
+
57
+ FileUtils.mkdir_p(MIGRATIONS_DIR)
58
+
59
+ table_name = extract_table_name(migration_name)
60
+ migration_content = if migration_name.start_with?('create_') && table_name
61
+ create_table_template(table_name, *columns)
62
+ else
63
+ migration_template(migration_name)
64
+ end
65
+
66
+ File.write(full_path, migration_content)
67
+
68
+ puts "✓ Created migration: #{full_path}"
69
+ puts "Table name detected: #{table_name}" if table_name
70
+
71
+ if columns.any?
72
+ puts "Columns added: #{columns.join(', ')}"
73
+ end
74
+
75
+ puts ""
76
+ puts "To apply this migration, run one of these:"
77
+ puts " hyr-rule-db migrate # Development environment (default)"
78
+ puts " APP_ENV=test hyr-rule-db migrate # For test environment"
79
+ puts " APP_ENV=development hyr-rule-db migrate # For development environment"
80
+ puts " APP_ENV=production hyr-rule-db migrate # For production environment"
81
+ end
82
+
83
+ def extract_table_name(migration_name)
84
+ case migration_name
85
+ when /^create_(.+)$/
86
+ $1
87
+ when /^add_(.+)_to_(.+)$/
88
+ $2
89
+ when /^remove_(.+)_from_(.+)$/
90
+ $2
91
+ when /^drop_(.+)$/
92
+ $1
93
+ else
94
+ nil
95
+ end
96
+ end
97
+
98
+ def migration_template(migration_name)
99
+ table_name = extract_table_name(migration_name)
100
+
101
+ if migration_name.start_with?('create_') && table_name
102
+ create_table_template(table_name)
103
+ elsif migration_name.start_with?('add_') && table_name
104
+ column_name = migration_name.match(/^add_(.+)_to_#{table_name}$/)[1]
105
+ add_column_template(table_name, column_name)
106
+ elsif migration_name.start_with?('remove_') && table_name
107
+ column_name = migration_name.match(/^remove_(.+)_from_#{table_name}$/)[1]
108
+ remove_column_template(table_name, column_name)
109
+ elsif migration_name.start_with?('drop_') && table_name
110
+ drop_table_template(table_name)
111
+ else
112
+ generic_template(migration_name)
113
+ end
114
+ end
115
+
116
+
117
+ def create_table_template(table_name, *columns)
118
+ # Parse columns with data types (format: name:string, age:int, price:decimal)
119
+ columns_code = if columns.any?
120
+ columns.map do |col|
121
+ if col.include?(':')
122
+ col_name, col_type = col.split(':', 2)
123
+ case col_type.downcase
124
+ when 'int', 'integer'
125
+ "Integer :#{col_name}, null: false"
126
+ when 'string', 'str', 'varchar', 'var'
127
+ "String :#{col_name}, size: 255, null: false"
128
+ when 'text'
129
+ "String :#{col_name}, text: true, null: false"
130
+ when 'decimal', 'float', 'numeric'
131
+ "Decimal :#{col_name}, size: [10, 2], null: false"
132
+ when 'bool', 'boolean'
133
+ "TrueClass :#{col_name}, null: false"
134
+ when 'date'
135
+ "Date :#{col_name}, null: false"
136
+ when 'datetime', 'timestamp'
137
+ "DateTime :#{col_name}, null: false"
138
+ else
139
+ "String :#{col_name}, size: 255, null: false" # default fallback
140
+ end
141
+ else
142
+ # Default to string if no type specified
143
+ "String :#{col}, size: 255, null: false"
144
+ end
145
+ end.map { |line| " #{line}" }.join("\n")
146
+ else
147
+ " # Add #{table_name} columns here"
148
+ end
149
+
150
+ <<~RUBY
151
+ Sequel.migration do
152
+ up do
153
+ create_table(:#{table_name}) do
154
+ primary_key :id, type: :bigint
155
+ #{columns_code}
156
+
157
+ DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP
158
+ DateTime :updated_at, default: Sequel::CURRENT_TIMESTAMP
159
+ end
160
+ end
161
+
162
+ down do
163
+ drop_table(:#{table_name})
164
+ end
165
+ end
166
+ RUBY
167
+ end
168
+
169
+
170
+
171
+
172
+
173
+
174
+
175
+
176
+ def add_column_template(table_name, column_name)
177
+ <<~RUBY
178
+ Sequel.migration do
179
+ change do
180
+ alter_table(:#{table_name}) do
181
+ add_column :#{column_name}, String
182
+ end
183
+ end
184
+ end
185
+ RUBY
186
+ end
187
+
188
+
189
+
190
+
191
+
192
+ def remove_column_template(table_name, column_name)
193
+ <<~RUBY
194
+ Sequel.migration do
195
+ change do
196
+ alter_table(:#{table_name}) do
197
+ drop_column :#{column_name}
198
+ end
199
+ end
200
+ end
201
+ RUBY
202
+ end
203
+
204
+ def drop_table_template(table_name)
205
+ <<~RUBY
206
+ Sequel.migration do
207
+ change do
208
+ drop_table(:#{table_name})
209
+ end
210
+ end
211
+ RUBY
212
+ end
213
+
214
+ def generic_template(migration_name)
215
+ <<~RUBY
216
+ Sequel.migration do
217
+ change do
218
+ # Migration: #{migration_name}
219
+ # Add your custom migration code here
220
+ end
221
+ end
222
+ RUBY
223
+ end
224
+
225
+ # -------------------------------
226
+ # Migration methods
227
+ # -------------------------------
228
+
229
+ def run_migrations
230
+ migration_files = Dir.glob(File.join(MIGRATIONS_DIR, "[0-9]*_*.rb")).sort
231
+ if migration_files.empty?
232
+ puts "No migration files found in #{MIGRATIONS_DIR}"
233
+ return
234
+ end
235
+
236
+ begin
237
+ # Get current applied migrations before migration
238
+ applied_before = if DB.table_exists?(:schema_migrations)
239
+ DB[:schema_migrations].order(:filename).map { |r| r[:filename].gsub('.rb', '') }
240
+ else
241
+ []
242
+ end
243
+
244
+ # Run migrations
245
+ Sequel::Migrator.run(DB, MIGRATIONS_DIR)
246
+
247
+ # Get applied migrations after migration
248
+ applied_after = if DB.table_exists?(:schema_migrations)
249
+ DB[:schema_migrations].order(:filename).map { |r| r[:filename].gsub('.rb', '') }
250
+ else
251
+ []
252
+ end
253
+
254
+ # Find which migrations were just applied
255
+ newly_applied = applied_after - applied_before
256
+
257
+ if newly_applied.empty?
258
+ puts "✓ All files migrated successfully: no pending migrations"
259
+ else
260
+ if newly_applied.size == 1
261
+ puts "✓ Migration applied successfully: #{newly_applied.first}"
262
+ else
263
+ puts "✓ #{newly_applied.size} migrations applied successfully:"
264
+ newly_applied.each { |migration| puts " - #{migration}" }
265
+ end
266
+ end
267
+ rescue => e
268
+ puts "✗ Migration failed: #{e.message}"
269
+ exit 1
270
+ end
271
+ end
272
+
273
+
274
+
275
+
276
+ def rollback_migrations
277
+ puts "Rolling back all migrations..."
278
+ begin
279
+ Sequel::Migrator.run(DB, MIGRATIONS_DIR, target: 0)
280
+ puts "✓ Rollback completed successfully"
281
+ rescue => e
282
+ puts "✗ Rollback failed: #{e.message}"
283
+ exit 1
284
+ end
285
+ end
286
+
287
+ def show_status
288
+ puts "Migration Status:"
289
+ puts "Database: #{DB.opts[:database]}"
290
+
291
+ migration_files = Dir.glob(File.join(MIGRATIONS_DIR, "[0-9]*_*.rb")).sort
292
+
293
+ if DB.table_exists?(:schema_migrations)
294
+ applied_migrations = DB[:schema_migrations].order(:filename).map { |r| r[:filename].gsub('.rb', '') }
295
+ latest = applied_migrations.last
296
+ puts "Schema migrations table: ✓ created"
297
+ puts "Latest applied migration: #{latest || 'none'}"
298
+ puts "Applied migrations: #{applied_migrations.size} of #{migration_files.size}"
299
+
300
+ # Show pending migrations
301
+ pending_migrations = migration_files.reject do |file|
302
+ filename = File.basename(file, '.rb')
303
+ applied_migrations.include?(filename)
304
+ end
305
+
306
+ if pending_migrations.any?
307
+ puts "\nPending migrations:"
308
+ pending_migrations.each { |f| puts " - #{File.basename(f)}" }
309
+ puts "\nRun one of these to apply pending migrations:"
310
+ puts " hyr-rule-db migrate # Development environment (default)"
311
+ puts " APP_ENV=test hyr-rule-db migrate # For test environment"
312
+ puts " APP_ENV=development hyr-rule-db migrate # For development environment"
313
+ puts " APP_ENV=production hyr-rule-db migrate # For production environment"
314
+ else
315
+ puts "✓ All migrations are applied"
316
+ end
317
+ else
318
+ puts "Schema migrations table: ○ not created yet"
319
+ puts "Latest applied migration: none"
320
+
321
+ if migration_files.any?
322
+ puts "\nMigration files:"
323
+ migration_files.each { |f| puts " - #{File.basename(f)}" }
324
+ puts "\nRun one of these to apply pending migrations:"
325
+ puts " hyr-rule-db migrate # For development environment"
326
+ puts " APP_ENV=test hyr-rule-db migrate # For test environment"
327
+ puts " APP_ENV=development hyr-rule-db migrate # For development environment"
328
+ puts " APP_ENV=production hyr-rule-db migrate # For production environment"
329
+ else
330
+ puts "No migration files found in #{MIGRATIONS_DIR}"
331
+ end
332
+ end
333
+ end
334
+
335
+
336
+ def show_help
337
+ puts <<~HELP
338
+ Hyraft Rule Database Commands
339
+ Commands:
340
+ migrate, up - Run all pending migrations
341
+ rollback, down - Rollback all migrations
342
+ status - Show migration status
343
+ reset - Rollback and re-run all migrations
344
+ generate <name> - Create a new migration file
345
+ help - Show this help
346
+
347
+ Examples:
348
+ hyr-rule-db migrate
349
+ hyr-rule-db status
350
+ hyr-rule-db generate create_users
351
+ hyr-rule-db generate create_articles title content published_at
352
+ hyr-rule-db generate create_products name price description user_id
353
+
354
+ Migration Generation Examples:
355
+ hyr-rule-db generate create_users
356
+ hyr-rule-db generate create_articles title content published_at
357
+ hyr-rule-db generate create_products name price description
358
+ hyr-rule-db generate create_orders user_id total_amount status
359
+ hyr-rule-db generate add_email_to_users
360
+ hyr-rule-db generate remove_status_from_posts
361
+ hyr-rule-db generate drop_old_tables
362
+ HELP
363
+ end
364
+
365
+ # -------------------------------
366
+ # Main execution
367
+ # -------------------------------
368
+ command = ARGV[0] || "help"
369
+ migration_name = ARGV[1]
370
+
371
+ case command
372
+ when "migrate", "up"
373
+ run_migrations
374
+ when "rollback", "down"
375
+ rollback_migrations
376
+ when "status"
377
+ show_status
378
+ when "reset"
379
+ rollback_migrations
380
+ run_migrations
381
+ when "generate", "g"
382
+ if ARGV[1]
383
+ migration_name = ARGV[1]
384
+ columns = ARGV[2..-1] || [] # Get all remaining arguments as columns
385
+ generate_migration(migration_name, *columns)
386
+ else
387
+ puts "Error: Migration name required"
388
+ puts ""
389
+ puts "Usage: hyr-rule-db generate <migration_name> [column1 column2 ...]"
390
+ puts ""
391
+ puts "Examples:"
392
+ puts " hyr-rule-db generate create_users"
393
+ puts " hyr-rule-db generate create_products name price description"
394
+ puts " hyr-rule-db generate create_orders user_id total_amount status"
395
+ puts " hyr-rule-db generate add_email_to_users"
396
+ exit 1
397
+ end
398
+ when "help", "-h", "--help"
399
+ show_help
400
+ else
401
+ puts "Unknown command: #{command}"
402
+ show_help
403
+ exit 1
404
+ end