aicommit 0.0.4 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +21 -0
- data/Readme.md +53 -0
- data/bin/aicommit +3 -1
- data/lib/aicommit.rb +48 -66
- data/lib/commit_message_generator.rb +27 -0
- data/lib/git_client.rb +41 -0
- data/lib/token_manager.rb +42 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0cd5fd61fe0b6342c4a58f1f2c3e5bcb3a406cc3088df91772ab2a9b43716dd0
|
4
|
+
data.tar.gz: 2cecba681f7a7f4b83d5390d945aa33ecb54a539a2386f513b551669ef580cfe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '08acb35449d5e7e78983d6f4f066cdbb31c9a2089a1d3adeed944ef7efbca95199eced51992c12c076dbebf2c19347da95807ce51ebc159b9425842a84ebc178'
|
7
|
+
data.tar.gz: 4b34a6394d6614f02c65d6cfe59858648921443a35de8e06d02c451be2fc60a19146f6a19a9f689e9b60177abf0a652ee34d6c7283a416d861f280aa3c964c16
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2023 EJ (YiJie)
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/Readme.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# AICommit
|
2
|
+
Use your own spell against you.
|
3
|
+
|
4
|
+
## Setup
|
5
|
+
### Prerequisites
|
6
|
+
- Ruby 2.5 or later
|
7
|
+
- An OpenAI API key
|
8
|
+
|
9
|
+
### Installation
|
10
|
+
Install the aicommit gem:
|
11
|
+
```bash
|
12
|
+
gem install aicommit
|
13
|
+
```
|
14
|
+
### Upgrading
|
15
|
+
To upgrade to the latest version of AICommit, run:
|
16
|
+
|
17
|
+
```bash
|
18
|
+
gem update aicommit
|
19
|
+
```
|
20
|
+
|
21
|
+
### Usage
|
22
|
+
#### Generate a commit message
|
23
|
+
To generate a commit message based on the changes in your Git repository:
|
24
|
+
|
25
|
+
1. Run the following command at the root of your project:
|
26
|
+
```bash
|
27
|
+
aicommit
|
28
|
+
```
|
29
|
+
|
30
|
+
2. The AI model will generate a commit message based on the changes in your Git repository.
|
31
|
+
|
32
|
+
3. Review the generated commit message.
|
33
|
+
|
34
|
+
4. To commit the changes with the generated commit message, enter Y at the prompt.
|
35
|
+
To enter a new commit message, enter N.
|
36
|
+
To quit without committing, enter Q.
|
37
|
+
|
38
|
+
#### Uninstallation
|
39
|
+
To uninstall AICommit, run:
|
40
|
+
|
41
|
+
```bash
|
42
|
+
gem uninstall aicommit
|
43
|
+
```
|
44
|
+
### How it works
|
45
|
+
AICommit uses OpenAI's GPT-3.5 AI model to generate commit messages based on the changes in your Git repository.
|
46
|
+
|
47
|
+
### Contributing
|
48
|
+
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
|
49
|
+
|
50
|
+
Please make sure to update tests as appropriate.
|
51
|
+
|
52
|
+
### License
|
53
|
+
This project is licensed under the MIT License - see the LICENSE.md file for details.
|
data/bin/aicommit
CHANGED
data/lib/aicommit.rb
CHANGED
@@ -1,79 +1,61 @@
|
|
1
1
|
require "git"
|
2
2
|
require "openai"
|
3
|
-
|
3
|
+
require_relative "token_manager"
|
4
|
+
require_relative "git_client"
|
5
|
+
require_relative "commit_message_generator"
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
puts "Please enter your OpenAI API key (or 'q' to quit):"
|
9
|
-
api_key = gets.chomp
|
10
|
-
if api_key.downcase == "q"
|
11
|
-
puts "Exiting program."
|
12
|
-
exit
|
7
|
+
class Aicommit
|
8
|
+
def initialize
|
9
|
+
@token_manager = TokenManager.new
|
13
10
|
end
|
14
11
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
12
|
+
def run
|
13
|
+
patch_diffs = git_client.get_patch_str
|
14
|
+
|
15
|
+
commit_message = get_commit_message(patch_diffs)
|
16
|
+
|
17
|
+
loop do
|
18
|
+
puts "commit_message: #{commit_message}"
|
19
|
+
puts "Do you want to keep this commit_message? (Y/R/N) (or Q to quit)"
|
20
|
+
case gets.chomp
|
21
|
+
when /^[Yy]$/
|
22
|
+
git_client.commit_all(commit_message)
|
23
|
+
puts "Committed all changes with message: #{commit_message}"
|
24
|
+
exit
|
25
|
+
when /^[Rr]$/
|
26
|
+
puts "Regenerating..."
|
27
|
+
commit_message = get_commit_message(patch_diffs)
|
28
|
+
when /^[Nn]$/
|
29
|
+
puts "Please enter your new commit_message:"
|
30
|
+
commit_message = gets.chomp
|
31
|
+
when /^[Qq]$/
|
32
|
+
puts "Quit without committing."
|
33
|
+
exit
|
34
|
+
else
|
35
|
+
puts "Invalid command. Please enter Y, N, or Q."
|
36
|
+
end
|
37
|
+
end
|
38
38
|
end
|
39
39
|
|
40
|
-
|
41
|
-
end
|
40
|
+
private
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
save_api_key_to_env
|
49
|
-
end
|
50
|
-
|
51
|
-
patch_str = ""
|
42
|
+
def get_commit_message(diff)
|
43
|
+
response = commit_message_generator.generate(diff)
|
44
|
+
if response[:code] == 401
|
45
|
+
puts "Invalid API key."
|
46
|
+
@token_manager.write!("OPENAI_API_TOKEN")
|
52
47
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
48
|
+
get_commit_message(diff)
|
49
|
+
else
|
50
|
+
response[:result]
|
51
|
+
end
|
52
|
+
end
|
59
53
|
|
60
|
-
|
54
|
+
def git_client
|
55
|
+
@_git_client ||= GitClient.new
|
56
|
+
end
|
61
57
|
|
62
|
-
|
63
|
-
|
64
|
-
puts "Do you want to keep this commit_message? (Y/N) (or Q to quit)"
|
65
|
-
command = gets.chomp
|
66
|
-
if command.match?(/^[Yy]$/)
|
67
|
-
git.commit_all(commit_message)
|
68
|
-
puts "Committed all changes with message: #{commit_message}"
|
69
|
-
break
|
70
|
-
elsif command.match?(/^[Nn]$/)
|
71
|
-
puts "Please enter your new commit_message:"
|
72
|
-
commit_message = gets.chomp
|
73
|
-
elsif command.match?(/^[Qq]$/)
|
74
|
-
puts "Quit without committing."
|
75
|
-
exit
|
76
|
-
else
|
77
|
-
puts "Invalid command. Please enter Y, N, or Q."
|
58
|
+
def commit_message_generator
|
59
|
+
@_commit_message_generator = CommitMessageGenerator.new(@token_manager.fetch("OPENAI_API_TOKEN"))
|
78
60
|
end
|
79
61
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "openai"
|
2
|
+
|
3
|
+
class CommitMessageGenerator
|
4
|
+
def initialize(access_token)
|
5
|
+
@client = OpenAI::Client.new(access_token: access_token)
|
6
|
+
end
|
7
|
+
|
8
|
+
def generate(diff)
|
9
|
+
response = @client.chat(
|
10
|
+
parameters: {
|
11
|
+
model: "gpt-3.5-turbo",
|
12
|
+
messages: set_messages(diff)
|
13
|
+
}
|
14
|
+
)
|
15
|
+
|
16
|
+
{result: response.dig("choices", 0, "message", "content")&.strip, code: response.code}
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def set_messages(diff)
|
22
|
+
diff = diff[-3800..] || diff
|
23
|
+
spell = "Please generate a commit message based on the following diff in one sentance and less than 80 letters: \n#{diff}"
|
24
|
+
|
25
|
+
[{role: "user", content: spell}]
|
26
|
+
end
|
27
|
+
end
|
data/lib/git_client.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
class GitClient
|
2
|
+
def initialize
|
3
|
+
if !Dir.exist?(".git")
|
4
|
+
puts "Not a git repository!"
|
5
|
+
exit
|
6
|
+
end
|
7
|
+
|
8
|
+
@git = Git.open(".")
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_patch_str
|
12
|
+
if current_branch.nil?
|
13
|
+
puts "No HEAD detected, please add your first commit, exiting program."
|
14
|
+
exit
|
15
|
+
end
|
16
|
+
|
17
|
+
patch_str = ""
|
18
|
+
@git.diff.each do |diff|
|
19
|
+
patch = diff.patch
|
20
|
+
patch_str += "\n\n#{diff.path}\n"
|
21
|
+
patch_str += patch
|
22
|
+
end
|
23
|
+
|
24
|
+
if patch_str.nil? || patch_str.strip.empty?
|
25
|
+
puts "No changes detected, exiting program."
|
26
|
+
exit
|
27
|
+
end
|
28
|
+
|
29
|
+
patch_str
|
30
|
+
end
|
31
|
+
|
32
|
+
def commit_all(message)
|
33
|
+
@git.commit_all(message)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def current_branch
|
39
|
+
@git.current_branch
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "dotenv"
|
2
|
+
|
3
|
+
class TokenManager
|
4
|
+
ENV_PATH = "#{File.expand_path("../..", __FILE__)}/.env".freeze
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
Dotenv.load(ENV_PATH)
|
8
|
+
end
|
9
|
+
|
10
|
+
def fetch(key)
|
11
|
+
api_token = ENV[key]
|
12
|
+
|
13
|
+
if api_token.nil? || api_token.empty?
|
14
|
+
save_api_token_to_env!(key, gets_api_token)
|
15
|
+
else
|
16
|
+
api_token
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def write!(key)
|
21
|
+
save_api_token_to_env!(key, gets_api_token)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def gets_api_token
|
27
|
+
puts "Please enter your OpenAI API token (or 'q' to quit):"
|
28
|
+
api_token = gets.chomp
|
29
|
+
if api_token.downcase == "q"
|
30
|
+
puts "Exiting program."
|
31
|
+
exit
|
32
|
+
end
|
33
|
+
api_token
|
34
|
+
end
|
35
|
+
|
36
|
+
def save_api_token_to_env!(key, api_token)
|
37
|
+
File.write(ENV_PATH, "#{key}=#{api_token}")
|
38
|
+
Dotenv.overload!(ENV_PATH)
|
39
|
+
puts "Your API token has been saved to .env"
|
40
|
+
api_token
|
41
|
+
end
|
42
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aicommit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jackal998
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-03-
|
12
|
+
date: 2023-03-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: git
|
@@ -61,8 +61,13 @@ executables:
|
|
61
61
|
extensions: []
|
62
62
|
extra_rdoc_files: []
|
63
63
|
files:
|
64
|
+
- LICENSE
|
65
|
+
- Readme.md
|
64
66
|
- bin/aicommit
|
65
67
|
- lib/aicommit.rb
|
68
|
+
- lib/commit_message_generator.rb
|
69
|
+
- lib/git_client.rb
|
70
|
+
- lib/token_manager.rb
|
66
71
|
homepage: https://github.com/jackal998/aicommit
|
67
72
|
licenses:
|
68
73
|
- MIT
|