4
4
https://github.com/libgit2/libgit2sharp/wiki
5
5
"""
6
6
7
- import importlib
8
7
import os .path as op
9
8
from collections import OrderedDict
10
9
11
10
from pyrevit import HOST_APP , PyRevitException
12
- import pyrevit .compat as compat
13
11
from pyrevit .compat import PY3 , safe_strtype
14
12
from pyrevit import framework
15
13
from pyrevit .framework import clr
16
14
from pyrevit .framework import DateTime , DateTimeOffset
17
15
from pyrevit .coreutils .logger import get_logger
18
16
19
- #pylint: disable=W0703,C0302
20
- mlogger = get_logger (__name__ ) #pylint: disable=C0103
17
+ # pylint: disable=W0703,C0302
18
+ mlogger = get_logger (__name__ ) # pylint: disable=C0103
21
19
22
20
23
- GIT_LIB = ' LibGit2Sharp'
21
+ GIT_LIB = " LibGit2Sharp"
24
22
25
23
LIBGIT_DLL = framework .get_dll_file (GIT_LIB )
26
- mlogger .debug (' Loading dll: %s' , LIBGIT_DLL )
24
+ mlogger .debug (" Loading dll: %s" , LIBGIT_DLL )
27
25
28
26
try :
29
27
if PY3 :
30
28
clr .AddReference (LIBGIT_DLL )
31
29
else :
32
30
clr .AddReferenceToFileAndPath (LIBGIT_DLL )
33
31
34
- import LibGit2Sharp as libgit # pylint: disable=import-error
32
+ import LibGit2Sharp as libgit # pylint: disable=import-error
35
33
36
34
except Exception as load_err :
37
- mlogger .error ('Can not load %s module. '
38
- 'This module is necessary for getting pyRevit version '
39
- 'and staying updated. | %s' , GIT_LIB , load_err )
35
+ mlogger .error (
36
+ "Can not load %s module. "
37
+ "This module is necessary for getting pyRevit version "
38
+ "and staying updated. | %s" ,
39
+ GIT_LIB ,
40
+ load_err ,
41
+ )
40
42
41
43
42
44
class PyRevitGitAuthenticationError (PyRevitException ):
43
45
"""Git authentication error."""
46
+
44
47
pass
45
48
46
49
@@ -57,6 +60,7 @@ class RepoInfo(object):
57
60
username (str): credentials - username
58
61
password (str): credentials - password
59
62
"""
63
+
60
64
def __init__ (self , repo ):
61
65
self .directory = repo .Info .WorkingDirectory
62
66
self .name = op .basename (op .normpath (self .directory ))
@@ -67,8 +71,9 @@ def __init__(self, repo):
67
71
self .username = self .password = None
68
72
69
73
def __repr__ (self ):
70
- return '<type \' RepoInfo\' head \' {}\' @ {}>' \
71
- .format (self .last_commit_hash , self .directory )
74
+ return "<type 'RepoInfo' head '{}' @ {}>" .format (
75
+ self .last_commit_hash , self .directory
76
+ )
72
77
73
78
74
79
def _credentials_hndlr (username , password ):
@@ -79,64 +84,81 @@ def _credentials_hndlr(username, password):
79
84
80
85
81
86
def _get_credentials_hndlr (username , password ):
82
- return libgit .Handlers . \
83
- CredentialsHandler ( lambda url , uname , types :
84
- _credentials_hndlr ( username , password ) )
87
+ return libgit .Handlers .CredentialsHandler (
88
+ lambda url , uname , types : _credentials_hndlr ( username , password )
89
+ )
85
90
86
91
87
92
def _make_pull_options (repo_info ):
88
- mlogger .debug (' Making pull options: %s' , repo_info )
93
+ mlogger .debug (" Making pull options: %s" , repo_info )
89
94
pull_ops = libgit .PullOptions ()
90
95
pull_ops .FetchOptions = libgit .FetchOptions ()
91
96
if repo_info .username and repo_info .password :
92
- mlogger .debug ('Making Credentials handler. '
93
- '(Username and password are available but'
94
- 'will not be logged for privacy purposes.)' )
97
+ mlogger .debug (
98
+ "Making Credentials handler. "
99
+ "(Username and password are available but"
100
+ "will not be logged for privacy purposes.)"
101
+ )
95
102
96
- pull_ops .FetchOptions .CredentialsProvider = \
97
- _get_credentials_hndlr (repo_info .username , repo_info .password )
103
+ pull_ops .FetchOptions .CredentialsProvider = _get_credentials_hndlr (
104
+ repo_info .username , repo_info .password
105
+ )
98
106
99
107
return pull_ops
100
108
101
109
102
110
def _make_fetch_options (repo_info ):
103
- mlogger .debug (' Making fetch options: %s' , repo_info )
111
+ mlogger .debug (" Making fetch options: %s" , repo_info )
104
112
fetch_ops = libgit .FetchOptions ()
105
113
if repo_info .username and repo_info .password :
106
- mlogger .debug ('Making Credentials handler. '
107
- '(Username and password are available but'
108
- 'will not be logged for privacy purposes.)' )
114
+ mlogger .debug (
115
+ "Making Credentials handler. "
116
+ "(Username and password are available but"
117
+ "will not be logged for privacy purposes.)"
118
+ )
109
119
110
- fetch_ops .CredentialsProvider = \
111
- _get_credentials_hndlr (repo_info .username , repo_info .password )
120
+ fetch_ops .CredentialsProvider = _get_credentials_hndlr (
121
+ repo_info .username , repo_info .password
122
+ )
112
123
113
124
return fetch_ops
114
125
115
126
116
127
def _make_clone_options (username = None , password = None ):
117
- mlogger .debug (' Making clone options.' )
128
+ mlogger .debug (" Making clone options." )
118
129
clone_ops = libgit .CloneOptions ()
119
- if username and password :
120
- mlogger .debug ('Making Credentials handler. '
121
- '(Username and password are available but'
122
- 'will not be logged for privacy purposes.)' )
123
130
124
- clone_ops .CredentialsProvider = \
125
- _get_credentials_hndlr (username , password )
131
+ if username and password :
132
+ mlogger .debug ("Making Credentials handler." )
133
+ creds_handler = _get_credentials_hndlr (username , password )
134
+
135
+ # Only set the CredentialsProvider if it's a valid property
136
+ if hasattr (clone_ops , "CredentialsProvider" ):
137
+ clone_ops .CredentialsProvider = creds_handler
138
+ elif hasattr (clone_ops , "FetchOptions" ) and hasattr (
139
+ clone_ops .FetchOptions , "CredentialsProvider"
140
+ ):
141
+ clone_ops .FetchOptions .CredentialsProvider = creds_handler
142
+ else :
143
+ mlogger .warning (
144
+ "CloneOptions does not support CredentialsProvider. "
145
+ "Skipping credentials."
146
+ )
126
147
127
148
return clone_ops
128
149
129
150
130
151
def _make_pull_signature ():
131
- mlogger .debug ('Creating pull signature for username: %s' , HOST_APP .username )
132
- return libgit .Signature (HOST_APP .username ,
133
- HOST_APP .username ,
134
- DateTimeOffset (DateTime .Now ))
152
+ mlogger .debug ("Creating pull signature for username: %s" ,
153
+ HOST_APP .username )
154
+ return libgit .Signature (
155
+ HOST_APP .username , HOST_APP .username , DateTimeOffset (DateTime .Now )
156
+ )
135
157
136
158
137
159
def _process_git_error (exception_err ):
138
160
exception_msg = safe_strtype (exception_err )
139
- if ' 401' in exception_msg :
161
+ if " 401" in exception_msg :
140
162
raise PyRevitGitAuthenticationError (exception_msg )
141
163
else :
142
164
raise PyRevitException (exception_msg )
@@ -166,18 +188,19 @@ def git_pull(repo_info):
166
188
"""
167
189
repo = repo_info .repo
168
190
try :
169
- libgit .Commands .Pull (repo ,
170
- _make_pull_signature (),
171
- _make_pull_options ( repo_info ) )
191
+ libgit .Commands .Pull (
192
+ repo , _make_pull_signature (), _make_pull_options ( repo_info )
193
+ )
172
194
173
- mlogger .debug (' Successfully pulled repo: %s' , repo_info .directory )
174
- head_msg = safe_strtype (repo .Head .Tip .Message ).replace (' \n ' , '' )
195
+ mlogger .debug (" Successfully pulled repo: %s" , repo_info .directory )
196
+ head_msg = safe_strtype (repo .Head .Tip .Message ).replace (" \n " , "" )
175
197
176
- mlogger .debug (' New head is: %s > %s' , repo .Head .Tip .Id .Sha , head_msg )
198
+ mlogger .debug (" New head is: %s > %s" , repo .Head .Tip .Id .Sha , head_msg )
177
199
return RepoInfo (repo )
178
200
179
201
except Exception as pull_err :
180
- mlogger .debug ('Failed git pull: %s | %s' , repo_info .directory , pull_err )
202
+ mlogger .debug ("Failed git pull: %s | %s" ,
203
+ repo_info .directory , pull_err )
181
204
_process_git_error (pull_err )
182
205
183
206
@@ -192,20 +215,22 @@ def git_fetch(repo_info):
192
215
"""
193
216
repo = repo_info .repo
194
217
try :
195
- libgit .Commands .Fetch (repo ,
196
- repo .Head .TrackedBranch .RemoteName ,
197
- [],
198
- _make_fetch_options (repo_info ),
199
- 'fetching pyrevit updates' )
200
-
201
- mlogger .debug ('Successfully pulled repo: %s' , repo_info .directory )
202
- head_msg = safe_strtype (repo .Head .Tip .Message ).replace ('\n ' , '' )
203
-
204
- mlogger .debug ('New head is: %s > %s' , repo .Head .Tip .Id .Sha , head_msg )
218
+ libgit .Commands .Fetch (
219
+ repo ,
220
+ repo .Head .TrackedBranch .RemoteName ,
221
+ [],
222
+ _make_fetch_options (repo_info ),
223
+ "fetching pyrevit updates" ,
224
+ )
225
+
226
+ mlogger .debug ("Successfully pulled repo: %s" , repo_info .directory )
227
+ head_msg = safe_strtype (repo .Head .Tip .Message ).replace ("\n " , "" )
228
+
229
+ mlogger .debug ("New head is: %s > %s" , repo .Head .Tip .Id .Sha , head_msg )
205
230
return RepoInfo (repo )
206
231
207
232
except Exception as fetch_err :
208
- mlogger .debug (' Failed git fetch: %s | %s' ,
233
+ mlogger .debug (" Failed git fetch: %s | %s" ,
209
234
repo_info .directory , fetch_err )
210
235
_process_git_error (fetch_err )
211
236
@@ -220,16 +245,18 @@ def git_clone(repo_url, clone_dir, username=None, password=None):
220
245
password (str): credentials - password
221
246
"""
222
247
try :
223
- libgit .Repository .Clone (repo_url ,
224
- clone_dir ,
225
- _make_clone_options (username = username ,
226
- password = password ))
248
+ libgit .Repository .Clone (
249
+ repo_url ,
250
+ clone_dir ,
251
+ _make_clone_options (username = username , password = password ),
252
+ )
227
253
228
- mlogger .debug (' Completed git clone: %s @ %s' , repo_url , clone_dir )
254
+ mlogger .debug (" Completed git clone: %s @ %s" , repo_url , clone_dir )
229
255
230
256
except Exception as clone_err :
231
- mlogger .debug ('Error cloning repo: %s to %s | %s' ,
232
- repo_url , clone_dir , clone_err )
257
+ mlogger .debug (
258
+ "Error cloning repo: %s to %s | %s" , repo_url , clone_dir , clone_err
259
+ )
233
260
_process_git_error (clone_err )
234
261
235
262
@@ -243,28 +270,31 @@ def compare_branch_heads(repo_info):
243
270
repo = repo_info .repo
244
271
repo_branches = repo .Branches
245
272
246
- mlogger .debug (' Repo branches: %s' , [b .FriendlyName for b in repo_branches ])
273
+ mlogger .debug (" Repo branches: %s" , [b .FriendlyName for b in repo_branches ])
247
274
248
275
for branch in repo_branches :
249
276
if branch .FriendlyName == repo_info .branch and not branch .IsRemote :
250
277
try :
251
278
if branch .TrackedBranch :
252
- mlogger .debug ('Comparing heads: %s of %s' ,
253
- branch .CanonicalName ,
254
- branch .TrackedBranch .CanonicalName )
255
-
256
- hist_div = repo .ObjectDatabase . \
257
- CalculateHistoryDivergence (branch .Tip ,
258
- branch .TrackedBranch .Tip )
279
+ mlogger .debug (
280
+ "Comparing heads: %s of %s" ,
281
+ branch .CanonicalName ,
282
+ branch .TrackedBranch .CanonicalName ,
283
+ )
284
+
285
+ hist_div = repo .ObjectDatabase .CalculateHistoryDivergence (
286
+ branch .Tip , branch .TrackedBranch .Tip
287
+ )
259
288
return hist_div
260
289
except Exception as compare_err :
261
- mlogger .error ('Can not compare branch %s in repo: %s | %s' ,
262
- branch ,
263
- repo ,
264
- safe_strtype (compare_err ).replace ('\n ' , '' ))
290
+ mlogger .error (
291
+ "Can not compare branch %s in repo: %s | %s" ,
292
+ branch ,
293
+ repo ,
294
+ safe_strtype (compare_err ).replace ("\n " , "" ),
295
+ )
265
296
else :
266
- mlogger .debug ('Skipping remote branch: %s' , branch .CanonicalName )
267
-
297
+ mlogger .debug ("Skipping remote branch: %s" , branch .CanonicalName )
268
298
269
299
270
300
def get_all_new_commits (repo_info ):
@@ -294,8 +324,7 @@ def get_all_new_commits(repo_info):
294
324
commits = repo .Commits .QueryBy (commit_filter )
295
325
commitsdict = OrderedDict ()
296
326
for commit in commits :
297
- if commit in repo .Head .Commits \
298
- or commit in repo .Head .TrackedBranch .Commits :
327
+ if commit in repo .Head .Commits or commit in repo .Head .TrackedBranch .Commits :
299
328
commitsdict [commit .Id .ToString ()] = commit .MessageShort
300
329
301
330
return commitsdict
0 commit comments