aia 0.3.4 → 0.3.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|