skilleter-modules 0.0.7__py3-none-any.whl → 0.0.9__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.
- skilleter_modules/git.py +28 -101
- skilleter_modules/popup.py +1 -1
- {skilleter_modules-0.0.7.dist-info → skilleter_modules-0.0.9.dist-info}/METADATA +1 -5
- {skilleter_modules-0.0.7.dist-info → skilleter_modules-0.0.9.dist-info}/RECORD +7 -8
- {skilleter_modules-0.0.7.dist-info → skilleter_modules-0.0.9.dist-info}/WHEEL +1 -1
- skilleter_modules/gitlab.py +0 -193
- {skilleter_modules-0.0.7.dist-info → skilleter_modules-0.0.9.dist-info}/licenses/LICENSE +0 -0
- {skilleter_modules-0.0.7.dist-info → skilleter_modules-0.0.9.dist-info}/top_level.txt +0 -0
skilleter_modules/git.py
CHANGED
|
@@ -27,11 +27,11 @@ import re
|
|
|
27
27
|
import logging
|
|
28
28
|
import fnmatch
|
|
29
29
|
import subprocess
|
|
30
|
+
from functools import cache
|
|
30
31
|
|
|
31
32
|
import pygit2
|
|
32
33
|
|
|
33
34
|
from . import run
|
|
34
|
-
from . import gitlab
|
|
35
35
|
|
|
36
36
|
################################################################################
|
|
37
37
|
# Configuration files to access
|
|
@@ -873,6 +873,7 @@ def reset(sha1, path=None):
|
|
|
873
873
|
|
|
874
874
|
################################################################################
|
|
875
875
|
|
|
876
|
+
@cache
|
|
876
877
|
def config_get(section, key, source=None, defaultvalue=None, path=None):
|
|
877
878
|
""" Return the specified configuration entry
|
|
878
879
|
Returns a default value if no matching configuration entry exists """
|
|
@@ -900,6 +901,8 @@ def config_get(section, key, source=None, defaultvalue=None, path=None):
|
|
|
900
901
|
def config_set(section, key, value, source=None, path=None):
|
|
901
902
|
""" Set a configuration entry """
|
|
902
903
|
|
|
904
|
+
config_get.cache_clear()
|
|
905
|
+
|
|
903
906
|
cmd = ['config']
|
|
904
907
|
|
|
905
908
|
if source == GLOBAL:
|
|
@@ -1212,37 +1215,38 @@ def isbranch(branchname, path=None):
|
|
|
1212
1215
|
|
|
1213
1216
|
################################################################################
|
|
1214
1217
|
|
|
1215
|
-
def
|
|
1216
|
-
""" Return
|
|
1217
|
-
|
|
1218
|
-
|
|
1218
|
+
def is_default_branch(path, branchname=None):
|
|
1219
|
+
""" Return True if the specified branch is a default branch """
|
|
1220
|
+
|
|
1221
|
+
# Use the current branch if not specified
|
|
1219
1222
|
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
for name in remote_list:
|
|
1223
|
-
if 'gitlab' in remote_list[name]:
|
|
1224
|
-
url = remote_list[name].split('@')[1].split(':')[0]
|
|
1225
|
-
repo = remote_list[name].split(':')[1]
|
|
1223
|
+
if not branchname:
|
|
1224
|
+
branchname = branch(path=path)
|
|
1226
1225
|
|
|
1227
|
-
|
|
1228
|
-
url = f'https://{url}'
|
|
1226
|
+
# Get the list of default branch wildcards
|
|
1229
1227
|
|
|
1230
|
-
|
|
1231
|
-
|
|
1228
|
+
default_branches = config_get('skilleter-thingy', 'defaultBranches', defaultvalue=DEFAULT_DEFAULT_BRANCHES, path=path).split(',')
|
|
1229
|
+
|
|
1230
|
+
# If the branch matches any of the wildcards, return True
|
|
1232
1231
|
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1232
|
+
for defbranch in default_branches:
|
|
1233
|
+
if fnmatch.fnmatch(branchname, defbranch):
|
|
1234
|
+
return True
|
|
1235
|
+
|
|
1236
|
+
# No match, so not a default branch
|
|
1237
|
+
|
|
1238
|
+
return False
|
|
1239
|
+
|
|
1240
|
+
################################################################################
|
|
1236
1241
|
|
|
1237
|
-
|
|
1238
|
-
|
|
1242
|
+
def default_branch(path=None):
|
|
1243
|
+
""" Return the name of the default branch """
|
|
1239
1244
|
|
|
1240
1245
|
git_branches = branches(path=path)
|
|
1241
|
-
default_branches = config_get('skilleter-thingy', 'defaultBranches', defaultvalue=DEFAULT_DEFAULT_BRANCHES, path=path).split(',')
|
|
1242
1246
|
|
|
1243
|
-
for
|
|
1244
|
-
if
|
|
1245
|
-
return
|
|
1247
|
+
for branchname in git_branches:
|
|
1248
|
+
if is_default_branch(path, branchname):
|
|
1249
|
+
return branchname
|
|
1246
1250
|
|
|
1247
1251
|
raise GitError('Unable to determine default branch in the repo')
|
|
1248
1252
|
|
|
@@ -1423,80 +1427,3 @@ def clean(recurse=False, force=False, dry_run=False, quiet=False,
|
|
|
1423
1427
|
cmd.append('-X')
|
|
1424
1428
|
|
|
1425
1429
|
return git(cmd, path=path)
|
|
1426
|
-
|
|
1427
|
-
################################################################################
|
|
1428
|
-
|
|
1429
|
-
def run_tests():
|
|
1430
|
-
"""Test suite for the module"""
|
|
1431
|
-
|
|
1432
|
-
print('Creating local git repo')
|
|
1433
|
-
|
|
1434
|
-
init('test-repo')
|
|
1435
|
-
os.chdir('test-repo')
|
|
1436
|
-
|
|
1437
|
-
try:
|
|
1438
|
-
print('Initial status:')
|
|
1439
|
-
print(' User name: %s' % config_get('user', 'name'))
|
|
1440
|
-
print(' Project: %s' % project())
|
|
1441
|
-
print(' Remotes: %s' % remotes())
|
|
1442
|
-
print(' Current branch: %s' % branch())
|
|
1443
|
-
print(' Current working tree: %s' % working_tree())
|
|
1444
|
-
print(' Rebasing? %s' % rebasing())
|
|
1445
|
-
print(' Status: %s' % status())
|
|
1446
|
-
print()
|
|
1447
|
-
|
|
1448
|
-
print('Adding a removing a configuration value')
|
|
1449
|
-
|
|
1450
|
-
config_set('user', 'size', 'medium')
|
|
1451
|
-
|
|
1452
|
-
print(' User size config: %s' % config_get('user', 'size'))
|
|
1453
|
-
|
|
1454
|
-
config_rm('user', 'size')
|
|
1455
|
-
|
|
1456
|
-
value = config_get('user', 'size')
|
|
1457
|
-
if value is None:
|
|
1458
|
-
print(' Successfully failed to read the newly-deleted config data')
|
|
1459
|
-
else:
|
|
1460
|
-
raise GitError('Unexpected lack of error reading configuration data', 1)
|
|
1461
|
-
|
|
1462
|
-
config_set('user', 'email', 'user@localhost')
|
|
1463
|
-
config_set('user', 'name', 'User Name')
|
|
1464
|
-
|
|
1465
|
-
print('')
|
|
1466
|
-
|
|
1467
|
-
with open('newfile.txt', 'w', encoding='utf8') as newfile:
|
|
1468
|
-
newfile.write('THIS IS A TEST')
|
|
1469
|
-
|
|
1470
|
-
print('Adding and committing "newfile.txt"')
|
|
1471
|
-
|
|
1472
|
-
add(['newfile.txt'])
|
|
1473
|
-
|
|
1474
|
-
commit(['newfile.txt'], 'Test the add and commit functionality')
|
|
1475
|
-
|
|
1476
|
-
print('Removing and committing "newfile.txt"')
|
|
1477
|
-
|
|
1478
|
-
rm(['newfile.txt'])
|
|
1479
|
-
|
|
1480
|
-
commit(None, 'Removed "newfile.txt"')
|
|
1481
|
-
|
|
1482
|
-
print('Removing the last commit')
|
|
1483
|
-
|
|
1484
|
-
reset('HEAD~1')
|
|
1485
|
-
|
|
1486
|
-
print('Commit info for HEAD %s' % commit_info('HEAD'))
|
|
1487
|
-
|
|
1488
|
-
except GitError as exc:
|
|
1489
|
-
sys.stderr.write(f'ERROR: {exc.msg}')
|
|
1490
|
-
sys.exit(1)
|
|
1491
|
-
|
|
1492
|
-
finally:
|
|
1493
|
-
# If anything fails, then clean up afterwards
|
|
1494
|
-
|
|
1495
|
-
os.chdir('..')
|
|
1496
|
-
shutil.rmtree('test-repo')
|
|
1497
|
-
|
|
1498
|
-
################################################################################
|
|
1499
|
-
# Entry point
|
|
1500
|
-
|
|
1501
|
-
if __name__ == '__main__':
|
|
1502
|
-
run_tests()
|
skilleter_modules/popup.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: skilleter_modules
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.9
|
|
4
4
|
Summary: Modules used by my various Python projects (and hopefully useful to other people)
|
|
5
5
|
Author-email: John Skilleter <john@skilleter.org.uk>
|
|
6
6
|
Project-URL: Home, https://skilleter.org.uk
|
|
@@ -38,10 +38,6 @@ Miscellaneous file-related functions - backup creation, file-type detection, etc
|
|
|
38
38
|
|
|
39
39
|
A git library
|
|
40
40
|
|
|
41
|
-
## gitlab.py
|
|
42
|
-
|
|
43
|
-
GitLab access module - due to be deprecated as I no longer support GitLab
|
|
44
|
-
|
|
45
41
|
## path.py
|
|
46
42
|
|
|
47
43
|
Filesystem path-related functions
|
|
@@ -6,15 +6,14 @@ skilleter_modules/dc_util.py,sha256=Df73imXhHx3HzcPHiRcHAoea0e3HURdLcrolUsMhOFs,
|
|
|
6
6
|
skilleter_modules/dircolors.py,sha256=p_rCka-Fnjyu38H8qB3RSZogOkmkbHWYrLbtSWIHcfs,12449
|
|
7
7
|
skilleter_modules/docker.py,sha256=VKcV1aR7X7Yq4ml7zIamwAD05w73Z_2D8yW9MxcNXaE,2923
|
|
8
8
|
skilleter_modules/files.py,sha256=HLrNcUdnpWO-1GEZiDochpVdDKto4G1ukmk4Mszdy7o,4752
|
|
9
|
-
skilleter_modules/git.py,sha256=
|
|
10
|
-
skilleter_modules/gitlab.py,sha256=uXAF918xnPk6qQyiwPQDbMZfqtJzhiRqDS7yEtJEIAg,6079
|
|
9
|
+
skilleter_modules/git.py,sha256=SmK9vVu6ahxQ0mst0fx3S8FPQGOdlUI4QPSLa47nXfs,40929
|
|
11
10
|
skilleter_modules/path.py,sha256=sk_v9wlRTqZybyl6muAM5yL93ni2LTM0pPj1tyqcaHs,4886
|
|
12
|
-
skilleter_modules/popup.py,sha256=
|
|
11
|
+
skilleter_modules/popup.py,sha256=xq3C64ju_1aDr4koyhC-Y9SJv57kUawrh8L486Jo564,2578
|
|
13
12
|
skilleter_modules/run.py,sha256=mXzf1kJxNIKSYVT6khJ8s5RiA2cVqkoOFk0P6QPIBY0,10631
|
|
14
13
|
skilleter_modules/tidy.py,sha256=AN_3CRHd8HyWeXlNtd0gZyaA0UJfO4k3IvC5fszeUtk,5972
|
|
15
14
|
skilleter_modules/venv_template.py,sha256=ZfUvi8qFNGrk7J030Zy57xjwMtfIArJyqa-MqafyjVk,1016
|
|
16
|
-
skilleter_modules-0.0.
|
|
17
|
-
skilleter_modules-0.0.
|
|
18
|
-
skilleter_modules-0.0.
|
|
19
|
-
skilleter_modules-0.0.
|
|
20
|
-
skilleter_modules-0.0.
|
|
15
|
+
skilleter_modules-0.0.9.dist-info/licenses/LICENSE,sha256=ljOS4DjXvqEo5VzGfdaRwgRZPbNScGBmfwyC8PChvmQ,32422
|
|
16
|
+
skilleter_modules-0.0.9.dist-info/METADATA,sha256=IWwWK22sKoREQWxXMdjEh2wPf0nq3lwgwUltkGTBCnA,1735
|
|
17
|
+
skilleter_modules-0.0.9.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
18
|
+
skilleter_modules-0.0.9.dist-info/top_level.txt,sha256=DMa0AkGOjoDHiHDG6Nw1jtdUylaMm5WkF6uODT9yxJc,18
|
|
19
|
+
skilleter_modules-0.0.9.dist-info/RECORD,,
|
skilleter_modules/gitlab.py
DELETED
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
#! /usr/bin/env python3
|
|
2
|
-
|
|
3
|
-
################################################################################
|
|
4
|
-
""" GitLab module - implemented using the REST API as some features are not
|
|
5
|
-
available (or don't work) in the official Python module
|
|
6
|
-
|
|
7
|
-
Copyright (C) 2017-20 John Skilleter
|
|
8
|
-
|
|
9
|
-
Licence: GPL v3 or later
|
|
10
|
-
|
|
11
|
-
Note: There are two types of function for returning data from GitLab;
|
|
12
|
-
the paged functions and the non-paged ones - the paged ones return a page
|
|
13
|
-
(normally 20 items) of data and need to be called repeated until no data is
|
|
14
|
-
left whereas the non-paged ones query all the data and concatenate it
|
|
15
|
-
together.
|
|
16
|
-
|
|
17
|
-
The paged functions expect a full request string with the URL, as returned
|
|
18
|
-
by the request_string() member. The non-paged ones call request_string()
|
|
19
|
-
to add the URL & API prefix.
|
|
20
|
-
"""
|
|
21
|
-
################################################################################
|
|
22
|
-
|
|
23
|
-
import sys
|
|
24
|
-
import os
|
|
25
|
-
|
|
26
|
-
try:
|
|
27
|
-
import requests
|
|
28
|
-
except ModuleNotFoundError:
|
|
29
|
-
sys.stderr.write('This code requires the Python "requests" module which should be installed via your package manager\n')
|
|
30
|
-
sys.exit(1)
|
|
31
|
-
|
|
32
|
-
################################################################################
|
|
33
|
-
|
|
34
|
-
class GitLabError(Exception):
|
|
35
|
-
""" Gitlab exceptions """
|
|
36
|
-
|
|
37
|
-
def __init__(self, response):
|
|
38
|
-
""" Save the error code and text """
|
|
39
|
-
|
|
40
|
-
self.status = response.status_code
|
|
41
|
-
self.message = response.reason
|
|
42
|
-
|
|
43
|
-
def __str__(self):
|
|
44
|
-
""" Return a string version of the exception """
|
|
45
|
-
|
|
46
|
-
return '%s: %s' % (self.status, self.message)
|
|
47
|
-
|
|
48
|
-
################################################################################
|
|
49
|
-
|
|
50
|
-
class GitLab:
|
|
51
|
-
""" Class for GitLab access """
|
|
52
|
-
|
|
53
|
-
def __init__(self, gitlab, token=None):
|
|
54
|
-
""" Initialisation """
|
|
55
|
-
|
|
56
|
-
# Save the GitLab URL
|
|
57
|
-
|
|
58
|
-
self.gitlab = gitlab
|
|
59
|
-
|
|
60
|
-
# If we have a private token use it, otherwise try and get it from
|
|
61
|
-
# the environmnet
|
|
62
|
-
|
|
63
|
-
self.token = token if token else os.getenv('GITLAB_TOKEN', None)
|
|
64
|
-
|
|
65
|
-
# Create the default header for requests
|
|
66
|
-
|
|
67
|
-
self.header = {'Private-Token': self.token}
|
|
68
|
-
|
|
69
|
-
################################################################################
|
|
70
|
-
|
|
71
|
-
@staticmethod
|
|
72
|
-
def encode_project(name):
|
|
73
|
-
""" Encode a project name in the form request by GitLab requests """
|
|
74
|
-
|
|
75
|
-
return name.replace('/', '%2F')
|
|
76
|
-
|
|
77
|
-
################################################################################
|
|
78
|
-
|
|
79
|
-
def request_string(self, request):
|
|
80
|
-
""" Add the URL/API header onto a request string """
|
|
81
|
-
|
|
82
|
-
return '%s/api/v4/%s' % (self.gitlab, request)
|
|
83
|
-
|
|
84
|
-
################################################################################
|
|
85
|
-
|
|
86
|
-
def request(self, request, parameters=None):
|
|
87
|
-
""" Send a request to GitLab - handles pagination and returns all the
|
|
88
|
-
results concatenated together """
|
|
89
|
-
|
|
90
|
-
if parameters:
|
|
91
|
-
request = '%s?%s' % (request, '&'.join(parameters))
|
|
92
|
-
|
|
93
|
-
gl_request = self.request_string(request)
|
|
94
|
-
|
|
95
|
-
# Keep requesting data until there's no 'next' link in the response
|
|
96
|
-
|
|
97
|
-
while True:
|
|
98
|
-
response = requests.get(gl_request, headers=self.header)
|
|
99
|
-
|
|
100
|
-
if not response:
|
|
101
|
-
raise GitLabError(response)
|
|
102
|
-
|
|
103
|
-
yield response.json()
|
|
104
|
-
|
|
105
|
-
if 'next' not in response.links:
|
|
106
|
-
break
|
|
107
|
-
|
|
108
|
-
gl_request = response.links['next']['url']
|
|
109
|
-
|
|
110
|
-
################################################################################
|
|
111
|
-
|
|
112
|
-
def paged_request(self, request):
|
|
113
|
-
""" Send a request to GitLab - returns all the results concatenated together
|
|
114
|
-
and returns a page of results along with the request for the next page of
|
|
115
|
-
results (if any).
|
|
116
|
-
|
|
117
|
-
Note that the request parameter is the full request string as returned by
|
|
118
|
-
request_string(). """
|
|
119
|
-
|
|
120
|
-
response = requests.get(request, headers=self.header)
|
|
121
|
-
|
|
122
|
-
result = response.json()
|
|
123
|
-
|
|
124
|
-
if not response:
|
|
125
|
-
raise GitLabError(response)
|
|
126
|
-
|
|
127
|
-
request = response.links['next']['url'] if 'next' in response.links else None
|
|
128
|
-
|
|
129
|
-
return result, request
|
|
130
|
-
|
|
131
|
-
################################################################################
|
|
132
|
-
|
|
133
|
-
def projects(self):
|
|
134
|
-
""" Return a list of projects """
|
|
135
|
-
|
|
136
|
-
return self.request('projects')
|
|
137
|
-
|
|
138
|
-
################################################################################
|
|
139
|
-
|
|
140
|
-
def branches(self, repo):
|
|
141
|
-
""" Return the list of branches in a repo """
|
|
142
|
-
|
|
143
|
-
for batch in self.request('projects/%s/repository/branches' % self.encode_project(repo)):
|
|
144
|
-
for branch in batch:
|
|
145
|
-
yield branch
|
|
146
|
-
|
|
147
|
-
################################################################################
|
|
148
|
-
|
|
149
|
-
def merge_requests(self, **kwargs):
|
|
150
|
-
""" Return a list of merge requests filtered according to the parameters """
|
|
151
|
-
|
|
152
|
-
request = 'merge_requests'
|
|
153
|
-
|
|
154
|
-
parameters = []
|
|
155
|
-
|
|
156
|
-
for data in kwargs:
|
|
157
|
-
parameters.append('%s=%s' % (data, kwargs[data]))
|
|
158
|
-
|
|
159
|
-
for result in self.request(request, parameters):
|
|
160
|
-
for r in result:
|
|
161
|
-
yield r
|
|
162
|
-
|
|
163
|
-
################################################################################
|
|
164
|
-
|
|
165
|
-
def default_branch(self, repo):
|
|
166
|
-
""" Query gitlab to retreive the default branch for the repo """
|
|
167
|
-
|
|
168
|
-
# Look for the default branch
|
|
169
|
-
|
|
170
|
-
for branch in self.branches(repo):
|
|
171
|
-
if branch['default']:
|
|
172
|
-
return branch['name']
|
|
173
|
-
|
|
174
|
-
return None
|
|
175
|
-
|
|
176
|
-
################################################################################
|
|
177
|
-
|
|
178
|
-
def isbranch(self, repo, branchname):
|
|
179
|
-
""" Return True if the branch exists in the repo """
|
|
180
|
-
|
|
181
|
-
request = self.request_string('projects/%s/repository/branches' % self.encode_project(repo))
|
|
182
|
-
|
|
183
|
-
while True:
|
|
184
|
-
branches, request = self.paged_request(request)
|
|
185
|
-
|
|
186
|
-
for branch in branches:
|
|
187
|
-
if branch['name'] == branchname:
|
|
188
|
-
return True
|
|
189
|
-
|
|
190
|
-
if not request:
|
|
191
|
-
break
|
|
192
|
-
|
|
193
|
-
return False
|
|
File without changes
|
|
File without changes
|