gpt-pr 0.2.0__py3-none-any.whl → 0.3.0__py3-none-any.whl
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.
Potentially problematic release.
This version of gpt-pr might be problematic. Click here for more details.
- {gpt_pr-0.2.0.dist-info → gpt_pr-0.3.0.dist-info}/METADATA +5 -5
- gpt_pr-0.3.0.dist-info/RECORD +15 -0
- {gpt_pr-0.2.0.dist-info → gpt_pr-0.3.0.dist-info}/entry_points.txt +1 -0
- gptpr/config.py +97 -0
- gptpr/gh.py +16 -6
- gptpr/gitutil.py +10 -8
- gptpr/main.py +45 -0
- gptpr/prdata.py +20 -8
- gptpr/test_config.py +99 -0
- gptpr/version.py +1 -1
- gpt_pr-0.2.0.dist-info/RECORD +0 -13
- {gpt_pr-0.2.0.dist-info → gpt_pr-0.3.0.dist-info}/WHEEL +0 -0
- {gpt_pr-0.2.0.dist-info → gpt_pr-0.3.0.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: gpt-pr
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Automate your GitHub workflow with GPT-PR: an OpenAI powered library for streamlined PR generation.
|
|
5
5
|
Home-page: http://github.com/alissonperez/gpt-pr
|
|
6
6
|
Author: Alisson R. Perez
|
|
@@ -8,19 +8,19 @@ Author-email: alissonperez@outlook.com
|
|
|
8
8
|
License: MIT
|
|
9
9
|
Requires-Python: >=3.7
|
|
10
10
|
Requires-Dist: cffi ==1.15.1
|
|
11
|
-
Requires-Dist: cryptography ==42.0.
|
|
11
|
+
Requires-Dist: cryptography ==42.0.7
|
|
12
12
|
Requires-Dist: fire ==0.6.0
|
|
13
13
|
Requires-Dist: pycparser ==2.21
|
|
14
14
|
Requires-Dist: wcwidth ==0.2.13
|
|
15
15
|
Requires-Dist: charset-normalizer ==3.3.2 ; python_full_version >= "3.7.0"
|
|
16
16
|
Requires-Dist: prompt-toolkit ==3.0.43 ; python_full_version >= "3.7.0"
|
|
17
17
|
Requires-Dist: openai ==1.14.0 ; python_full_version >= "3.7.1"
|
|
18
|
-
Requires-Dist: exceptiongroup ==1.2.
|
|
18
|
+
Requires-Dist: exceptiongroup ==1.2.1 ; python_version < "3.11"
|
|
19
19
|
Requires-Dist: cached-property ==1.5.2 ; python_version < "3.8"
|
|
20
20
|
Requires-Dist: importlib-metadata ==6.7.0 ; python_version == "3.7"
|
|
21
21
|
Requires-Dist: six ==1.16.0 ; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2"
|
|
22
22
|
Requires-Dist: deprecated ==1.2.14 ; python_version >= "2.7" and python_version not in "3.0, 3.1, 3.2, 3.3"
|
|
23
|
-
Requires-Dist: idna ==3.
|
|
23
|
+
Requires-Dist: idna ==3.7 ; python_version >= "3.5"
|
|
24
24
|
Requires-Dist: certifi ==2024.2.2 ; python_version >= "3.6"
|
|
25
25
|
Requires-Dist: distro ==1.9.0 ; python_version >= "3.6"
|
|
26
26
|
Requires-Dist: pynacl ==1.5.0 ; python_version >= "3.6"
|
|
@@ -40,7 +40,7 @@ Requires-Dist: requests ==2.31.0 ; python_version >= "3.7"
|
|
|
40
40
|
Requires-Dist: smmap ==5.0.1 ; python_version >= "3.7"
|
|
41
41
|
Requires-Dist: sniffio ==1.3.1 ; python_version >= "3.7"
|
|
42
42
|
Requires-Dist: termcolor ==2.3.0 ; python_version >= "3.7"
|
|
43
|
-
Requires-Dist: tqdm ==4.66.
|
|
43
|
+
Requires-Dist: tqdm ==4.66.4 ; python_version >= "3.7"
|
|
44
44
|
Requires-Dist: typing-extensions ==4.7.1 ; python_version >= "3.7"
|
|
45
45
|
Requires-Dist: urllib3 ==2.0.7 ; python_version >= "3.7"
|
|
46
46
|
Requires-Dist: zipp ==3.15.0 ; python_version >= "3.7"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
gptpr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
gptpr/config.py,sha256=YVQgTuJYVwqAabqK-E3xSzlc4QUvZb0q4dUW-_pY2cg,2609
|
|
3
|
+
gptpr/consolecolor.py,sha256=_JmBMNjIflWMlgP2VkCWu6uQLR9oHBy52uV3TRJJgF4,800
|
|
4
|
+
gptpr/gh.py,sha256=uSWY_TzbrAM00neOBkyfV5vxDO4FzMtIrs-Zczp-Tck,1127
|
|
5
|
+
gptpr/gitutil.py,sha256=NBD3iRnbFEPRU47w7c5TowwtZieDYkU4zybvv0PoOU0,5783
|
|
6
|
+
gptpr/main.py,sha256=tc1iLkGVWa0O2gGRAPlGP8MTRA3B1xryIX1Hi6MCn9w,2595
|
|
7
|
+
gptpr/prdata.py,sha256=ejx4zLRViJ83OmqvlxGWnw7alo8RPL_YdlwEJFhMQ8g,6183
|
|
8
|
+
gptpr/test_config.py,sha256=_vP-3RJf8WXGGQESr5bCUbmxf8owc1uVJXMSBF_MtH0,2712
|
|
9
|
+
gptpr/test_prdata.py,sha256=rSJ-yqOdw-iYdBWyqnA2SXbdrhT8KgIkRTTf9SY1S1g,474
|
|
10
|
+
gptpr/version.py,sha256=VrXpHDu3erkzwl_WXrqINBm9xWkcyUy53IQOj042dOs,22
|
|
11
|
+
gpt_pr-0.3.0.dist-info/METADATA,sha256=sva8MD89gNrCtK1xWkfHyJvP1A5JOhW15SS1nC-TwwQ,2638
|
|
12
|
+
gpt_pr-0.3.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
13
|
+
gpt_pr-0.3.0.dist-info/entry_points.txt,sha256=WhcbcQXqo5-IGliYWiYMhop4-Wm7bcH2ljFKLWrmO7c,81
|
|
14
|
+
gpt_pr-0.3.0.dist-info/top_level.txt,sha256=DZcbzlsjh4BD8njGcvhOeCZ83U_oYWgCn0w8qx5--04,6
|
|
15
|
+
gpt_pr-0.3.0.dist-info/RECORD,,
|
gptpr/config.py
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
from copy import deepcopy
|
|
2
|
+
import configparser
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def config_command_example(name, value_sample):
|
|
7
|
+
return f'gpt-pr-config set {name} {value_sample}'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
CONFIG_README_SECTION = 'https://github.com/alissonperez/gpt-pr?tab=readme-ov-file#authentication--api-keys'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Config:
|
|
14
|
+
|
|
15
|
+
config_filename = '.gpt-pr.ini'
|
|
16
|
+
|
|
17
|
+
_default_config = {
|
|
18
|
+
# Github
|
|
19
|
+
'GH_TOKEN': '',
|
|
20
|
+
|
|
21
|
+
# Open AI info
|
|
22
|
+
'OPENAI_MODEL': 'gpt-4o',
|
|
23
|
+
'OPENAI_API_KEY': '',
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
def __init__(self, config_dir=None):
|
|
27
|
+
self.default_config = deepcopy(self._default_config)
|
|
28
|
+
self._config_dir = config_dir or os.path.expanduser('~')
|
|
29
|
+
self._config = configparser.ConfigParser()
|
|
30
|
+
self._initialized = False
|
|
31
|
+
|
|
32
|
+
def load(self):
|
|
33
|
+
if self._initialized:
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
config_file_path = self.get_filepath()
|
|
37
|
+
|
|
38
|
+
if os.path.exists(config_file_path):
|
|
39
|
+
self._config.read(config_file_path)
|
|
40
|
+
self._ensure_default_values()
|
|
41
|
+
else:
|
|
42
|
+
self._config['user'] = {}
|
|
43
|
+
self._config['DEFAULT'] = deepcopy(self.default_config)
|
|
44
|
+
self.persist()
|
|
45
|
+
|
|
46
|
+
self._initialized = True
|
|
47
|
+
|
|
48
|
+
def _ensure_default_values(self):
|
|
49
|
+
added = False
|
|
50
|
+
for key, value in self.default_config.items():
|
|
51
|
+
if key not in self._config['DEFAULT']:
|
|
52
|
+
self._config['DEFAULT'][key] = value
|
|
53
|
+
added = True
|
|
54
|
+
|
|
55
|
+
if added:
|
|
56
|
+
self.persist()
|
|
57
|
+
|
|
58
|
+
def persist(self):
|
|
59
|
+
config_file_path = self.get_filepath()
|
|
60
|
+
|
|
61
|
+
with open(config_file_path, 'w') as configfile:
|
|
62
|
+
self._config.write(configfile)
|
|
63
|
+
|
|
64
|
+
def get_filepath(self):
|
|
65
|
+
return os.path.join(self._config_dir, self.config_filename)
|
|
66
|
+
|
|
67
|
+
def set_user_config(self, name, value):
|
|
68
|
+
self.load()
|
|
69
|
+
self._config['user'][name] = value
|
|
70
|
+
|
|
71
|
+
def reset_user_config(self, name):
|
|
72
|
+
self.load()
|
|
73
|
+
self._config['user'][name] = self.default_config[name]
|
|
74
|
+
self.persist()
|
|
75
|
+
|
|
76
|
+
def get_user_config(self, name):
|
|
77
|
+
self.load()
|
|
78
|
+
return self._config['user'][name]
|
|
79
|
+
|
|
80
|
+
def all_values(self):
|
|
81
|
+
self.load()
|
|
82
|
+
|
|
83
|
+
# iterate over all sections and values and return them in a list
|
|
84
|
+
result = []
|
|
85
|
+
|
|
86
|
+
# add default section
|
|
87
|
+
for option in self._config['DEFAULT']:
|
|
88
|
+
result.append(('DEFAULT', option, self._config['DEFAULT'][option]))
|
|
89
|
+
|
|
90
|
+
for section in self._config.sections():
|
|
91
|
+
for option in self._config[section]:
|
|
92
|
+
result.append((section, option, self._config[section][option]))
|
|
93
|
+
|
|
94
|
+
return result
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
config = Config()
|
gptpr/gh.py
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from github import Github
|
|
3
3
|
from InquirerPy import inquirer
|
|
4
|
+
from gptpr.config import config, config_command_example, CONFIG_README_SECTION
|
|
4
5
|
|
|
5
|
-
GH_TOKEN = os.environ.get('GH_TOKEN')
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
def _get_gh_token():
|
|
8
|
+
gh_token = config.get_user_config('GH_TOKEN')
|
|
9
|
+
if not gh_token:
|
|
10
|
+
gh_token = os.environ.get('GH_TOKEN')
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
if not gh_token:
|
|
13
|
+
print('Please set "gh_token" config. Just run:',
|
|
14
|
+
config_command_example('gh_token', '[my gh token]'),
|
|
15
|
+
'more about at', CONFIG_README_SECTION)
|
|
16
|
+
exit(1)
|
|
17
|
+
|
|
18
|
+
return gh_token
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
gh = Github(_get_gh_token())
|
|
12
22
|
|
|
13
23
|
|
|
14
24
|
def create_pr(pr_data, yield_confirmation):
|
|
@@ -21,7 +31,7 @@ def create_pr(pr_data, yield_confirmation):
|
|
|
21
31
|
|
|
22
32
|
if pr_confirmation:
|
|
23
33
|
pr = repo.create_pull(title=pr_data.title, body=pr_data.body,
|
|
24
|
-
head=pr_data.branch_info.branch, base=
|
|
34
|
+
head=pr_data.branch_info.branch, base=pr_data.branch_info.base_branch)
|
|
25
35
|
print("Pull request created successfully: ", pr.html_url)
|
|
26
36
|
else:
|
|
27
37
|
print('cancelling...')
|
gptpr/gitutil.py
CHANGED
|
@@ -10,6 +10,7 @@ from InquirerPy.base.control import Choice
|
|
|
10
10
|
class BranchInfo:
|
|
11
11
|
owner: str
|
|
12
12
|
repo: str
|
|
13
|
+
base_branch: str
|
|
13
14
|
branch: str
|
|
14
15
|
commits: list
|
|
15
16
|
highlight_commits: list
|
|
@@ -70,10 +71,11 @@ def get_branch_info(base_branch, yield_confirmation):
|
|
|
70
71
|
return BranchInfo(
|
|
71
72
|
owner=owner,
|
|
72
73
|
repo=repo_name,
|
|
74
|
+
base_branch=base_branch,
|
|
73
75
|
branch=current_branch.name,
|
|
74
76
|
commits=commits,
|
|
75
77
|
highlight_commits=highlight_commits,
|
|
76
|
-
diff=_get_diff_changes(repo, current_branch.name, yield_confirmation)
|
|
78
|
+
diff=_get_diff_changes(repo, base_branch, current_branch.name, yield_confirmation)
|
|
77
79
|
)
|
|
78
80
|
|
|
79
81
|
|
|
@@ -85,7 +87,7 @@ def _branch_exists(repo, branch_name):
|
|
|
85
87
|
|
|
86
88
|
|
|
87
89
|
def _get_diff_messages_against_base_branch(repo, branch, base_branch):
|
|
88
|
-
# Get commit messages that are in the current branch but not in the
|
|
90
|
+
# Get commit messages that are in the current branch but not in the base branch
|
|
89
91
|
commits_diff = list(repo.iter_commits(f'{base_branch}..{branch}'))
|
|
90
92
|
|
|
91
93
|
return [commit.message.strip('\n') for commit in commits_diff]
|
|
@@ -147,33 +149,33 @@ def _extract_owner_and_repo(repo_url):
|
|
|
147
149
|
return owner, '.'.join(repo_info.split('.')[:-1])
|
|
148
150
|
|
|
149
151
|
|
|
150
|
-
def _get_diff_changes(repo, branch, yield_confirmation):
|
|
152
|
+
def _get_diff_changes(repo, base_branch, branch, yield_confirmation):
|
|
151
153
|
diff_changes = []
|
|
152
154
|
|
|
153
|
-
stats = _get_stats(repo, branch)
|
|
155
|
+
stats = _get_stats(repo, base_branch, branch)
|
|
154
156
|
files_to_ignore = _get_files_to_ignore(stats, yield_confirmation)
|
|
155
157
|
|
|
156
158
|
for file_change in stats:
|
|
157
159
|
if file_change.file_path in files_to_ignore:
|
|
158
160
|
continue
|
|
159
161
|
|
|
160
|
-
file_diff = repo.git.diff(
|
|
162
|
+
file_diff = repo.git.diff(base_branch, branch, '--', file_change.file_path)
|
|
161
163
|
|
|
162
164
|
diff_changes.append(file_diff)
|
|
163
165
|
|
|
164
166
|
return '\n'.join(diff_changes)
|
|
165
167
|
|
|
166
168
|
|
|
167
|
-
def _get_stats(repo, branch):
|
|
169
|
+
def _get_stats(repo, base_branch, branch):
|
|
168
170
|
'''
|
|
169
|
-
Get the stats of the difference between the current branch and the
|
|
171
|
+
Get the stats of the difference between the current branch and the base branch
|
|
170
172
|
'''
|
|
171
173
|
|
|
172
174
|
# returns:
|
|
173
175
|
# 4 0 README.md
|
|
174
176
|
# 2 0 application/aggregator/aggregator.go
|
|
175
177
|
# 0 257 go.sum
|
|
176
|
-
diff_index = repo.git.diff(
|
|
178
|
+
diff_index = repo.git.diff(base_branch, branch, '--numstat')
|
|
177
179
|
|
|
178
180
|
files_changed = []
|
|
179
181
|
for line in diff_index.split('\n'):
|
gptpr/main.py
CHANGED
|
@@ -5,6 +5,8 @@ from gptpr.gitutil import get_branch_info
|
|
|
5
5
|
from gptpr.gh import create_pr
|
|
6
6
|
from gptpr.prdata import get_pr_data
|
|
7
7
|
from gptpr.version import __version__
|
|
8
|
+
from gptpr.config import config, config_command_example, CONFIG_README_SECTION
|
|
9
|
+
from gptpr import consolecolor as cc
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
def run(base_branch='main', yield_confirmation=False, version=False):
|
|
@@ -44,9 +46,52 @@ def run(base_branch='main', yield_confirmation=False, version=False):
|
|
|
44
46
|
create_pr(pr_data, yield_confirmation)
|
|
45
47
|
|
|
46
48
|
|
|
49
|
+
def set_config(name, value):
|
|
50
|
+
name = name.upper()
|
|
51
|
+
config.set_user_config(name, value)
|
|
52
|
+
config.persist()
|
|
53
|
+
|
|
54
|
+
print('Config value', cc.bold(name), 'set to', cc.yellow(value))
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def get_config(name):
|
|
58
|
+
upper_name = name.upper()
|
|
59
|
+
print('Config value', cc.bold(name), '=', cc.yellow(config.get_user_config(upper_name)))
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def reset_config(name):
|
|
63
|
+
upper_name = name.upper()
|
|
64
|
+
config.reset_user_config(upper_name)
|
|
65
|
+
print('Config value', cc.bold(name), '=', cc.yellow(config.get_user_config(upper_name)))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def print_config():
|
|
69
|
+
print('Config values at', cc.yellow(config.get_filepath()))
|
|
70
|
+
print('')
|
|
71
|
+
print('To set values, just run:', cc.yellow(config_command_example('[config name]', '[value]')))
|
|
72
|
+
print('More about at', cc.yellow(CONFIG_README_SECTION))
|
|
73
|
+
print('')
|
|
74
|
+
current_section = None
|
|
75
|
+
for section, option, value in config.all_values():
|
|
76
|
+
if current_section != section:
|
|
77
|
+
print('')
|
|
78
|
+
current_section = section
|
|
79
|
+
|
|
80
|
+
print(f'[{cc.bold(section)}]', option, '=', cc.yellow(value))
|
|
81
|
+
|
|
82
|
+
|
|
47
83
|
def main():
|
|
48
84
|
fire.Fire(run)
|
|
49
85
|
|
|
50
86
|
|
|
87
|
+
def run_config():
|
|
88
|
+
fire.Fire({
|
|
89
|
+
'set': set_config,
|
|
90
|
+
'get': get_config,
|
|
91
|
+
'print': print_config,
|
|
92
|
+
'reset': reset_config
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
|
|
51
96
|
if __name__ == '__main__':
|
|
52
97
|
main()
|
gptpr/prdata.py
CHANGED
|
@@ -4,6 +4,7 @@ import os
|
|
|
4
4
|
from openai import OpenAI
|
|
5
5
|
|
|
6
6
|
from gptpr.gitutil import BranchInfo
|
|
7
|
+
from gptpr.config import config
|
|
7
8
|
import gptpr.consolecolor as cc
|
|
8
9
|
|
|
9
10
|
TOKENIZER_RATIO = 4
|
|
@@ -37,6 +38,20 @@ def _get_pr_template():
|
|
|
37
38
|
return pr_template
|
|
38
39
|
|
|
39
40
|
|
|
41
|
+
def _get_open_ai_key():
|
|
42
|
+
api_key = config.get_user_config('OPENAI_API_KEY')
|
|
43
|
+
|
|
44
|
+
if not api_key:
|
|
45
|
+
api_key = os.environ.get('OPENAI_API_KEY')
|
|
46
|
+
|
|
47
|
+
if not api_key:
|
|
48
|
+
print('Please set "openai_api_key" config, just run:',
|
|
49
|
+
cc.yellow('gpt-pr-config set openai_api_key [open ai key]'))
|
|
50
|
+
exit(1)
|
|
51
|
+
|
|
52
|
+
return api_key
|
|
53
|
+
|
|
54
|
+
|
|
40
55
|
@dataclass
|
|
41
56
|
class PrData():
|
|
42
57
|
branch_info: BranchInfo
|
|
@@ -48,7 +63,7 @@ class PrData():
|
|
|
48
63
|
f'{cc.bold("Repository")}: {cc.yellow(self.branch_info.owner)}/{cc.yellow(self.branch_info.repo)}',
|
|
49
64
|
f'{cc.bold("Title")}: {cc.yellow(self.title)}',
|
|
50
65
|
f'{cc.bold("Branch name")}: {cc.yellow(self.branch_info.branch)}',
|
|
51
|
-
f'{cc.bold("Base branch")}: {cc.yellow(
|
|
66
|
+
f'{cc.bold("Base branch")}: {cc.yellow(self.branch_info.base_branch)}',
|
|
52
67
|
f'{cc.bold("PR Description")}:\n{self.body}',
|
|
53
68
|
])
|
|
54
69
|
|
|
@@ -108,17 +123,14 @@ def get_pr_data(branch_info):
|
|
|
108
123
|
else:
|
|
109
124
|
messages.append({'role': 'user', 'content': 'Diff changes:\n' + branch_info.diff})
|
|
110
125
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if not openai_api_key:
|
|
114
|
-
print("Please set OPENAI_API_KEY environment variable.")
|
|
115
|
-
exit(1)
|
|
126
|
+
client = OpenAI(api_key=_get_open_ai_key())
|
|
116
127
|
|
|
117
|
-
|
|
128
|
+
openai_model = config.get_user_config('OPENAI_MODEL')
|
|
129
|
+
print('Using OpenAI model:', cc.yellow(openai_model))
|
|
118
130
|
|
|
119
131
|
chat_completion = client.chat.completions.create(
|
|
120
132
|
messages=messages,
|
|
121
|
-
model=
|
|
133
|
+
model=openai_model,
|
|
122
134
|
functions=functions,
|
|
123
135
|
function_call={'name': 'create_pr'},
|
|
124
136
|
temperature=0,
|
gptpr/test_config.py
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import configparser
|
|
3
|
+
|
|
4
|
+
from pytest import fixture
|
|
5
|
+
|
|
6
|
+
from gptpr.config import Config
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@fixture
|
|
10
|
+
def temp_config(tmpdir):
|
|
11
|
+
temp_dir = tmpdir.mkdir('config_dir')
|
|
12
|
+
config = Config(temp_dir)
|
|
13
|
+
return config, temp_dir
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _check_config(config, temp_dir, config_list):
|
|
17
|
+
# Read the configuration file and verify its contents
|
|
18
|
+
config_to_test = configparser.ConfigParser()
|
|
19
|
+
config_to_test.read(os.path.join(str(temp_dir), config.config_filename))
|
|
20
|
+
|
|
21
|
+
for section, key, value in config_list:
|
|
22
|
+
assert config_to_test[section][key] == value
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_init_config_file(temp_config):
|
|
26
|
+
config, temp_dir = temp_config
|
|
27
|
+
config.load()
|
|
28
|
+
|
|
29
|
+
# Check if the file exists
|
|
30
|
+
assert os.path.isfile(os.path.join(str(temp_dir), config.config_filename))
|
|
31
|
+
|
|
32
|
+
_check_config(config, temp_dir, [
|
|
33
|
+
('DEFAULT', 'OPENAI_MODEL', 'gpt-4o'),
|
|
34
|
+
('DEFAULT', 'OPENAI_API_KEY', ''),
|
|
35
|
+
])
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_new_default_value_should_be_added(temp_config):
|
|
39
|
+
config, temp_dir = temp_config
|
|
40
|
+
config.load() # data was written to the file
|
|
41
|
+
|
|
42
|
+
new_config = Config(temp_dir)
|
|
43
|
+
|
|
44
|
+
# Add a new default value
|
|
45
|
+
new_config.default_config['NEW_DEFAULT'] = 'new_default_value'
|
|
46
|
+
new_config.load() # Should update config file...
|
|
47
|
+
|
|
48
|
+
_check_config(new_config, temp_dir, [
|
|
49
|
+
('DEFAULT', 'NEW_DEFAULT', 'new_default_value'),
|
|
50
|
+
])
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def test_set_user_config(temp_config):
|
|
54
|
+
config, temp_dir = temp_config
|
|
55
|
+
|
|
56
|
+
config.set_user_config('OPENAI_MODEL', 'gpt-3.5')
|
|
57
|
+
config.persist()
|
|
58
|
+
|
|
59
|
+
# Read the configuration file and verify its contents
|
|
60
|
+
config_to_test = configparser.ConfigParser()
|
|
61
|
+
config_to_test.read(os.path.join(str(temp_dir), config.config_filename))
|
|
62
|
+
|
|
63
|
+
_check_config(config, temp_dir, [
|
|
64
|
+
('user', 'OPENAI_MODEL', 'gpt-3.5'),
|
|
65
|
+
('user', 'OPENAI_API_KEY', ''),
|
|
66
|
+
])
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def test_all_values(temp_config):
|
|
70
|
+
config, temp_dir = temp_config
|
|
71
|
+
|
|
72
|
+
all_values = config.all_values()
|
|
73
|
+
|
|
74
|
+
assert all_values == [
|
|
75
|
+
('DEFAULT', 'gh_token', ''),
|
|
76
|
+
('DEFAULT', 'openai_model', 'gpt-4o'),
|
|
77
|
+
('DEFAULT', 'openai_api_key', ''),
|
|
78
|
+
('user', 'gh_token', ''),
|
|
79
|
+
('user', 'openai_model', 'gpt-4o'),
|
|
80
|
+
('user', 'openai_api_key', ''),
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_reset_user_config(temp_config):
|
|
85
|
+
config, temp_dir = temp_config
|
|
86
|
+
|
|
87
|
+
config.set_user_config('OPENAI_MODEL', 'gpt-3.5')
|
|
88
|
+
config.persist()
|
|
89
|
+
|
|
90
|
+
config.reset_user_config('OPENAI_MODEL')
|
|
91
|
+
|
|
92
|
+
# Read the configuration file and verify its contents
|
|
93
|
+
config_to_test = configparser.ConfigParser()
|
|
94
|
+
config_to_test.read(os.path.join(str(temp_dir), config.config_filename))
|
|
95
|
+
|
|
96
|
+
_check_config(config, temp_dir, [
|
|
97
|
+
('user', 'OPENAI_MODEL', 'gpt-4o'),
|
|
98
|
+
('user', 'OPENAI_API_KEY', ''),
|
|
99
|
+
])
|
gptpr/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.
|
|
1
|
+
__version__ = "0.3.0"
|
gpt_pr-0.2.0.dist-info/RECORD
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
gptpr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
gptpr/consolecolor.py,sha256=_JmBMNjIflWMlgP2VkCWu6uQLR9oHBy52uV3TRJJgF4,800
|
|
3
|
-
gptpr/gh.py,sha256=y8JgWYTzYzjOWitkEK9Lshjmuv1gV7Tt4DHBrISxAJM,761
|
|
4
|
-
gptpr/gitutil.py,sha256=uhNwwH3r84p5GK1j_19sZEPMyfftEiGpzuV6QZSW6qE,5667
|
|
5
|
-
gptpr/main.py,sha256=rkalqLcc1Nh5WH51w7ayEMIYNoScrRBNVYl3KLuZFdY,1270
|
|
6
|
-
gptpr/prdata.py,sha256=RErSbUyIb0LxCjlUS4KKHoNi2WN94NRO3Cw0mCxtHiU,5824
|
|
7
|
-
gptpr/test_prdata.py,sha256=rSJ-yqOdw-iYdBWyqnA2SXbdrhT8KgIkRTTf9SY1S1g,474
|
|
8
|
-
gptpr/version.py,sha256=Zn1KFblwuFHiDRdRAiRnDBRkbPttWh44jKa5zG2ov0E,22
|
|
9
|
-
gpt_pr-0.2.0.dist-info/METADATA,sha256=oLLwZT78ZD4ymXo5rABD0L_vI8zbJlidiKOu4OzkaNg,2638
|
|
10
|
-
gpt_pr-0.2.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
11
|
-
gpt_pr-0.2.0.dist-info/entry_points.txt,sha256=aXCkyNdoUHfSJXVhRKHj8m09twDfcDmY7xC66u5N3hE,43
|
|
12
|
-
gpt_pr-0.2.0.dist-info/top_level.txt,sha256=DZcbzlsjh4BD8njGcvhOeCZ83U_oYWgCn0w8qx5--04,6
|
|
13
|
-
gpt_pr-0.2.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|