Class: Tina4::CLI
- Inherits:
-
Object
- Object
- Tina4::CLI
- Defined in:
- lib/tina4/cli.rb
Constant Summary collapse
- GENERATORS =
── Command registries — the single source of truth ─────────────────
ONE entry per command/generator drives dispatch (#run / #cmd_generate), the human help (#cmd_help), AND the machine-readable manifest (
commands --json). Add a command in ONE place and it appears in dispatch, help, and discovery — there is no second list to sync. Ruby mirror of the Python master's COMMANDS / GENERATORS registries (tina4_python/cli/init.py).GENERATORS[name] = { handler: :method_symbol, usage: str, summary: str } COMMANDS[name] = { handler: :method_symbol, summary: str, usage?: str, # arg/flag hint for #cmd_help (human only) args?: [str], # positional args for the manifest ("x?" = optional) subcommands?: [str] } # sub-names for the manifest (generate)Handlers are instance-method symbols dispatched via #send: GENERATORS handlers take (name, flags); COMMANDS handlers take (argv).
{ "model" => { handler: :generate_model, usage: '<Name> [--fields "name:string,price:float"]', summary: "ORM model + matching migration" }, "route" => { handler: :generate_route, usage: "<name> [--model Name] [--public]", summary: "CRUD route file, secure by default (--public opens writes)" }, "crud" => { handler: :generate_crud, usage: '<Name> [--fields "..."] [--public]', summary: "Model + migration + routes + form + view + test" }, "migration" => { handler: :generate_migration, usage: "<description>", summary: "Timestamped migration file (UP/DOWN)" }, "middleware" => { handler: :generate_middleware, usage: "<Name>", summary: "Middleware with before/after hooks" }, "test" => { handler: :generate_test, usage: "<name> [--model Name]", summary: "RSpec test file" }, "form" => { handler: :generate_form, usage: '<Name> [--fields "..."]', summary: "Form template with inputs matching model fields" }, "view" => { handler: :generate_view, usage: '<Name> [--fields "..."]', summary: "List + detail view templates" }, "auth" => { handler: :generate_auth, usage: "", summary: "Login/register routes + User model + templates" }, "service" => { handler: :generate_service, usage: '<Name> [--every 5m | --cron "..."]', summary: "Scheduled ServiceRunner task (src/services/)" }, "queue" => { handler: :generate_queue, usage: "<topic>", summary: "Producer + consumer worker (src/services/)" }, "validator" => { handler: :generate_validator, usage: "<Name>", summary: "Request-body Validator (src/validators/)" }, "seeder" => { handler: :generate_seeder, usage: "<Model>", summary: "FakeData + seed_orm seeder (seeds/)" }, "websocket" => { handler: :generate_websocket, usage: "<path>", summary: "Tina4.websocket handler (src/routes/)" }, "listener" => { handler: :generate_listener, usage: "<event>", summary: "Tina4::Events.on listener (src/listeners/)" }, }.freeze
- QUEUE_SUBCOMMANDS =
Sub-dispatch table for the top-level
queuecommand — the SINGLE source for its subcommands (drives #cmd_queue dispatch AND the manifest's queue.subcommands). Ruby mirror of the Python master's _QUEUE_SUBCOMMANDS. Distinct from thequeueGENERATOR, which SCAFFOLDS a consumer file. { "work" => :queue_work, "stats" => :queue_stats, "retry" => :queue_retry, "clear" => :queue_clear, }.freeze
- COMMANDS =
{ "init" => { handler: :cmd_init, usage: "[NAME]", args: ["name?"], summary: "Initialize a new Tina4 project" }, "start" => { handler: :cmd_start, usage: "[options]", summary: "Start the Tina4 web server" }, "serve" => { handler: :cmd_start, summary: "Alias for start" }, "migrate" => { handler: :cmd_migrate, usage: "[--create NAME] [--rollback N]", summary: "Run database migrations" }, "migrate:create" => { handler: :cmd_migrate_create, usage: "<desc>", args: ["description"], summary: "Create a new migration file" }, "migrate:status" => { handler: :cmd_migrate_status, summary: "Show migration status (completed and pending)" }, "migrate:rollback" => { handler: :cmd_migrate_rollback, usage: "[-n N]", summary: "Rollback the last batch of migrations" }, "seed" => { handler: :cmd_seed, usage: "[--clear]", summary: "Run all seed files in seeds/" }, "seed:create" => { handler: :cmd_seed_create, usage: "NAME", args: ["name"], summary: "Create a new seed file" }, "test" => { handler: :cmd_test, summary: "Run inline tests" }, "queue" => { handler: :cmd_queue, usage: "<work|stats|retry|clear> [topic]", subcommands: QUEUE_SUBCOMMANDS.keys, summary: "Run queue workers and manage jobs" }, "build" => { handler: :cmd_build, usage: "[--tag NAME] [--file PATH]", summary: "Build the deployable Docker image" }, "version" => { handler: :cmd_version, summary: "Show Tina4 version" }, "routes" => { handler: :cmd_routes, summary: "List all registered routes" }, "console" => { handler: :cmd_console, summary: "Start an interactive console" }, "generate" => { handler: :cmd_generate, usage: "<what> <name> [options]", subcommands: GENERATORS.keys, summary: "Generate scaffolding (see Generators below)" }, "ai" => { handler: :cmd_ai, usage: "[--all]", summary: "Detect AI tools and install context files" }, "metrics" => { handler: :cmd_metrics, usage: "[--top N] [--json] [--fail-on warn|error] [--path DIR]", summary: "Rank top code-quality offenders" }, "commands" => { handler: :cmd_commands, usage: "[--json]", summary: "List available commands (add --json for machine form)" }, "help" => { handler: :cmd_help, summary: "Show this help message" }, }.freeze
- FIELD_TYPE_MAP =
── Field type mapping ──────────────────────────────────────────────
{ "string" => { orm: "string_field", sql: "VARCHAR(255)", default: "''" }, "str" => { orm: "string_field", sql: "VARCHAR(255)", default: "''" }, "int" => { orm: "integer_field", sql: "INTEGER", default: "0" }, "integer" => { orm: "integer_field", sql: "INTEGER", default: "0" }, "float" => { orm: "float_field", sql: "REAL", default: "0" }, "numeric" => { orm: "float_field", sql: "REAL", default: "0" }, "decimal" => { orm: "float_field", sql: "REAL", default: "0" }, "bool" => { orm: "boolean_field", sql: "INTEGER", default: "0" }, "boolean" => { orm: "boolean_field", sql: "INTEGER", default: "0" }, "text" => { orm: "string_field", sql: "TEXT", default: "''" }, "datetime" => { orm: "string_field", sql: "TEXT", default: "NULL" }, "blob" => { orm: "string_field", sql: "BLOB", default: "NULL" }, }.freeze
Class Method Summary collapse
Instance Method Summary collapse
Class Method Details
.start(argv) ⇒ Object
94 95 96 |
# File 'lib/tina4/cli.rb', line 94 def self.start(argv) new.run(argv) end |
Instance Method Details
#run(argv) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/tina4/cli.rb', line 98 def run(argv) command = argv.shift || "help" command = "help" if %w[-h --help].include?(command) # Dispatch from the single-source-of-truth COMMANDS registry. The same # registry drives #cmd_help and the `commands --json` manifest, so # dispatch, help, and discovery never drift. spec = COMMANDS[command] if spec send(spec[:handler], argv) else puts "Unknown command: #{command}" cmd_help exit 1 end end |