@@ -56,6 +56,22 @@ local Filter = {
56
56
to_reclone = function (p ) return p .status == Status .TO_RECLONE end ,
57
57
}
58
58
59
+ local function file_write (path , flags , data )
60
+ local err_msg = " Failed to %s '" .. path .. " '"
61
+ local file = assert (uv .fs_open (path , flags , 0x1A4 ), err_msg :format (" open" ))
62
+ assert (uv .fs_write (file , data ), err_msg :format (" write" ))
63
+ assert (uv .fs_close (file ), err_msg :format (" close" ))
64
+ end
65
+
66
+ local function file_read (path )
67
+ local err_msg = " Failed to %s '" .. path .. " '"
68
+ local file = assert (uv .fs_open (path , " r" , 0x1A4 ), err_msg :format (" open" ))
69
+ local stat = assert (uv .fs_stat (path ), err_msg :format (" get stats for" ))
70
+ local data = assert (uv .fs_read (file , stat .size , 0 ), err_msg :format (" read" ))
71
+ assert (uv .fs_close (file ), err_msg :format (" close" ))
72
+ return data
73
+ end
74
+
59
75
--- @return Package
60
76
local function find_unlisted ()
61
77
local unlisted = {}
78
94
--- @return string
79
95
local function get_git_hash (dir )
80
96
local first_line = function (path )
81
- local file = uv .fs_open (path , " r" , 438 )
82
- if file then
83
- local stat = assert (uv .fs_fstat (file ))
84
- local data = assert (uv .fs_read (file , stat .size , 0 ))
85
- uv .fs_close (file )
86
- return vim .split (data , " \n " )[1 ]
87
- end
97
+ local data = file_read (path )
98
+ return vim .split (data , " \n " )[1 ]
88
99
end
89
100
local head_ref = first_line (vim .fs .joinpath (dir , " .git" , " HEAD" ))
90
101
return head_ref and first_line (vim .fs .joinpath (dir , " .git" , head_ref :sub (6 , - 1 )))
@@ -119,15 +130,17 @@ end
119
130
--- @param prev_hash string
120
131
--- @param cur_hash string
121
132
local function log_update_changes (pkg , prev_hash , cur_hash )
122
- local output = " \n\n " .. pkg .name .. " updated:\n "
123
133
vim .system (
124
134
{ " git" , " log" , " --pretty=format:* %s" , (" %s..%s" ):format (prev_hash , cur_hash ) },
125
135
{ cwd = pkg .dir , text = true },
126
136
function (obj )
127
- assert (obj .code == 0 , " Exited(" .. obj .code .. " )" )
128
- local log = assert (uv .fs_open (Config .log , " a+" , 0x1A4 ))
129
- uv .fs_write (log , output .. obj .stdout )
130
- uv .fs_close (log )
137
+ if obj .code ~= 0 then
138
+ local msg = " failed to execute git log into %q (code %d):\n %s"
139
+ file_write (Config .log , " a+" , msg :format (pkg .dir , obj .code , obj .stderr ))
140
+ return
141
+ end
142
+ local output = " \n\n %s updated:\n %s"
143
+ file_write (Config .log , " a+" , output :format (pkg .name , obj .stdout ))
131
144
end
132
145
)
133
146
end
@@ -171,25 +184,18 @@ local function lock_write()
171
184
for p , _ in pairs (pkgs ) do
172
185
pkgs [p ].build = nil
173
186
end
174
- local file = uv .fs_open (Config .lock , " w" , 438 )
175
- if file then
176
- local ok , result = pcall (vim .json .encode , pkgs )
177
- if not ok then
178
- error (result )
179
- end
180
- assert (uv .fs_write (file , result ))
181
- assert (uv .fs_close (file ))
187
+ local ok , result = pcall (vim .json .encode , pkgs )
188
+ if not ok then
189
+ error (result )
182
190
end
191
+ -- Ignore if fail
192
+ pcall (file_write , Config .lock , " w" , result )
183
193
Lock = Packages
184
194
end
185
195
186
196
local function lock_load ()
187
- -- don't really know why 438 see ':h uv_fs_t'
188
- local file = uv .fs_open (Config .lock , " r" , 438 )
189
- if file then
190
- local stat = assert (uv .fs_fstat (file ))
191
- local data = assert (uv .fs_read (file , stat .size , 0 ))
192
- assert (uv .fs_close (file ))
197
+ local exists , data = pcall (file_read , Config .lock )
198
+ if exists then
193
199
local ok , result = pcall (vim .json .decode , data )
194
200
if ok then
195
201
Lock = not vim .tbl_isempty (result ) and result or Packages
@@ -253,7 +259,10 @@ local function pull(pkg, counter, build_queue)
253
259
return
254
260
end
255
261
local cur_hash = get_git_hash (pkg .dir )
256
- if cur_hash == prev_hash then
262
+ -- It can happen that the user has deleted manually a directory.
263
+ -- Thus the pkg.hash is left blank and we need to update it.
264
+ if cur_hash == prev_hash or prev_hash == " " then
265
+ pkg .hash = cur_hash
257
266
counter (pkg .name , Messages .update , " nop" )
258
267
return
259
268
end
@@ -351,21 +360,26 @@ local function register(pkg)
351
360
--- @diagnostic disable-next-line : missing-fields
352
361
pkg = { pkg }
353
362
end
363
+
354
364
local url = pkg .url
355
365
or (pkg [1 ]:match (" ^https?://" ) and pkg [1 ]) -- [1] is a URL
356
366
or string.format (Config .url_format , pkg [1 ]) -- [1] is a repository name
367
+
357
368
local name = pkg .as or url :gsub (" %.git$" , " " ):match (" /([%w-_.]+)$" ) -- Infer name from `url`
358
369
if not name then
359
370
return vim .notify (" Paq: Failed to parse " .. vim .inspect (pkg ), vim .log .levels .ERROR )
360
371
end
361
372
local opt = pkg .opt or Config .opt and pkg .opt == nil
362
373
local dir = vim .fs .joinpath (Config .path , (opt and " opt" or " start" ), name )
374
+ local ok , hash = pcall (get_git_hash , dir )
375
+ hash = ok and hash or " "
376
+
363
377
Packages [name ] = {
364
378
name = name ,
365
379
branch = pkg .branch ,
366
380
dir = dir ,
367
381
status = uv .fs_stat (dir ) and Status .INSTALLED or Status .TO_INSTALL ,
368
- hash = get_git_hash ( dir ) ,
382
+ hash = hash ,
369
383
pin = pkg .pin ,
370
384
build = pkg .build ,
371
385
url = url ,
0 commit comments