pr_ai_gen 0.1.0

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: 9d88c164cc0b3c276e43759573219cc064e5d141cd264d46e184bca12f02926b
4
+ data.tar.gz: 10041eea9b1b4465539cf00d260782692f84db5ea2347b8cbe5cc2bbdd725c57
5
+ SHA512:
6
+ metadata.gz: dc88eee40aed632629dc2bdb1eb2fc2fa9ee5017b95a4f6c0dba9d2c9ca70d998563c020c6640766af70d57bdf6d74bf4412abe6d532730788e04e204f75d2fa
7
+ data.tar.gz: 553d015be904145afab53f9dde76bf605fe12d6d875ee5341522c18f637c84879c061e777c307edef44daba0a3c84dabff949153f37c29ede5c724812b1f5dce
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem 'git'
4
+ gem 'httparty'
5
+ gem 'octokit'
6
+ gem 'capybara'
7
+ gem 'selenium-webdriver'
8
+ gem 'optparse'
9
+ gem 'pry'
data/Gemfile.lock ADDED
@@ -0,0 +1,82 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ addressable (2.8.6)
5
+ public_suffix (>= 2.0.2, < 6.0)
6
+ base64 (0.2.0)
7
+ capybara (3.39.2)
8
+ addressable
9
+ matrix
10
+ mini_mime (>= 0.1.3)
11
+ nokogiri (~> 1.8)
12
+ rack (>= 1.6.0)
13
+ rack-test (>= 0.6.3)
14
+ regexp_parser (>= 1.5, < 3.0)
15
+ xpath (~> 3.2)
16
+ coderay (1.1.3)
17
+ faraday (2.8.1)
18
+ base64
19
+ faraday-net_http (>= 2.0, < 3.1)
20
+ ruby2_keywords (>= 0.0.4)
21
+ faraday-net_http (3.0.2)
22
+ git (1.19.1)
23
+ addressable (~> 2.8)
24
+ rchardet (~> 1.8)
25
+ httparty (0.20.0)
26
+ mime-types (~> 3.0)
27
+ multi_xml (>= 0.5.2)
28
+ matrix (0.4.2)
29
+ method_source (1.0.0)
30
+ mime-types (3.4.1)
31
+ mime-types-data (~> 3.2015)
32
+ mime-types-data (3.2022.0105)
33
+ mini_mime (1.1.5)
34
+ multi_xml (0.6.0)
35
+ nokogiri (1.15.5-arm64-darwin)
36
+ racc (~> 1.4)
37
+ nokogiri (1.15.5-x86_64-linux)
38
+ racc (~> 1.4)
39
+ octokit (8.1.0)
40
+ base64
41
+ faraday (>= 1, < 3)
42
+ sawyer (~> 0.9)
43
+ optparse (0.4.0)
44
+ pry (0.14.1)
45
+ coderay (~> 1.1)
46
+ method_source (~> 1.0)
47
+ public_suffix (5.0.4)
48
+ racc (1.7.3)
49
+ rack (3.0.9.1)
50
+ rack-test (2.1.0)
51
+ rack (>= 1.3)
52
+ rchardet (1.8.0)
53
+ regexp_parser (2.9.0)
54
+ rexml (3.2.6)
55
+ ruby2_keywords (0.0.5)
56
+ rubyzip (2.3.2)
57
+ sawyer (0.9.2)
58
+ addressable (>= 2.3.5)
59
+ faraday (>= 0.17.3, < 3)
60
+ selenium-webdriver (4.9.0)
61
+ rexml (~> 3.2, >= 3.2.5)
62
+ rubyzip (>= 1.2.2, < 3.0)
63
+ websocket (~> 1.0)
64
+ websocket (1.2.10)
65
+ xpath (3.2.0)
66
+ nokogiri (~> 1.8)
67
+
68
+ PLATFORMS
69
+ arm64-darwin-22
70
+ x86_64-linux
71
+
72
+ DEPENDENCIES
73
+ capybara
74
+ git
75
+ httparty
76
+ octokit
77
+ optparse
78
+ pry
79
+ selenium-webdriver
80
+
81
+ BUNDLED WITH
82
+ 2.4.21
data/exe/pr-ai-gen ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/pull_request_ai_generator'
4
+
5
+ generator = PullRequestAIGenerator.new(ARGV)
6
+
7
+ case generator.options[:command]
8
+ when :init
9
+ generator.init
10
+ else
11
+ generator.run
12
+ end
@@ -0,0 +1,161 @@
1
+ require 'optparse'
2
+ require 'git'
3
+ require 'httparty'
4
+ require 'octokit'
5
+ require 'capybara/dsl'
6
+ require 'pry'
7
+
8
+ # Define the CLI class
9
+ class PullRequestAIGenerator
10
+ OPEN_AI_URL = "https://api.openai.com/v1"
11
+
12
+ include Capybara::DSL
13
+
14
+ attr_reader :options
15
+
16
+ def initialize(args)
17
+ @options = parse_options(args)
18
+ @diff = nil
19
+ @pr_content = nil
20
+ @git_repo = nil
21
+ end
22
+
23
+ def init
24
+ puts 'Initializing pr-ai-gen...'
25
+ credentials_path = File.expand_path('~/.pr-gem/credentials')
26
+ pr_gem_path = File.expand_path('~/.pr-gem')
27
+
28
+ unless File.exist?(pr_gem_path)
29
+ Dir.mkdir(pr_gem_path)
30
+ puts '.pr-gem repository created successfully!'
31
+ end
32
+
33
+ if File.exist?(credentials_path)
34
+ puts 'Credentials file already exists!'
35
+ return
36
+ end
37
+
38
+ puts 'Please enter your OpenAI API key:'
39
+ openai_token = STDIN.gets.chomp
40
+ File.write(credentials_path, "OPENAI_TOKEN=#{openai_token}\n")
41
+ puts 'Credentials file created successfully!'
42
+ end
43
+
44
+ def run
45
+ puts 'Running pr-ai-gen...'
46
+ fetch_diff
47
+ load_template
48
+ get_openai_token
49
+ generate_pr_content
50
+ print_content
51
+ end
52
+
53
+ private
54
+
55
+ def parse_options(args)
56
+ options = { target_branch: 'main', directory_location: File.expand_path("."), command: :run }
57
+
58
+ if args[0] == 'init'
59
+ options[:command] = :init
60
+ elsif args[0] == 'generate'
61
+ options[:command] = :run
62
+
63
+ if args[1]
64
+ options[:directory_location] = File.expand_path(args[1])
65
+ end
66
+
67
+ if args[2]
68
+ local, target = args[2].split(':')
69
+ options[:local_branch] = local
70
+ options[:target_branch] = target || options[:target_branch]
71
+ end
72
+ else
73
+ raise Exception.new "Invalid command!"
74
+ end
75
+
76
+ OptionParser.new do |opts|
77
+ opts.banner = "Usage: pr-ai-gen <directory_location> <branch>:<target-branch=main>"
78
+
79
+ opts.on("-h", "--help", "Prints this help") do
80
+ puts opts
81
+ exit
82
+ end
83
+
84
+ end.parse!(args)
85
+
86
+ options
87
+ end
88
+
89
+ def fetch_diff
90
+ # Start the ssh-agent in the background
91
+ `eval $(ssh-agent -s)`
92
+
93
+ # Add your SSH private key to the ssh-agent
94
+ `ssh-add ~/.ssh/id_ed25519`
95
+ ssh_keys = `ssh-add -l`
96
+
97
+ if ssh_keys.include?('No identities')
98
+ puts 'No SSH keys are added to the ssh-agent.'
99
+ exit
100
+ end
101
+
102
+ @git_repo = Git.open(@options[:directory_location])
103
+ @git_repo.fetch
104
+ @git_repo.checkout(@options[:local_branch])
105
+ @diff = @git_repo.diff(@options[:target_branch], @options[:local_branch])
106
+ end
107
+
108
+ def load_template
109
+ template_path = File.join(@options[:directory_location], '.github', 'PULL_REQUEST_TEMPLATE.md')
110
+ if File.exist?(template_path)
111
+ @template = File.read(template_path)
112
+ else
113
+ @template = "# Default PR Template\n\n## Changes Made\n\nDescribe your changes in detail here."
114
+ end
115
+ end
116
+
117
+ def get_openai_token
118
+ credentials_path = File.expand_path('~/.pr-gem/credentials')
119
+ if File.exist?(credentials_path)
120
+ credentials = File.readlines(credentials_path).map(&:strip)
121
+ @openai_token = credentials.find { |line| line.start_with?('OPENAI_TOKEN=') }
122
+ raise "OpenAI credentials not found!" unless @openai_token
123
+ @openai_token = @openai_token.split('=')[1]
124
+ else
125
+ raise "OpenAI credentials file not found!"
126
+ end
127
+ end
128
+
129
+ def generate_pr_content
130
+ puts "Generating PR content..."
131
+
132
+ response = HTTParty.post(
133
+ "#{OPEN_AI_URL}/chat/completions",
134
+ headers: {
135
+ "Content-Type" => "application/json",
136
+ "Authorization" => "Bearer #{@openai_token}"
137
+ },
138
+ body: {
139
+ model: "gpt-4-turbo-preview",
140
+ messages: [
141
+ {
142
+ role: "user",
143
+ content: "fill this templete:\n #{@template}\n with the following changes:\n #{@diff.to_s}"
144
+ },
145
+ ],
146
+ max_tokens: 1024
147
+ }.to_json
148
+ )
149
+
150
+ @pr_content = response.dig("choices", 0, "message", "content").strip
151
+
152
+ puts "PR content generated successfully!"
153
+ end
154
+
155
+ def print_content
156
+ puts "PR CONTENT FOLLOWING:"
157
+ puts "BEGIN-------------------------------------------------------------------------"
158
+ puts @pr_content
159
+ puts "---------------------------------------------------------------------------END"
160
+ end
161
+ end
data/pr_ai_gen.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "pr_ai_gen"
3
+ spec.version = "0.1.0"
4
+ spec.authors = ["Lucas Stoller"]
5
+ spec.email = ["l.s.stoller@gmail.com"]
6
+ spec.summary = "A CLI tool to generate pull requests using OpenAI"
7
+ spec.description = "This tool automates the process of creating pull requests by using OpenAI to generate the content based on the differences between two git branches."
8
+ spec.homepage = "https://theright.dev"
9
+
10
+ spec.files = `git ls-files`.split($/)
11
+ spec.bindir = "exe"
12
+ spec.executables = spec.executables = ['pr-ai-gen']
13
+ spec.require_paths = ["lib"]
14
+
15
+ spec.add_dependency "git"
16
+ spec.add_dependency "openai"
17
+ spec.add_dependency "octokit"
18
+ spec.add_dependency "capybara"
19
+ spec.add_dependency "selenium-webdriver"
20
+
21
+ spec.add_development_dependency "bundler", "~> 2.0"
22
+ spec.add_development_dependency "rake", "~> 13.0"
23
+ end
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pr_ai_gen
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Lucas Stoller
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-03-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: git
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: openai
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: octokit
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: capybara
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: selenium-webdriver
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: bundler
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '13.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '13.0'
111
+ description: This tool automates the process of creating pull requests by using OpenAI
112
+ to generate the content based on the differences between two git branches.
113
+ email:
114
+ - l.s.stoller@gmail.com
115
+ executables:
116
+ - pr-ai-gen
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - ".gitignore"
121
+ - Gemfile
122
+ - Gemfile.lock
123
+ - exe/pr-ai-gen
124
+ - lib/pull_request_ai_generator.rb
125
+ - pr_ai_gen.gemspec
126
+ homepage: https://theright.dev
127
+ licenses: []
128
+ metadata: {}
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubygems_version: 3.3.7
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: A CLI tool to generate pull requests using OpenAI
148
+ test_files: []