Module: Hammer::Builtins::Recipes

Defined in:
lib/hammer/builtins.rb

Overview

Implementations of the ‘self:recipe <action>` sub-commands, plus the no-action listing view. Kept in its own module so the namespace definition above stays small and skimmable.

Class Method Summary collapse

Class Method Details

.dispatch(action, name, rest = []) ⇒ Object



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

def dispatch(action, name, rest = [])
  case action
  when nil       then list
  when 'install' then install(name, rest.first)
  when 'show'    then show(require_name!(name, 'show'))
  when 'path'    then path(require_name!(name, 'path'))
  when 'edit'    then edit(require_name!(name, 'edit'))
  when 'run'     then Hammer.recipe(require_name!(name, 'run'), rest)
  else
    Shell.print_error "unknown action: #{action}"
    Shell.say 'valid: install, show, path, edit, run (or omit for list)', :yellow
    exit 1
  end
end

.edit(name) ⇒ Object

For a gem recipe, offer to copy to user dir first so edits survive ‘hammer self:update`. Then exec $EDITOR on the file.



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
# File 'lib/hammer/builtins.rb', line 148

def edit(name)
  path = Hammer::Recipe.path(name) or fail_unknown(name)
  editor = ENV['EDITOR'] || ENV['VISUAL']
  unless editor
    Shell.print_error '$EDITOR not set'
    exit 1
  end

  if path.start_with?(Hammer::Recipe::GEM_DIR)
    user_dir = ENV['HAMMER_RECIPES_DIR'] || File.expand_path('~/.config/hammer/recipes')
    target = File.join(user_dir, "#{name}.rb")
    unless File.exist?(target)
      if Shell.yes?("copy gem recipe to #{target} before editing? (recommended)")
        require 'fileutils'
        FileUtils.mkdir_p(user_dir)
        FileUtils.cp(path, target)
        Shell.say "copied to #{target}", :green
        path = target
      end
    else
      path = target
    end
  end

  system(editor, path)
end

.fail_unknown(name) ⇒ Object



175
176
177
178
# File 'lib/hammer/builtins.rb', line 175

def fail_unknown(name)
  Shell.print_error "unknown recipe: #{name}"
  exit 1
end

.install(name, target = nil) ⇒ Object

With no NAME: arrow-key picker. With NAME only: print the stub to stdout (user pipes it themselves). With NAME + TARGET: write the stub to TARGET and chmod +x in one shot.



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/hammer/builtins.rb', line 108

def install(name, target = nil)
  if name.nil?
    names = Hammer::Recipe.all.keys.sort
    if names.empty?
      Shell.print_error 'no recipes available'
      exit 1
    end
    idx = Shell.choose('pick a recipe to install', names)
    exit 1 if idx.nil?
    name = names[idx]
  end

  unless Hammer::Recipe.path(name)
    Shell.print_error "unknown recipe: #{name}"
    exit 1
  end

  stub = Hammer::Recipe.stub(name)
  if target
    path = File.expand_path(target)
    File.write(path, stub)
    File.chmod(0o755, path)
    Shell.say "installed #{name} -> #{path}", :green
  else
    puts stub
  end
end

.listObject

Group by source dir; each row shows desc and installed-or-not.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/hammer/builtins.rb', line 80

def list
  groups = Hammer::Recipe.grouped
  if groups.empty?
    Shell.say 'no recipes found', :gray
    return
  end

  rows = Hammer::Recipe.all.map do |name, path|
    [name, Hammer::Recipe.desc(path), Hammer::Recipe.installed_path(name)]
  end
  width = rows.map { |n, _, _| n.length }.max

  groups.each_with_index do |(source, items), i|
    Shell.say '' if i > 0
    Shell.say "#{source}:", :yellow
    items.each_key do |name|
      _n, desc, installed = rows.find { |r| r.first == name }
      status = installed ? "(installed: #{installed})" : "[install: hammer self:recipe install #{name}]"
      line = "  #{name.ljust(width)}  # #{desc}"
      Shell.say line
      Shell.say "  #{' ' * width}    #{status}", :gray
    end
  end
end

.path(name) ⇒ Object



141
142
143
144
# File 'lib/hammer/builtins.rb', line 141

def path(name)
  path = Hammer::Recipe.path(name) or fail_unknown(name)
  puts path
end

.require_name!(name, action) ⇒ Object



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

def require_name!(name, action)
  return name if name
  Shell.print_error "missing recipe name (usage: self:recipe #{action} NAME)"
  exit 1
end

.show(name) ⇒ Object



136
137
138
139
# File 'lib/hammer/builtins.rb', line 136

def show(name)
  path = Hammer::Recipe.path(name) or fail_unknown(name)
  puts File.read(path)
end