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_json(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 35 |
# 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') register_json(h) unless h.commands.key?('json') end |
.register_agents(klass) ⇒ Object
89 90 91 92 93 94 95 96 |
# File 'lib/hammer/builtins.rb', line 89 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, …).
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/hammer/builtins.rb', line 62 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
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/hammer/builtins.rb', line 37 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
107 108 109 110 111 112 113 114 |
# File 'lib/hammer/builtins.rb', line 107 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_json(klass) ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/hammer/builtins.rb', line 116 def register_json(klass) klass.class_eval do task :json do desc <<~TXT Dump the CLI definition as JSON: tasks grouped exactly like the bare-`hammer` listing, each with desc, options, examples, aliases, needs. Consumed by the macOS GUI and any tooling that wants the full Hammerfile spec. TXT example 'h:json' example 'h:json --all # include the reserved h: tasks' example 'h:json --compact # minified, single line' opt :all, type: :boolean, desc: 'include reserved built-in h: tasks' opt :compact, type: :boolean, desc: 'minified JSON (default: pretty)' proc do |opts| require 'json' spec = self.class.root.export_spec(include_builtins: opts[:all]) puts opts[:compact] ? JSON.generate(spec) : JSON.pretty_generate(spec) end 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`).
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/hammer/builtins.rb', line 144 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
80 81 82 83 84 85 86 87 |
# File 'lib/hammer/builtins.rb', line 80 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
98 99 100 101 102 103 104 105 |
# File 'lib/hammer/builtins.rb', line 98 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.
186 187 188 189 190 191 192 193 194 |
# File 'lib/hammer/builtins.rb', line 186 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 |