ai_refactor 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 758af953e626b18190ef1e2252e730ea636d773a53b63052aaa7aba6213b49a2
4
- data.tar.gz: 2bf63e217e7c3647e9cc26a9112f72eb19b81700f5784730a15ec0b229889963
3
+ metadata.gz: fa9421b9791dda3c02b930e63d0fa7bd3dc587d121a0b3748a0f9d8c649f98a3
4
+ data.tar.gz: a5cb385968939847ebb1ceb1d663b1926e410fce0571fa2ab7463440347c0f50
5
5
  SHA512:
6
- metadata.gz: 76e034568b78234e7b66c756601be73976f3367c542112b6cfc88c47ab3edb31016a8507201eee382a33ed2c7d041707295fcf140cfecc859a1d6e5b99c52d35
7
- data.tar.gz: bb00b41760079e5203c5bcadbff10c09b7fc701ec12a1c25623dbff85862e6c3de0416d341ad41c22d03dad54fdadc97ccb33e2a02756186a65ad9e4dfb17d4d
6
+ metadata.gz: 6ff997f0533fe95da7f0361789d88b4a73ecd8fbd82a1f54179fbce3b6a3b466c40330ae615a00f850e549212fe2463ba60ca4467cc0d9f65bbd6679f326dff1
7
+ data.tar.gz: 5898b17ebaa96c24a89cae1ff741a53d3afbb7a6c4844f52a271ddfecc1ebc1923026324601cb98e56b5aed0d673bba5d583d388a7a936e4cc86b272e1858bd8
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ai_refactor (0.2.0)
4
+ ai_refactor (0.3.0)
5
5
  colorize (< 2.0)
6
6
  open3 (< 2.0)
7
7
  ruby-openai (>= 3.4.0, < 5.0)
data/exe/ai_refactor CHANGED
@@ -14,7 +14,6 @@ supported_names = AIRefactor::Refactors.names
14
14
  option_parser = OptionParser.new do |parser|
15
15
  parser.banner = "Usage: ai_refactor REFACTOR_TYPE INPUT_FILE_OR_DIR [options]\n\nWhere REFACTOR_TYPE is one of: #{supported_names}\n\n"
16
16
 
17
- # todo: support for a sort of generic process which uses a custom prompt file
18
17
  parser.on("-p", "--prompt PROMPT_FILE", String, "Specify path to a text file that contains the ChatGPT 'system' prompt.") do |f|
19
18
  options[:prompt_file_path] = f
20
19
  end
@@ -27,11 +26,11 @@ option_parser = OptionParser.new do |parser|
27
26
  options[:ai_model] = m
28
27
  end
29
28
 
30
- parser.on(nil, "--temperature TEMP", Float, "Specify the temperature parameter for ChatGPT (default 0.7).") do |p|
29
+ parser.on("--temperature TEMP", Float, "Specify the temperature parameter for ChatGPT (default 0.7).") do |p|
31
30
  options[:ai_temperature] = p
32
31
  end
33
32
 
34
- parser.on(nil, "--max-tokens MAX_TOKENS", Integer, "Specify the max number of tokens of output ChatGPT can generate. Max will depend on the size of the prompt (default 1500)") do |m|
33
+ parser.on("--max-tokens MAX_TOKENS", Integer, "Specify the max number of tokens of output ChatGPT can generate. Max will depend on the size of the prompt (default 1500)") do |m|
35
34
  options[:ai_max_tokens] = m
36
35
  end
37
36
 
@@ -47,18 +46,23 @@ option_parser = OptionParser.new do |parser|
47
46
  options[:debug] = true
48
47
  end
49
48
 
50
- supported_refactors.each do |_name, refactorer|
51
- refactorer.command_line_options.each do |option|
52
- parser.on(option[:short], option[:long], option[:type], option[:help]) do |o|
53
- options[option[:key]] = o
54
- end
55
- end
56
- end
57
-
58
49
  parser.on("-h", "--help", "Prints this help") do
59
50
  puts parser
60
51
  exit
61
52
  end
53
+
54
+ parser.separator ""
55
+
56
+ supported_refactors.each do |name, refactorer|
57
+ parser.separator "For refactor type '#{name}':" if refactorer.command_line_options.size.positive?
58
+ refactorer.command_line_options.each do |option|
59
+ args = [option[:long], option[:type], option[:help]]
60
+ args.unshift(option[:short]) if option[:short]
61
+ parser.on(*args) do |o|
62
+ options[option[:key]] = o.nil? ? true : o
63
+ end
64
+ end
65
+ end
62
66
  end
63
67
 
