aicommit 0.0.4 → 0.0.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cea626b0f559f65a95e71bfdb301aefc9a43f6e9db7f527f6674a347f0f32146
4
- data.tar.gz: a86134c702c388c4d1b03a59818fdc51f982fd9b7c5a9a22b11c58f98fb2b796
3
+ metadata.gz: 0cd5fd61fe0b6342c4a58f1f2c3e5bcb3a406cc3088df91772ab2a9b43716dd0
4
+ data.tar.gz: 2cecba681f7a7f4b83d5390d945aa33ecb54a539a2386f513b551669ef580cfe
5
5
  SHA512:
6
- metadata.gz: b79282e1267f605a695130fe5cb9485db187058bf9f6de3c2e88eaba3a1f94ef68183790a166ec0db55e250a56369d2e71a77a248ac037d5973660f3027d4013
7
- data.tar.gz: 6429a2aa883f599c74588a63e7c287bde92107a5bb3372fce8fc38bc9104e1cd0c0b552d61ba2e9c82630633227e445113e6e42c8b3944408b39c43d3554b9c1
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
@@ -1,3 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "aicommit"
3
+ require_relative "../lib/aicommit"
4
+
5
+ Aicommit.new.run
data/lib/aicommit.rb CHANGED
@@ -1,79 +1,61 @@
1
1
  require "git"
2
2
  require "openai"
3
- require "dotenv"
3
+ require_relative "token_manager"
4
+ require_relative "git_client"
5
+ require_relative "commit_message_generator"
4
6
 
5
- Dotenv.load("#{File.expand_path("../..", __FILE__)}/.env")
6
-
7
- def save_api_key_to_env
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
- File.write("#{File.expand_path("../..", __FILE__)}/.env", "OPENAI_API_KEY=#{api_key}")
16
-
17
- Dotenv.overload!("#{File.expand_path("../..", __FILE__)}/.env")
18
- puts "Your API key has been saved to .env"
19
- end
20
-
21
- def generate_commit_message(diff)
22
- diff = diff[-3800..] || diff
23
- client = OpenAI::Client.new(access_token: ENV["OPENAI_API_KEY"])
24
- content = "Please generate a commit message based on the following diff in one sentance and less than 80 letters:\n#{diff}"
25
-
26
- response = client.chat(
27
- parameters: {
28
- model: "gpt-3.5-turbo",
29
- messages: [{role: "user", content: content}]
30
- }
31
- )
32
-
33
- if response.code == 401
34
- puts "Invalid API key."
35
- save_api_key_to_env
36
-
37
- return generate_commit_message(diff)
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
- response.dig("choices", 0, "message", "content")
41
- end
40
+ private
42
41
 
43
- if !Dir.exist?(".git")
44
- raise "Not a git repository!"
45
- end
46
-
47
- if ENV["OPENAI_API_KEY"].nil?
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
- git = Git.open(".")
54
- git.diff.each do |diff|
55
- patch = diff.patch
56
- patch_str += "\n\n#{diff.path}\n"
57
- patch_str += patch
58
- end
48
+ get_commit_message(diff)
49
+ else
50
+ response[:result]
51
+ end
52
+ end
59
53
 
60
- commit_message = generate_commit_message(patch_str)
54
+ def git_client
55
+ @_git_client ||= GitClient.new
56
+ end
61
57
 
62
- loop do
63
- puts "commit_message: #{commit_message}"
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
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-06 00:00:00.000000000 Z
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