code-review-ai 0.1.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 44b987a9b718977db5cb57cc5070619c83527a885415ef390c1d816bfeadae2b
4
+ data.tar.gz: 175707830a53cba891cd74bd612cc6fb7e3efa3da3afeff59a5ddd2bc6607112
5
+ SHA512:
6
+ metadata.gz: 95a4b53f801fed345232ee28aaca77ebbe7266ed154bc9c5ca4fd463b80e9a4bc2ed364d169a948c439f05c65f3735fff6adfc5112c84dcacb87c48704023027
7
+ data.tar.gz: a419729cc7f97749e220e453d8d80ad98bc96282950e3b9fd06cc366a3d1c66610c689a5108df0f8e1c9911e70c8d6a061e69c7e72a6a1f3f418add41d2f0097
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'code_review_ai'
4
+ require 'optparse'
5
+
6
+ options = {}
7
+ OptionParser.new do |opts|
8
+ opts.banner = <<~BANNER
9
+ Code Review AI - AI-powered code review tool
10
+
11
+ Usage: code-review-ai --command [review|summary] [options]
12
+
13
+ Commands:
14
+ review - Conduct AI code review on current branch
15
+ summary - Generate branch change summary
16
+
17
+ Environment Variables:
18
+ OPENAI_ACCESS_TOKEN - OpenAI API key
19
+ OPENAI_MODEL - AI model (default: gpt-3.5-turbo)
20
+ OPENAI_LANGUAGE - Output language (default: English)
21
+ BANNER
22
+
23
+ opts.on("-k", "--api-key KEY", "OpenAI API key") do |key|
24
+ options[:api_key] = key
25
+ end
26
+
27
+ opts.on("-m", "--model MODEL", "AI model to use") do |model|
28
+ options[:model] = model
29
+ end
30
+
31
+ opts.on("-l", "--language LANG", "Language for output") do |lang|
32
+ options[:language] = lang
33
+ end
34
+
35
+ opts.on("-c", "--command CMD", "Command (review or summary)") do |cmd|
36
+ options[:command] = cmd
37
+ end
38
+ end.parse!
39
+
40
+ begin
41
+ api_key = options[:api_key] || ENV['OPENAI_ACCESS_TOKEN']
42
+ model = options[:model] || ENV['OPENAI_MODEL'] || 'gpt-3.5-turbo'
43
+ language = options[:language] || ENV['OPENAI_LANGUAGE'] || 'English'
44
+ command = options[:command] || 'review'
45
+
46
+ reviewer = CodeReviewAi::Client.new(api_key, model, language)
47
+
48
+ case command
49
+ when 'review'
50
+ reviewer.conduct_code_review
51
+ when 'summary'
52
+ puts reviewer.generate_branch_summary
53
+ else
54
+ puts "Unknown command. Use 'review' or 'summary'"
55
+ exit 1
56
+ end
57
+ rescue StandardError => e
58
+ puts "Error: #{e.message}"
59
+ exit 1
60
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ require_relative '../prompts'
3
+
4
+ module CodeReviewAi
5
+ class Client
6
+ def generate_branch_summary
7
+ prompt = generate_prompt(CodeReviewAi::Prompts::BRANCH_SUMMARY_TEMPLATE, @language)
8
+ response = @client.chat(
9
+ parameters: {
10
+ model: @ai_model,
11
+ messages: [
12
+ {
13
+ role: 'system',
14
+ content: 'You are an assistant summarizing git branch changes clearly and concisely.'
15
+ },
16
+ {
17
+ role: 'user',
18
+ content: prompt
19
+ }
20
+ ]
21
+ }
22
+ )
23
+ summary = process_response(response)
24
+ puts summary
25
+ rescue StandardError => e
26
+ "Error generating branch summary: #{e.message}"
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ require_relative '../prompts'
3
+
4
+ module CodeReviewAi
5
+ class Client
6
+ # Conduct an AI-powered code review on the current branch
7
+ # Analyzes git diff and generates review comments using OpenAI
8
+ #
9
+ # @return [String] Generated code review comments
10
+ def conduct_code_review
11
+ prompt = generate_prompt(CodeReviewAi::Prompts::CODE_REVIEW_TEMPLATE, @language)
12
+ response = @client.chat(
13
+ parameters: {
14
+ model: @ai_model,
15
+ messages: [
16
+ {
17
+ role: 'system',
18
+ content: 'You are an assistant generating code review comments based on repository changes.'
19
+ },
20
+ {
21
+ role: 'user',
22
+ content: prompt
23
+ }
24
+ ]
25
+ }
26
+ )
27
+ code_review_comments = process_response(response)
28
+ apply_code_review_comments(code_review_comments)
29
+ rescue StandardError => e
30
+ "Error communicating with OpenAI API: #{e.message}"
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CodeReviewAi
4
+ class Client
5
+ # Initialize a new CodeReviewAi client
6
+ #
7
+ # @param api_token [String] OpenAI API access token for authentication
8
+ # @param ai_model [String] OpenAI model to use (e.g., 'gpt-3.5-turbo', 'gpt-4')
9
+ # @param language [String] Output language for generated content
10
+ def initialize(api_token, ai_model, language)
11
+ @client = create_openai_client(api_token)
12
+ @ai_model = ai_model
13
+ @language = language
14
+ end
15
+
16
+ private
17
+
18
+ def create_openai_client(api_token)
19
+ OpenAI::Client.new(
20
+ access_token: api_token,
21
+ log_errors: true
22
+ )
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CodeReviewAi
4
+ class Client
5
+ private
6
+
7
+ def process_response(response)
8
+ response.dig('choices', 0, 'message', 'content') || 'Error: Unable to generate code review.'
9
+ end
10
+
11
+ def generate_prompt(template, language)
12
+ format(template, changes: fetch_branch_changes, language: language)
13
+ end
14
+
15
+ def fetch_branch_changes
16
+ current_branch = get_current_branch
17
+ default_branch = check_for_default_branch('main') || check_for_default_branch('master')
18
+
19
+ raise 'Neither main nor master branch found in the repository' unless default_branch
20
+ raise 'Could not determine current branch' unless current_branch
21
+
22
+ stdout, stderr, status = Open3.capture3("git diff #{default_branch}..#{current_branch}")
23
+
24
+ raise "Error getting git diff: #{stderr}" unless status.success?
25
+
26
+ stdout.strip
27
+ end
28
+
29
+ def check_for_default_branch(branch_name)
30
+ _, _, status = Open3.capture3("git show-ref refs/heads/#{branch_name}")
31
+ status.success? ? branch_name : nil
32
+ end
33
+
34
+ def get_current_branch
35
+ stdout, _, status = Open3.capture3('git rev-parse --abbrev-ref HEAD')
36
+ return stdout.strip if status.success?
37
+
38
+ nil
39
+ end
40
+
41
+ def apply_code_review_comments(code_review_comments)
42
+ comment_blocks = code_review_comments.scan(/File:\s+(.*?)\s+Line:\s+(\d+)\s+Suggestion:\s+(.*?)\s*(?:\n|$)/m)
43
+
44
+ comment_blocks.each do |file_path, line_number, suggestion|
45
+ add_comments_to_file(file_path, line_number.to_i, suggestion)
46
+ end
47
+ end
48
+
49
+ def add_comments_to_file(file_path, line_number, suggestion)
50
+ file_content = File.readlines(file_path)
51
+
52
+ # Ensure the line number is within the bounds of the file's length
53
+ if (1..file_content.size).cover?(line_number)
54
+ # Add the comment at the specified line
55
+ file_content[line_number - 1] = "#{file_content[line_number - 1].chomp} # #{suggestion}\n"
56
+ # Write the modified content back to the file
57
+ File.write(file_path, file_content.join)
58
+ else
59
+ puts "Warning: Line #{line_number} does not exist in file #{file_path}."
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,52 @@
1
+ module CodeReviewAi
2
+ module Prompts
3
+ CODE_REVIEW_TEMPLATE = <<~PROMPT
4
+ Act as a Ruby developer with expert-level knowledge of OOP principles and best practices.
5
+ You are tasked with reviewing the changes in the repository and providing ACTIONABLE code improvement suggestions.
6
+
7
+ I will specifiy the language(e.g., English) of the code review and provide the differences between the "current branch" and "main (or master)" branch at the end of this prompt.
8
+
9
+ Instructions for your response:
10
+
11
+ 1. Carefully analyze the changes in terms of Object-Oriented Principles, performance, readability and maintainability, scalability, and error handling.
12
+ 2. Provide improvement suggestions for each file and line number where applicable.
13
+ 3. Use the exact format like below for every suggestion:
14
+
15
+ "File: lib/code_review_ai.rb \nLine: 12 \nSuggestion: [👉SUGGESTION💡]Consider adding error handling for scenarios where the Git repository cannot be opened.\n\nFile: lib/code_review_ai.rb \nLine: 24 \nSuggestion: [👉SUGGESTION💡]Add a comment to explain the purpose of the `generate_code_review` method.\n\nFile: lib/code_review_ai.rb \nLine: 33 \nSuggestion: [👉SUGGESTION💡]Add a comment to clarify what the expected format of the prompt is.\n\nFile: lib/code_review_ai.rb \nLine: 41 \nSuggestion: [👉SUGGESTION💡]Include a comment to describe what `apply_code_review_comments` does."
16
+
17
+ Ensure that each suggestion is clearly associated with the relevant file and line of code.
18
+ Make sure to FOLLOW THE FORMAT strictly to avoid any errors in processing the suggestions.
19
+
20
+ If code examples are available, make your best effort to include them in the suggestions.
21
+
22
+ Make sure NOT TO RETURN ANYTHING OUTSIDE OF THE REQUIRED FORMAT. No introduction or conclusion is needed.
23
+
24
+ Please generate the code review suggestions in following language:
25
+ %<language>s
26
+
27
+ Here are the changes in the repository:
28
+ %<changes>s
29
+ PROMPT
30
+
31
+ BRANCH_SUMMARY_TEMPLATE = <<~PROMPT
32
+ You are a Ruby developer with expert-level proficiency in OOP principles and best practices.
33
+ Your task is to provide a concise, well-structured summary of the changes made in the following branch.
34
+
35
+ Please ensure that all output is written in %<language>s.
36
+
37
+ Follow this format for your summary:
38
+
39
+ 1. **Overview**: A high-level summary of the changes made in the branch, written in %<language>s.
40
+
41
+ 2. **File-wise Breakdown**: For each file, list the key changes in bullet points. Be specific and concise:
42
+ - **Summary**: A brief description of the change.
43
+ - **Impact**: How the change affects the functionality or performance.
44
+ - **Potential Issues**: Any concerns or potential pitfalls with the change.
45
+ - **Suggestions for Improvement**: Recommendations for enhancing the change or code.
46
+ - **Other Notes**: Any additional relevant details or context.
47
+
48
+ Changes:
49
+ %<changes>s
50
+ PROMPT
51
+ end
52
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CodeReviewAi
4
+ VERSION = '0.1.1'
5
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openai'
4
+ require 'open3'
5
+ require_relative 'code_review_ai/client/initialize'
6
+ require_relative 'code_review_ai/client/code_review'
7
+ require_relative 'code_review_ai/client/branch_summary'
8
+ require_relative 'code_review_ai/client/utils'
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: code-review-ai
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Michiharu Ono
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2025-01-26 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: faraday
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '2.1'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '2.1'
26
+ - !ruby/object:Gem::Dependency
27
+ name: optparse
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '0.6'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.6'
40
+ - !ruby/object:Gem::Dependency
41
+ name: ruby-openai
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '7.3'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '7.3'
54
+ - !ruby/object:Gem::Dependency
55
+ name: bundler-audit
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '0.9'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '0.9'
68
+ - !ruby/object:Gem::Dependency
69
+ name: pry
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 0.14.0
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 0.14.0
82
+ - !ruby/object:Gem::Dependency
83
+ name: rspec
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '3.13'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '3.13'
96
+ - !ruby/object:Gem::Dependency
97
+ name: rubocop
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '1.6'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '1.6'
110
+ description: CLI tool that leverages OpenAI to generate code reviews
111
+ email: michiharuono77@gmail.com
112
+ executables:
113
+ - code-review-ai
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - bin/code-review-ai
118
+ - lib/code_review_ai.rb
119
+ - lib/code_review_ai/client/branch_summary.rb
120
+ - lib/code_review_ai/client/code_review.rb
121
+ - lib/code_review_ai/client/initialize.rb
122
+ - lib/code_review_ai/client/utils.rb
123
+ - lib/code_review_ai/prompts.rb
124
+ - lib/code_review_ai/version.rb
125
+ licenses:
126
+ - MIT
127
+ metadata:
128
+ rubygems_mfa_required: 'true'
129
+ post_install_message: |
130
+ After installing the gem, please run the following command to install Node.js dependencies:
131
+ npm install -g standard-version
132
+
133
+ You can then add a changelog by running:
134
+ npx standard-version --no-tag
135
+ This refers the version defined in the package.json file.
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '3.0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubygems_version: 3.6.2
151
+ specification_version: 4
152
+ summary: Generate code reviews effortlessly using OpenAI.
153
+ test_files: []