64
68
  option_parser.parse!
@@ -21,6 +21,17 @@ module AIRefactor
21
21
 
22
22
  private
23
23
 
24
+ def can_overwrite_output_file?(output_path)
25
+ logger.info "Do you wish to overwrite #{output_path}? (y/n)"
26
+ answer = $stdin.gets.chomp
27
+ unless answer == "y" || answer == "Y"
28
+ logger.warn "Skipping #{input_file}..."
29
+ self.failed_message = "Skipped as output file already exists"
30
+ return false
31
+ end
32
+ true
33
+ end
34
+
24
35
  def prompt_file_path
25
36
  self.class.prompt_file_path
26
37
  end
@@ -5,14 +5,20 @@ module AIRefactor
5
5
  class Generic < BaseRefactor
6
6
  def run
7
7
  logger.verbose "Generic refactor to #{input_file}... (using user supplied prompt #{prompt_file_path})"
8
+ logger.verbose "Write output to #{output_file_path}..." if output_file_path
8
9
 
9
10
  processor = AIRefactor::FileProcessor.new(
10
11
  input_path: input_file,
11
12
  prompt_file_path: prompt_file_path,
12
13
  ai_client: ai_client,
13
- logger: logger
14
+ logger: logger,
15
+ output_path: output_file_path
14
16
  )
15
17
 
18
+ if processor.output_exists?
19
+ return false unless can_overwrite_output_file?(output_file_path)
20
+ end
21
+
16
22
  logger.verbose "Converting #{input_file}..."
17
23
 
18
24
  begin
@@ -38,11 +44,38 @@ module AIRefactor
38
44
  return false
39
45
  end
40
46
 
41
- output_content
47
+ output_file_path ? true : output_content
42
48
  end
43
49
 
44
50
  private
45
51
 
52
+ def output_file_path
53
+ return output_file_path_from_template if output_template_path
54
+
55
+ path = options[:output_file_path]
56
+ return unless path
57
+
58
+ if path == true
59
+ input_file
60
+ else
61
+ path
62
+ end
63
+ end
64
+
65
+ def output_template_path
66
+ options[:output_template_path]
67
+ end
68
+
69
+ def output_file_path_from_template
70
+ path = output_template_path.gsub("[FILE]", File.basename(input_file))
71
+ .gsub("[NAME]", File.basename(input_file, ".*"))
72
+ .gsub("[DIR]", File.dirname(input_file))
73
+ .gsub("[REFACTOR]", self.class.refactor_name)
74
+ .gsub("[EXT]", File.extname(input_file))
75
+ raise "Output template could not be used" unless path.length.positive?
76
+ path
77
+ end
78
+
46
79
  def prompt_file_path
47
80
  specified_prompt_path = options[:prompt_file_path]
48
81
  if specified_prompt_path&.length&.positive?
@@ -61,6 +94,23 @@ module AIRefactor
61
94
  def prompt_file_path
62
95
  raise "Generic refactor requires prompt file to be user specified."
63
96
  end
97
+
98
+ def command_line_options
99
+ [
100
+ {
101
+ key: :output_file_path,
102
+ long: "--output [FILE]",
103
+ type: String,
104
+ help: "Write output to file instead of stdout. If no path provided will overwrite input file (will prompt to overwrite existing files)"
105
+ },
106
+ {
107
+ key: :output_template_path,
108
+ long: "--output-template TEMPLATE",
109
+ type: String,
110
+ help: "Write outputs to files instead of stdout. The template is used to create the output name, where the it can have substitutions, '[FILE]', '[NAME]', '[DIR]', '[REFACTOR]' & '[EXT]'. Eg `[DIR]/[NAME]_[REFACTOR][EXT]` (will prompt to overwrite existing files)"
111
+ }
112
+ ]
113
+ end
64
114
  end
65
115
  end
66
116
  end
@@ -35,13 +35,7 @@ module AIRefactor
35
35
  )
36
36
 
37
37
  if processor.output_exists?
38
- logger.info "Do you wish to overwrite #{output_path}? (y/n)"
39
- answer = $stdin.gets.chomp
40
- unless answer == "y" || answer == "Y"
41
- logger.warn "Skipping #{input_file}..."
42
- self.failed_message = "Skipped as output test file already exists"
43
- return false
44
- end
38
+ return false unless can_overwrite_output_file?(output_path)
45
39
  end
46
40
 
47
41
  logger.verbose "Converting #{input_file}..."
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AIRefactor
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ai_refactor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Ierodiaconou
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-24 00:00:00.000000000 Z
11
+ date: 2023-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize