1
1
module GitTools
2
2
3
+ using .. Pkg3
3
4
import LibGit2
4
5
using Printf
5
6
16
17
function showprogress (io:: IO , p:: MiniProgressBar )
17
18
perc = p. current / p. max * 100
18
19
prev_perc = p. prev / p. max * 100
20
+ # Bail early if we are not updating the progress bar,
21
+ # Saves printing to the terminal
19
22
if p. has_shown && ! (perc - prev_perc > 0.1 )
20
23
return
21
24
end
@@ -32,43 +35,45 @@ function showprogress(io::IO, p::MiniProgressBar)
32
35
print (io, " \r " )
33
36
end
34
37
35
- function transfer_progress (progress:: Ptr{LibGit2.GitTransferProgress} , p:: Any )
38
+ Base. @kwdef struct GitTransferProgress
39
+ total_objects:: Cuint
40
+ indexed_objects:: Cuint
41
+ received_objects:: Cuint
42
+ local_objects:: Cuint
43
+ total_deltas:: Cuint
44
+ indexed_deltas:: Cuint
45
+ received_bytes:: Csize_t
46
+ end
47
+
48
+ function transfer_progress (progress:: Ptr{GitTransferProgress} , p:: Any )
36
49
progress = unsafe_load (progress)
50
+ bar = unsafe_pointer_to_objref (p. transfer_progress)
51
+ @assert typeof (bar) == MiniProgressBar
37
52
if progress. total_deltas != 0
38
- p . header = " Resolving Deltas:"
39
- p . max = progress. total_deltas
40
- p . current = progress. indexed_deltas
53
+ bar . header = " Resolving Deltas:"
54
+ bar . max = progress. total_deltas
55
+ bar . current = progress. indexed_deltas
41
56
else
42
- p . max = progress. total_objects
43
- p . current = progress. received_objects
57
+ bar . max = progress. total_objects
58
+ bar . current = progress. received_objects
44
59
end
45
- showprogress (stdout , p )
60
+ showprogress (stdout , bar )
46
61
return Cint (0 )
47
62
end
48
63
49
64
function clone (url, source_path; isbare:: Bool = false , header = nothing , branch = nothing , credentials = nothing )
50
- isdir (source_path) && error (" $source_path already exists" )
51
- printstyled (stdout , " Cloning " ; color = :green , bold= true )
52
- if header == nothing
53
- println (stdout , " from git repo: " , url, " ." )
54
- else
55
- println (stdout , header)
56
- end
65
+ Pkg3. Types. printpkgstyle (stdout , :Cloning , header == nothing ? string (" git-repo `" , url, " `" ) : header)
57
66
transfer_payload = MiniProgressBar (header = " Fetching:" , color = Base. info_color ())
58
67
cred_payload = LibGit2. CredentialPayload (credentials)
59
- print (stdout , " \e [?25l" )
68
+ print (stdout , " \e [?25l" ) # disable cursor
60
69
try
61
- GC. @preserve p branch begin
70
+ GC. @preserve transfer_payload branch begin
62
71
callbacks = LibGit2. RemoteCallbacks (
63
- credentials= (LibGit2. credential_cb (), pointer_from_objref (cred_payload)),
64
- transfer_progress= (cfunction (transfer_progress, Cint, Tuple{Ptr{LibGit2 . GitTransferProgress}, Any}), pointer_from_objref (transfer_payload)),
72
+ credentials= (LibGit2. credentials_cb (), pointer_from_objref (cred_payload)),
73
+ transfer_progress= (cfunction (transfer_progress, Cint, Tuple{Ptr{GitTransferProgress}, Any}), pointer_from_objref (transfer_payload)),
65
74
)
66
75
fetch_opts = LibGit2. FetchOptions (callbacks = callbacks)
67
- if branch == nothing
68
- clone_opts = LibGit2. CloneOptions (fetch_opts= fetch_opts, bare= isbare)
69
- else
70
- clone_opts = LibGit2. CloneOptions (fetch_opts= fetch_opts, bare= isbare, checkout_branch= Cstring (pointer (branch)))
71
- end
76
+ clone_opts = LibGit2. CloneOptions (fetch_opts= fetch_opts, bare= isbare, checkout_branch= branch == nothing ? C_NULL : Cstring (pointer (branch)))
72
77
return LibGit2. clone (url, source_path, clone_opts)
73
78
end
74
79
catch e
@@ -79,10 +84,42 @@ function clone(url, source_path; isbare::Bool=false, header = nothing, branch =
79
84
rm (source_path; force= true , recursive= true )
80
85
rethrow (e)
81
86
finally
82
- print (stdout , " \e [?25h" )
83
- println (stdout )
87
+ print (stdout , " \0 33[2K" ) # clear line
88
+ print (stdout , " \e [?25h" ) # put back cursor
89
+ end
90
+ LibGit2. approve (cred_payload)
91
+ end
92
+
93
+ function fetch (repo:: LibGit2.GitRepo , remoteurl= nothing ; header = nothing , refspecs= String[], credentials= nothing )
94
+ remote = if remoteurl == nothing
95
+ LibGit2. get (LibGit2. GitRemote, repo, " origin" )
96
+ else
97
+ LibGit2. GitRemoteAnon (repo, remoteurl)
98
+ end
99
+ Pkg3. Types. printpkgstyle (stdout , :Updating , header == nothing ? string (" git-repo `" , LibGit2. url (remote), " `" ) : header)
100
+ transfer_payload = MiniProgressBar (header = " Fetching:" , color = Base. info_color ())
101
+ cred_payload = LibGit2. CredentialPayload (credentials)
102
+ print (stdout , " \e [?25l" ) # disable cursor
103
+ try
104
+ GC. @preserve transfer_payload begin
105
+ callbacks = LibGit2. RemoteCallbacks (
106
+ credentials= (LibGit2. credentials_cb (), pointer_from_objref (cred_payload)),
107
+ transfer_progress= (cfunction (transfer_progress, Cint, Tuple{Ptr{GitTransferProgress}, Any}), pointer_from_objref (transfer_payload)),
108
+ )
109
+ fetch_opts = LibGit2. FetchOptions (callbacks = callbacks)
110
+ return LibGit2. fetch (remote, refspecs; options= fetch_opts)
111
+ end
112
+ catch e
113
+ if isa (e, LibGit2. GitError) && e. code == LibGit2. Error. EAUTH
114
+ LibGit2. reject (cred_payload)
115
+ end
116
+ rethrow (e)
117
+ finally
118
+ close (remote)
119
+ print (stdout , " \0 33[2K" ) # clear line
120
+ print (stdout , " \e [?25h" ) # put back cursor
84
121
end
85
122
LibGit2. approve (cred_payload)
86
123
end
87
124
88
- end # module
125
+ end # module
0 commit comments