Module: Hammer::Builtins

Defined in:
lib/hammer/builtins.rb

Overview

Built-in tasks of the ‘hammer` binary - all live at the root level (no reserved namespace). Two registration entry points:

  • register_core - tasks always available (subject to user override via the ‘unless commands.key?(…)` guard): :default, :help, :update, :agents, :version. These coexist with Hammerfile tasks.

  • register_no_project - tasks meaningful only when no Hammerfile is loaded (or ‘–system` was passed): :recipes, :init. These would collide too easily with user tasks if always registered, so the Hammerfile branch skips them.

Defined Under Namespace

Modules: RecipesActions

Class Method Summary collapse

Class Method Details

.register_agents(klass) ⇒ Object



81
82
83
84
85
86
87
88
# File 'lib/hammer/builtins.rb', line 81

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_core(klass) ⇒ Object



16
17
18
19
20
21
22
# File 'lib/hammer/builtins.rb', line 16

def register_core(klass)
  register_help(klass)    unless klass.commands.key?('help')
  register_default(klass) unless klass.commands.key?('default')
  register_update(klass)  unless klass.commands.key?('update')
  register_agents(klass)  unless klass.commands.key?('agents')
  register_version(klass) unless klass.commands.key?('version')
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, …).



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/hammer/builtins.rb', line 54

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



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/hammer/builtins.rb', line 29

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 'help'
      example 'help build'
      example 'help db:'
      proc do |opts|
        self.class.root.print_help(opts[:args].first, extended: true)
      end
    end
  end
end

.register_init(klass) ⇒ Object



99
100
101
102
103
104
105
106
# File 'lib/hammer/builtins.rb', line 99

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_no_project(klass) ⇒ Object



24
25
26
27
# File 'lib/hammer/builtins.rb', line 24

def register_no_project(klass)
  register_recipes(klass) unless klass.commands.key?('recipes')
  register_init(klass)    unless klass.commands.key?('init')
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 recipes –run srt – –help`).



113
114
115
116
117
118
119
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
# File 'lib/hammer/builtins.rb', line 113

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 'recipes'
      example 'recipes --install srt ~/bin/srt    # write + chmod in one shot'
      example 'recipes --install srt > ~/bin/srt && chmod +x $_'
      example 'recipes --show srt'
      example 'recipes --run srt extract movie.mp4'
      example '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



72
73
74
75
76
77
78
79
# File 'lib/hammer/builtins.rb', line 72

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



90
91
92
93
94
95
96
97
# File 'lib/hammer/builtins.rb', line 90

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_hammerfileObject

Writes ./Hammerfile with the canonical starter template. Refuses if one already exists - ‘init` must not clobber.



155
156
157
158
159
160
161
162
163
# File 'lib/hammer/builtins.rb', line 155

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