aia 0.3.3 → 0.3.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.semver +6 -0
- data/CHANGELOG.md +12 -0
- data/README.md +165 -55
- data/Rakefile +2 -0
- data/justfile +167 -0
- data/lib/aia/cli.rb +228 -115
- data/lib/aia/config.rb +7 -0
- data/lib/aia/logging.rb +49 -12
- data/lib/aia/main.rb +29 -15
- data/lib/aia/prompt_processing.rb +208 -4
- data/lib/aia/tools/editor.rb +50 -0
- data/lib/aia/{external → tools}/mods.rb +69 -10
- data/lib/aia/{external → tools}/sgpt.rb +2 -2
- data/lib/aia/{external → tools}/subl.rb +23 -5
- data/lib/aia/tools/vim.rb +91 -0
- data/lib/aia/{external/tool.rb → tools.rb} +28 -24
- data/lib/aia/version.rb +5 -1
- data/lib/aia.rb +17 -3
- data/main.just +56 -0
- data/man/aia.1 +134 -0
- data/man/aia.1.md +107 -0
- metadata +72 -18
- data/lib/aia/configuration.rb +0 -39
- data/lib/aia/external/,keep +0 -0
- data/lib/aia/external/.irbrc +0 -11
- data/lib/aia/external/ag.rb +0 -103
- data/lib/aia/external/bat.rb +0 -189
- data/lib/aia/external/fzf.rb +0 -147
- data/lib/aia/external/glow.rb +0 -37
- data/lib/aia/external/rg.rb +0 -1163
- data/lib/aia/external.rb +0 -259
- data/lib/aia/external_two.rb +0 -43
@@ -5,14 +5,20 @@ module AIA::PromptProcessing
|
|
5
5
|
|
6
6
|
# Fetch the first argument which should be the prompt id
|
7
7
|
def get_prompt
|
8
|
-
prompt_id =
|
8
|
+
prompt_id = AIA.config.arguments.shift
|
9
9
|
|
10
10
|
# TODO: or maybe go to a generic search and select process
|
11
11
|
|
12
|
+
# TODO: if external options were provided but no prompt id
|
13
|
+
# then by pass prompt process and send the extra
|
14
|
+
# options to the backend. For example:
|
15
|
+
# aia -- --settings
|
16
|
+
# should send --settings to mods and nothing else
|
17
|
+
|
12
18
|
abort("Please provide a prompt id") unless prompt_id
|
13
19
|
|
14
20
|
search_for_a_matching_prompt(prompt_id) unless existing_prompt?(prompt_id)
|
15
|
-
edit_prompt if edit?
|
21
|
+
edit_prompt if AIA.config.edit?
|
16
22
|
end
|
17
23
|
|
18
24
|
|
@@ -178,8 +184,17 @@ module AIA::PromptProcessing
|
|
178
184
|
|
179
185
|
|
180
186
|
def edit_prompt
|
181
|
-
|
182
|
-
|
187
|
+
# FIXME: replace with the editor from the configuration
|
188
|
+
|
189
|
+
@editor = AIA::Subl.new(
|
190
|
+
file: @prompt.path
|
191
|
+
)
|
192
|
+
|
193
|
+
@editor.run # blocks until file is closed
|
194
|
+
|
195
|
+
@options[:edit?][0] = false # turn off the --edit switch
|
196
|
+
|
197
|
+
# reload the edited prompt
|
183
198
|
@prompt = PromptManager::Prompt.get(id: @prompt.id)
|
184
199
|
end
|
185
200
|
|
@@ -210,3 +225,192 @@ module AIA::PromptProcessing
|
|
210
225
|
end
|
211
226
|
end
|
212
227
|
|
228
|
+
|
229
|
+
|
230
|
+
__END__
|
231
|
+
|
232
|
+
# lib/aia/prompt_processing.rb
|
233
|
+
|
234
|
+
class AIA::PromptProcessing
|
235
|
+
KW_HISTORY_MAX = 5
|
236
|
+
|
237
|
+
def initialize(arguments, options)
|
238
|
+
@arguments = arguments
|
239
|
+
@options = options
|
240
|
+
@prompt = nil
|
241
|
+
end
|
242
|
+
|
243
|
+
def execute
|
244
|
+
get_prompt
|
245
|
+
process_prompt
|
246
|
+
end
|
247
|
+
|
248
|
+
private
|
249
|
+
|
250
|
+
def get_prompt
|
251
|
+
prompt_id = @arguments.shift
|
252
|
+
abort("Please provide a prompt id") unless prompt_id
|
253
|
+
search_for_a_matching_prompt(prompt_id) unless existing_prompt?(prompt_id)
|
254
|
+
edit_prompt if edit?
|
255
|
+
end
|
256
|
+
|
257
|
+
def existing_prompt?(prompt_id)
|
258
|
+
@prompt = PromptManager::Prompt.get(id: prompt_id)
|
259
|
+
@prompt.keywords.each do |kw|
|
260
|
+
@prompt.parameters[kw] = Array(@prompt.parameters[kw])
|
261
|
+
end
|
262
|
+
true
|
263
|
+
rescue ArgumentError
|
264
|
+
false
|
265
|
+
end
|
266
|
+
|
267
|
+
def process_prompt
|
268
|
+
return if @prompt.keywords.empty?
|
269
|
+
replace_keywords
|
270
|
+
@prompt.build
|
271
|
+
@prompt.save
|
272
|
+
end
|
273
|
+
|
274
|
+
def replace_keywords
|
275
|
+
puts "ID: #{@prompt.id}"
|
276
|
+
show_prompt_without_comments
|
277
|
+
puts_instructions
|
278
|
+
@prompt.keywords.each do |kw|
|
279
|
+
value = keyword_value(kw, @prompt.parameters[kw])
|
280
|
+
update_keyword_history(kw, value) unless value.nil? || value.strip.empty?
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
def puts_instructions
|
285
|
+
puts "\nPress up/down arrow to scroll through history."
|
286
|
+
puts "Type new input or edit the current input."
|
287
|
+
puts "Quit #{MY_NAME} with a CNTL-D or a CNTL-C"
|
288
|
+
puts
|
289
|
+
end
|
290
|
+
|
291
|
+
def update_keyword_history(kw, value)
|
292
|
+
params = @prompt.parameters[kw]
|
293
|
+
params.delete(value)
|
294
|
+
params << value
|
295
|
+
params.shift if params.size > KW_HISTORY_MAX
|
296
|
+
end
|
297
|
+
|
298
|
+
def keyword_value(kw, history_array)
|
299
|
+
Readline::HISTORY.clear
|
300
|
+
Array(history_array).each { |entry| Readline::HISTORY.push(entry) unless entry.nil? || entry.empty? }
|
301
|
+
puts "Parameter #{kw} ..."
|
302
|
+
begin
|
303
|
+
a_string = Readline.readline("\n-=> ", true)
|
304
|
+
rescue Interrupt
|
305
|
+
a_string = nil
|
306
|
+
end
|
307
|
+
abort("okay. Come back soon.") if a_string.nil?
|
308
|
+
a_string.empty? ? history_array.first : a_string
|
309
|
+
end
|
310
|
+
|
311
|
+
def search_for_a_matching_prompt(prompt_id)
|
312
|
+
found_prompts = PromptManager::Prompt.search(prompt_id)
|
313
|
+
handle_no_prompts_found(prompt_id) if found_prompts.empty?
|
314
|
+
prompt_id = found_prompts.size == 1 ? found_prompts.first : handle_multiple_prompts(found_prompts, prompt_id)
|
315
|
+
@prompt = PromptManager::Prompt.get(id: prompt_id)
|
316
|
+
end
|
317
|
+
|
318
|
+
def handle_no_prompts_found(prompt_id)
|
319
|
+
if edit?
|
320
|
+
create_prompt(prompt_id)
|
321
|
+
edit_prompt
|
322
|
+
else
|
323
|
+
abort_no_prompts_error(prompt_id)
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
def abort_no_prompts_error(prompt_id)
|
328
|
+
abort <<~EOS
|
329
|
+
|
330
|
+
No prompts were found for: #{prompt_id}
|
331
|
+
To create a prompt with this ID use the --edit option
|
332
|
+
like this:
|
333
|
+
#{MY_NAME} #{prompt_id} --edit
|
334
|
+
|
335
|
+
EOS
|
336
|
+
end
|
337
|
+
|
338
|
+
def handle_multiple_prompts(found_these, while_looking_for_this)
|
339
|
+
raise ArgumentError, "Argument is not an Array" unless found_these.is_a?(Array)
|
340
|
+
result = execute_fzf(found_these, while_looking_for_this)
|
341
|
+
abort unless result
|
342
|
+
result
|
343
|
+
end
|
344
|
+
|
345
|
+
def execute_fzf(found_these, while_looking_for_this)
|
346
|
+
fzf_options = build_fzf_options(while_looking_for_this)
|
347
|
+
temp_file = create_tempfile_with_entries(found_these)
|
348
|
+
selected = `cat #{temp_file.path} | fzf #{fzf_options}`.strip
|
349
|
+
temp_file.unlink
|
350
|
+
selected.empty? ? nil : selected
|
351
|
+
end
|
352
|
+
|
353
|
+
def build_fzf_options(search_term)
|
354
|
+
[
|
355
|
+
"--tabstop=2",
|
356
|
+
"--header='Prompt IDs which contain: #{search_term}\nPress ESC to cancel.'",
|
357
|
+
"--header-first",
|
358
|
+
"--prompt='Search term: '",
|
359
|
+
'--delimiter :',
|
360
|
+
"--preview 'cat $PROMPTS_DIR/{1}.txt'",
|
361
|
+
"--preview-window=down:50%:wrap"
|
362
|
+
].join(' ')
|
363
|
+
end
|
364
|
+
|
365
|
+
def create_tempfile_with_entries(entries)
|
366
|
+
temp_file = Tempfile.new('fzf-input')
|
367
|
+
temp_file.puts(entries)
|
368
|
+
temp_file.close
|
369
|
+
temp_file
|
370
|
+
end
|
371
|
+
|
372
|
+
def create_prompt(prompt_id)
|
373
|
+
@prompt = PromptManager::Prompt.create(id: prompt_id)
|
374
|
+
# Additional prompt config...
|
375
|
+
end
|
376
|
+
|
377
|
+
|
378
|
+
|
379
|
+
def edit_prompt
|
380
|
+
# FIXME: replace with the editor from the configuration
|
381
|
+
|
382
|
+
@editor = AIA::Subl.new(
|
383
|
+
file: @prompt.path
|
384
|
+
)
|
385
|
+
|
386
|
+
@editor.run # blocks until file is closed
|
387
|
+
|
388
|
+
@options[:edit?][0] = false # turn off the --edit switch
|
389
|
+
|
390
|
+
# reload the edited prompt
|
391
|
+
@prompt = PromptManager::Prompt.get(id: @prompt.id)
|
392
|
+
end
|
393
|
+
|
394
|
+
|
395
|
+
def show_prompt_without_comments
|
396
|
+
puts remove_comments.wrap(indent: 4)
|
397
|
+
end
|
398
|
+
|
399
|
+
def remove_comments
|
400
|
+
lines = @prompt.text.lines
|
401
|
+
.reject { |a_line| a_line.strip.start_with?('#') }
|
402
|
+
.drop_while(&:empty?)
|
403
|
+
logical_end_inx = lines.index("__END__")
|
404
|
+
lines = lines[0...logical_end_inx] if logical_end_inx
|
405
|
+
lines.join("\n")
|
406
|
+
end
|
407
|
+
|
408
|
+
def edit?
|
409
|
+
@options[:edit?] && @options[:edit?][0] == true
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
|
414
|
+
|
415
|
+
|
416
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# lib/aia/tools/editor.rb
|
2
|
+
# This is the default editor setup in the
|
3
|
+
# system environment variable EDITOR
|
4
|
+
|
5
|
+
|
6
|
+
class AIA::Editor < AIA::Tools
|
7
|
+
DEFAULT_PARAMETERS = ""
|
8
|
+
|
9
|
+
attr_accessor :command
|
10
|
+
|
11
|
+
|
12
|
+
def initialize(file: "")
|
13
|
+
super
|
14
|
+
|
15
|
+
@role = :editor
|
16
|
+
@description = "Your default system $EDITOR"
|
17
|
+
@url = "unknown"
|
18
|
+
@install = "should already be installed"
|
19
|
+
|
20
|
+
@file = file
|
21
|
+
|
22
|
+
discover_editor
|
23
|
+
|
24
|
+
build_command
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def discover_editor
|
29
|
+
editor = ENV['EDITOR'] # This might be nil
|
30
|
+
|
31
|
+
if editor.nil?
|
32
|
+
@name = "echo"
|
33
|
+
@description = "You have no default editor"
|
34
|
+
@install = "Set your system environment variable EDITOR"
|
35
|
+
else
|
36
|
+
@name = editor
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def build_command
|
42
|
+
@command = "#{name} #{DEFAULT_PARAMETERS} #{@file}"
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def run
|
47
|
+
`#{command}`
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -1,22 +1,81 @@
|
|
1
|
-
# lib/aia/
|
1
|
+
# lib/aia/tools/mods.rb
|
2
2
|
|
3
|
-
class AIA::
|
4
|
-
|
3
|
+
class AIA::Mods < AIA::Tools
|
4
|
+
DEFAULT_PARAMETERS = [
|
5
|
+
"--no-limit" # no limit on input context
|
6
|
+
].join(' ').freeze
|
7
|
+
|
8
|
+
attr_accessor :command, :extra_options, :text, :files
|
9
|
+
|
10
|
+
# TODO: put the prompt text to be resolved into a
|
11
|
+
# temporary text file then cat that file into mods.
|
12
|
+
# This will keep from polluting the CLI history with
|
13
|
+
# lots of text
|
14
|
+
|
15
|
+
|
16
|
+
def initialize(
|
17
|
+
extra_options: "", # everything after -- on command line
|
18
|
+
text: "", # prompt text after keyword replacement
|
19
|
+
files: [] # context file paths (Array of Pathname)
|
20
|
+
)
|
5
21
|
super
|
6
|
-
@role
|
7
|
-
@
|
8
|
-
@url
|
22
|
+
@role = :gen_ai
|
23
|
+
@description = 'AI on the command-line'
|
24
|
+
@url = 'https://github.com/charmbracelet/mods'
|
25
|
+
|
26
|
+
@extra_options = extra_options
|
27
|
+
@text = text
|
28
|
+
@files = files
|
29
|
+
|
30
|
+
build_command
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def build_command
|
35
|
+
parameters = DEFAULT_PARAMETERS.dup + " "
|
36
|
+
parameters += "-f " if ::AIA.config.markdown?
|
37
|
+
parameters += "-m #{AIA.config.model} " if ::AIA.config.model
|
38
|
+
parameters += @extra_options
|
39
|
+
@command = "mods #{parameters} "
|
40
|
+
@command += %Q["#{@text}"] # TODO: consider using the pipeline
|
41
|
+
|
42
|
+
@files.each {|f| @command += " < #{f}" }
|
43
|
+
|
44
|
+
@command
|
9
45
|
end
|
10
46
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
"#{name} #{ai_default_opts} #{extra_options.join(' ')}"
|
47
|
+
|
48
|
+
def run
|
49
|
+
`#{command}`
|
15
50
|
end
|
16
51
|
end
|
17
52
|
|
18
53
|
__END__
|
19
54
|
|
55
|
+
|
56
|
+
# Execute the command and log the results
|
57
|
+
def send_prompt_to_external_command
|
58
|
+
command = build_command
|
59
|
+
|
60
|
+
puts command if verbose?
|
61
|
+
@result = `#{command}`
|
62
|
+
|
63
|
+
if @output.nil?
|
64
|
+
puts @result
|
65
|
+
else
|
66
|
+
@output.write @result
|
67
|
+
end
|
68
|
+
|
69
|
+
@result
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
##########################################################
|
77
|
+
|
78
|
+
|
20
79
|
GPT on the command line. Built for pipelines.
|
21
80
|
|
22
81
|
Usage:
|
@@ -1,17 +1,35 @@
|
|
1
|
-
# lib/aia/
|
1
|
+
# lib/aia/tools/subl.rb
|
2
2
|
|
3
|
-
class AIA::
|
4
|
-
|
3
|
+
class AIA::Subl < AIA::Tools
|
4
|
+
DEFAULT_PARAMETERS = [
|
5
|
+
"--new-window", # Open a new window
|
6
|
+
"--wait", # Wait for the files to be closed before returning
|
7
|
+
].join(' ')
|
8
|
+
|
9
|
+
attr_accessor :command
|
10
|
+
|
11
|
+
|
12
|
+
def initialize(file: "")
|
5
13
|
super
|
14
|
+
|
6
15
|
@role = :editor
|
7
16
|
@desc = "Sublime Text Editor"
|
8
17
|
@url = "https://www.sublimetext.com/"
|
9
18
|
@install = "echo 'Download from website'"
|
19
|
+
|
20
|
+
@file = file
|
21
|
+
|
22
|
+
build_command
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def build_command
|
27
|
+
@command = "#{name} #{DEFAULT_PARAMETERS} #{@file}"
|
10
28
|
end
|
11
29
|
|
12
30
|
|
13
|
-
def
|
14
|
-
`#{
|
31
|
+
def run
|
32
|
+
`#{command}`
|
15
33
|
end
|
16
34
|
end
|
17
35
|
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# lib/aia/tools/vim.rb
|
2
|
+
|
3
|
+
class AIA::Vim < AIA::Tools
|
4
|
+
DEFAULT_PARAMETERS = [
|
5
|
+
" ", # no parameters
|
6
|
+
].join(' ')
|
7
|
+
|
8
|
+
attr_accessor :command
|
9
|
+
|
10
|
+
|
11
|
+
def initialize(file: "")
|
12
|
+
super
|
13
|
+
|
14
|
+
@role = :editor
|
15
|
+
@description = "Vi IMproved (VIM)"
|
16
|
+
@url = "https://www.vim.org"
|
17
|
+
@install = "brew install vim"
|
18
|
+
|
19
|
+
@file = file
|
20
|
+
|
21
|
+
build_command
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def build_command
|
26
|
+
@command = "#{name} #{DEFAULT_PARAMETERS} #{@file}"
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def run
|
31
|
+
# Using 'system' instead of backticks becuase
|
32
|
+
# with the back ticks vim was complaining that it
|
33
|
+
# was not connected to a terminal.
|
34
|
+
system command
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
__END__
|
39
|
+
|
40
|
+
VIM - Vi IMproved 9.0 (2022 Jun 28, compiled Sep 30 2023 05:45:56)
|
41
|
+
|
42
|
+
Usage: vim [arguments] [file ..] edit specified file(s)
|
43
|
+
or: vim [arguments] - read text from stdin
|
44
|
+
or: vim [arguments] -t tag edit file where tag is defined
|
45
|
+
or: vim [arguments] -q [errorfile] edit file with first error
|
46
|
+
|
47
|
+
Arguments:
|
48
|
+
-- Only file names after this
|
49
|
+
-v Vi mode (like "vi")
|
50
|
+
-e Ex mode (like "ex")
|
51
|
+
-E Improved Ex mode
|
52
|
+
-s Silent (batch) mode (only for "ex")
|
53
|
+
-d Diff mode (like "vimdiff")
|
54
|
+
-y Easy mode (like "evim", modeless)
|
55
|
+
-R Readonly mode (like "view")
|
56
|
+
-Z Restricted mode (like "rvim")
|
57
|
+
-m Modifications (writing files) not allowed
|
58
|
+
-M Modifications in text not allowed
|
59
|
+
-b Binary mode
|
60
|
+
-l Lisp mode
|
61
|
+
-C Compatible with Vi: 'compatible'
|
62
|
+
-N Not fully Vi compatible: 'nocompatible'
|
63
|
+
-V[N][fname] Be verbose [level N] [log messages to fname]
|
64
|
+
-D Debugging mode
|
65
|
+
-n No swap file, use memory only
|
66
|
+
-r List swap files and exit
|
67
|
+
-r (with file name) Recover crashed session
|
68
|
+
-L Same as -r
|
69
|
+
-T <terminal> Set terminal type to <terminal>
|
70
|
+
--not-a-term Skip warning for input/output not being a terminal
|
71
|
+
--ttyfail Exit if input or output is not a terminal
|
72
|
+
-u <vimrc> Use <vimrc> instead of any .vimrc
|
73
|
+
--noplugin Don't load plugin scripts
|
74
|
+
-p[N] Open N tab pages (default: one for each file)
|
75
|
+
-o[N] Open N windows (default: one for each file)
|
76
|
+
-O[N] Like -o but split vertically
|
77
|
+
+ Start at end of file
|
78
|
+
+<lnum> Start at line <lnum>
|
79
|
+
--cmd <command> Execute <command> before loading any vimrc file
|
80
|
+
-c <command> Execute <command> after loading the first file
|
81
|
+
-S <session> Source file <session> after loading the first file
|
82
|
+
-s <scriptin> Read Normal mode commands from file <scriptin>
|
83
|
+
-w <scriptout> Append all typed commands to file <scriptout>
|
84
|
+
-W <scriptout> Write all typed commands to file <scriptout>
|
85
|
+
-x Edit encrypted files
|
86
|
+
--startuptime <file> Write startup timing messages to <file>
|
87
|
+
--log <file> Start logging to <file> early
|
88
|
+
-i <viminfo> Use <viminfo> instead of .viminfo
|
89
|
+
--clean 'nocompatible', Vim defaults, no plugins, no viminfo
|
90
|
+
-h or --help Print Help (this message) and exit
|
91
|
+
--version Print version information and exit
|
@@ -1,27 +1,21 @@
|
|
1
|
-
# lib/aia/
|
1
|
+
# lib/aia/tools.rb
|
2
2
|
|
3
|
-
class AIA::
|
3
|
+
class AIA::Tools
|
4
4
|
@@subclasses = []
|
5
5
|
|
6
|
-
# This method is called whenever a subclass is created
|
7
6
|
def self.inherited(subclass)
|
8
7
|
@@subclasses << subclass
|
9
8
|
end
|
10
9
|
|
10
|
+
attr_accessor :role, :name, :description, :url, :install
|
11
|
+
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@
|
18
|
-
@url = "URL"
|
19
|
-
@install = "brew install #{name}"
|
20
|
-
end
|
21
|
-
|
22
|
-
|
23
|
-
def self.tools
|
24
|
-
@@subclasses.map(&:name)
|
13
|
+
def initialize(*)
|
14
|
+
@role = :role
|
15
|
+
@name = self.class.name.split('::').last.downcase
|
16
|
+
@description = "description"
|
17
|
+
@url = "URL"
|
18
|
+
@install = "brew install #{name}"
|
25
19
|
end
|
26
20
|
|
27
21
|
|
@@ -31,14 +25,25 @@ class AIA::External::Tool
|
|
31
25
|
end
|
32
26
|
|
33
27
|
|
34
|
-
def help
|
35
|
-
|
28
|
+
def help
|
29
|
+
`#{name} --help`
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def version
|
34
|
+
`#{name} --version`
|
35
|
+
end
|
36
36
|
|
37
37
|
|
38
|
-
|
38
|
+
#########################################
|
39
39
|
class << self
|
40
|
-
def
|
41
|
-
|
40
|
+
def tools
|
41
|
+
@@subclasses.map(&:name)
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
def verify_tools
|
46
|
+
missing_tools = @@subclasses.map(&:new).reject(&:installed?)
|
42
47
|
unless missing_tools.empty?
|
43
48
|
puts format_missing_tools_response(missing_tools)
|
44
49
|
end
|
@@ -64,10 +69,9 @@ class AIA::External::Tool
|
|
64
69
|
end
|
65
70
|
|
66
71
|
|
67
|
-
Pathname.new(__dir__)
|
72
|
+
(Pathname.new(__dir__)+"tools")
|
68
73
|
.glob('*.rb')
|
69
|
-
.reject{|f| f.basename.to_s.end_with?('tool.rb') }
|
70
74
|
.each do |tool|
|
71
|
-
require_relative tool.basename.to_s
|
75
|
+
require_relative "tools/#{tool.basename.to_s}"
|
72
76
|
end
|
73
77
|
|
data/lib/aia/version.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# lib/aia/version.rb
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require 'semver'
|
5
|
+
|
4
6
|
module AIA
|
5
|
-
|
7
|
+
# .semver is located at the gem's root directory
|
8
|
+
version_file_path = File.join(__dir__, '..', '..')
|
9
|
+
VERSION = SemVer.find(version_file_path).to_s[1..]
|
6
10
|
end
|
data/lib/aia.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# lib/aia.rb
|
2
2
|
|
3
|
+
require 'debug_me'
|
4
|
+
include DebugMe
|
5
|
+
|
6
|
+
require 'hashie'
|
3
7
|
require 'pathname'
|
4
8
|
require 'readline'
|
5
9
|
require 'tempfile'
|
@@ -12,9 +16,19 @@ require_relative "aia/main"
|
|
12
16
|
require_relative "core_ext/string_wrap"
|
13
17
|
|
14
18
|
module AIA
|
15
|
-
|
16
|
-
|
17
|
-
|
19
|
+
class << self
|
20
|
+
attr_accessor :config
|
21
|
+
|
22
|
+
def run(args=ARGV)
|
23
|
+
args = args.split(' ') if args.is_a?(String)
|
24
|
+
|
25
|
+
# TODO: Currently this is a one and done architecture.
|
26
|
+
# If the args contain an "-i" or and "--interactive"
|
27
|
+
# flag could this turn into some kind of
|
28
|
+
# conversation REPL?
|
29
|
+
|
30
|
+
AIA::Main.new(args).call
|
31
|
+
end
|
18
32
|
end
|
19
33
|
end
|
20
34
|
|
data/main.just
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# aia/main.just
|
2
|
+
#
|
3
|
+
# Support man pages with ...
|
4
|
+
# gem install kramdown-man
|
5
|
+
#
|
6
|
+
|
7
|
+
RR := env_var('RR')
|
8
|
+
|
9
|
+
with ~/.justfile
|
10
|
+
|
11
|
+
# FIXME: justprep module process still has an issue with ~ and $HOME
|
12
|
+
# FIXME: justprep does not like more than one space between module name and path.
|
13
|
+
|
14
|
+
module repo /Users/dewayne/sandbox/git_repos/repo.just
|
15
|
+
module gem /Users/dewayne/sandbox/git_repos/gem.just
|
16
|
+
module version /Users/dewayne/just_modules/version.just
|
17
|
+
|
18
|
+
|
19
|
+
# Preview man page
|
20
|
+
preview_man_page:
|
21
|
+
kramdown-man {{RR}}/man/aia.1.md
|
22
|
+
|
23
|
+
|
24
|
+
# View man page
|
25
|
+
view_man_page: create_man_page
|
26
|
+
man {{RR}}/man/aia.1
|
27
|
+
|
28
|
+
|
29
|
+
# Create man page
|
30
|
+
create_man_page:
|
31
|
+
rake man
|
32
|
+
|
33
|
+
##########################################
|
34
|
+
|
35
|
+
# Tag the current commit, push it, then bump the version
|
36
|
+
tag_push_and_bump: tag push bump
|
37
|
+
|
38
|
+
|
39
|
+
# Create a git tag for the current version
|
40
|
+
tag:
|
41
|
+
git tag $(semver)
|
42
|
+
|
43
|
+
# Push the git current working directory and all tags
|
44
|
+
push:
|
45
|
+
git push
|
46
|
+
git push origin --tags
|
47
|
+
|
48
|
+
|
49
|
+
alias inc := bump
|
50
|
+
|
51
|
+
# Increament version's level: major.minor.patch
|
52
|
+
@bump level='patch':
|
53
|
+
semver increment {{level}}
|
54
|
+
echo "Now working on: $(semver)"
|
55
|
+
git add {{RR}}/.semver
|
56
|
+
|