Module: Hammer::Builtins
- Defined in:
- lib/hammer/builtins.rb
Overview
Built-in tasks of the ‘hammer` binary. Everything but :default lives under the reserved `h:` namespace (e.g. `hammer h:update`, `hammer h:recipes`) so the built-ins never collide with a project’s own root tasks. Only the bare ‘hammer` invocation and the `-h`/`–help`/`help` request are handled at root - bare fires :default, which also carries the `–version` convenience flag.
Defined Under Namespace
Modules: RecipesActions
Class Method Summary collapse
-
.register(klass) ⇒ Object
Single registration entry point - identical in every context (project Hammerfile or bare ‘hammer` binary).
- .register_agents(klass) ⇒ Object
-
.register_default(klass) ⇒ Object
‘:default` fires on bare `hammer` and on leading-flag invocations (other than -h/–help).
- .register_help(klass) ⇒ Object
- .register_init(klass) ⇒ Object
-
.register_recipes(klass) ⇒ Object
‘:recipes` rolls all recipe-management actions into one task.
- .register_update(klass) ⇒ Object
- .register_version(klass) ⇒ Object
-
.write_starter_hammerfile ⇒ Object
Writes ./Hammerfile with the canonical starter template.
Class Method Details
.register(klass) ⇒ Object
Single registration entry point - identical in every context (project Hammerfile or bare ‘hammer` binary). Namespacing under `h:` removes the old collision worries, so there’s no core vs no-project split and no hidden-desc dance: the same tasks register everywhere, always dispatchable, and surface in the listing only under the extended ‘–help` view (the `@builtin_namespace` flag).
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/hammer/builtins.rb', line 17 def register(klass) register_default(klass) unless klass.commands.key?('default') existed = klass.namespaces.key?('h') klass.namespace(:h) {} # ensure/reopen the reserved subclass h = klass.namespaces['h'] # Flag the tree so the compact listing prunes it - the built-ins # only show under the extended `--help` view (always dispatchable). # Skip when the user already owns an `h:` namespace, so their own # tasks stay visible in the bare listing. h.instance_variable_set(:@builtin_namespace, true) unless existed register_help(h) unless h.commands.key?('help') register_update(h) unless h.commands.key?('update') register_agents(h) unless h.commands.key?('agents') register_version(h) unless h.commands.key?('version') register_recipes(h) unless h.commands.key?('recipes') register_init(h) unless h.commands.key?('init') end |
.register_agents(klass) ⇒ Object
88 89 90 91 92 93 94 95 |
# File 'lib/hammer/builtins.rb', line 88 def register_agents(klass) klass.class_eval do task :agents do desc 'Print AGENTS.md (Hammerfile authoring docs for AI assistants)' proc { Hammer.print_ai_help } end end end |
.register_default(klass) ⇒ Object
‘:default` fires on bare `hammer` and on leading-flag invocations (other than -h/–help). Hidden from listings (no desc). All it does now is print help - the old flag opts (–update, –ai, …) moved to dedicated tasks (:update, :agents, …).
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/hammer/builtins.rb', line 61 def register_default(klass) klass.class_eval do task :default do opt :version, type: :boolean, alias: :v, desc: 'print lux-hammer version' # Inlined rather than dispatched to :version - going through # `hammer :version` would print the gray run banner. The # implementation is one line; not worth the indirection. proc do |opts| if opts[:version] puts Hammer::VERSION else self.class.root.print_help end end end end end |
.register_help(klass) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/hammer/builtins.rb', line 36 def register_help(klass) klass.class_eval do task :help do desc <<~TXT Show help. Optional TARGET = command name or namespace (`ns:`). Without TARGET prints the extended top-level help (commands, recipes, global flags, examples). With a command path prints per-command help; with a namespace prefix prints that namespace's command listing. TXT example 'h:help' example 'h:help build' example 'h:help db:' proc do |opts| self.class.root.print_help(opts[:args].first, extended: true) end end end end |
.register_init(klass) ⇒ Object
106 107 108 109 110 111 112 113 |
# File 'lib/hammer/builtins.rb', line 106 def register_init(klass) klass.class_eval do task :init do desc 'Write a starter Hammerfile in the current directory' proc { Hammer::Builtins.write_starter_hammerfile } end end end |
.register_recipes(klass) ⇒ Object
‘:recipes` rolls all recipe-management actions into one task. Bare invocation lists; opts pick the action and positional args carry the recipe name (and optional target path for –install). Run via `–run NAME [ARGS]` - use `–` to forward flags to the recipe itself (e.g. `hammer h:recipes –run srt – –help`).
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/hammer/builtins.rb', line 120 def register_recipes(klass) klass.class_eval do task :recipes do desc <<~TXT Manage recipes - the standalone Hammerfile-style scripts bundled with the gem (and under ~/.config/hammer/recipes). Bare invocation lists; flags pick the action. TXT opt :install, type: :boolean, desc: 'install recipe stub (picker if no NAME). With TARGET path: write + chmod.' opt :show, type: :boolean, desc: 'cat recipe source' opt :path, type: :boolean, desc: 'print recipe abs path' opt :edit, type: :boolean, desc: 'open recipe in $EDITOR (copies gem -> user dir first)' opt :run, type: :boolean, desc: 'run a recipe without installing its bin (forwards remaining args)' example 'h:recipes' example 'h:recipes --install srt ~/bin/srt # write + chmod in one shot' example 'h:recipes --install srt > ~/bin/srt && chmod +x $_' example 'h:recipes --show srt' example 'h:recipes --run srt extract movie.mp4' example 'h:recipes --run srt -- --help # -- forwards flags to the recipe' proc do |opts| args = opts[:args] if opts[:install] Hammer::Builtins::RecipesActions.install(args[0], args[1]) elsif opts[:show] Hammer::Builtins::RecipesActions.show(Hammer::Builtins::RecipesActions.require_name!(args[0], 'show')) elsif opts[:path] Hammer::Builtins::RecipesActions.path(Hammer::Builtins::RecipesActions.require_name!(args[0], 'path')) elsif opts[:edit] Hammer::Builtins::RecipesActions.edit(Hammer::Builtins::RecipesActions.require_name!(args[0], 'edit')) elsif opts[:run] name = Hammer::Builtins::RecipesActions.require_name!(args[0], 'run') Hammer.recipe(name, args[1..]) else Hammer::Builtins::RecipesActions.list end end end end end |
.register_update(klass) ⇒ Object
79 80 81 82 83 84 85 86 |
# File 'lib/hammer/builtins.rb', line 79 def register_update(klass) klass.class_eval do task :update do desc 'Rebuild + reinstall lux-hammer from main' proc { Hammer.self_update } end end end |
.register_version(klass) ⇒ Object
97 98 99 100 101 102 103 104 |
# File 'lib/hammer/builtins.rb', line 97 def register_version(klass) klass.class_eval do task :version do desc 'Print lux-hammer version' proc { puts Hammer::VERSION } end end end |
.write_starter_hammerfile ⇒ Object
Writes ./Hammerfile with the canonical starter template. Refuses if one already exists - ‘init` must not clobber.
162 163 164 165 166 167 168 169 170 |
# File 'lib/hammer/builtins.rb', line 162 def write_starter_hammerfile target = File.join(Dir.pwd, 'Hammerfile') if File.exist?(target) Shell.print_error "Hammerfile already exists at #{target}" exit 1 end File.write(target, Hammer::STARTER_HAMMERFILE) Shell.say "created #{target}", :green end |