-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstaller.woo
More file actions
495 lines (424 loc) · 17.8 KB
/
Copy pathinstaller.woo
File metadata and controls
495 lines (424 loc) · 17.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
---@author liyaxi
---@language woo
--- 当时写这个版本管理,这的 很那个啥。。。 不想写。。。。
local dir = _DIR
local work_dir = ''
local os = _os()
local install_dir
local class_installer = {
_ver = '',
_curr_where = nil,
_conf = nil,
_yml = nil,
_trs = nil,
_prefix_gitee = 'gitee.com/',
_prefix_github = 'github.com/',
_api_host = {
gitee = 'https://gitee.com/api/v5/repos/%s/tags',
github = 'https://api.github.com/repos/%s/tags'
},
_download_zip_addr = {
--- download from gitee.com
gitee = 'https://gitee.com/%s/repository/archive/%s.zip',
--- download from github.com
github = 'https://github.com/%s/archive/refs/%s.zip'
},
--- 是否已经创建.bin目录
_is_bin_created = false
}
--- 初始化
function class_installer:new (work_dir_)
print('install new...', work_dir_)
work_dir = work_dir_
local pkg_dir = work_dir_ .. '/package.woo'
print('pkg dir:', pkg_dir)
if not _file_exist(pkg_dir) then
_out('package.woo lose,this not a correct package')
return false
end
print('start parse:', pkg_dir)
local pStr = _cat(pkg_dir, true)
if not pStr then
print('parse fail,check syntax in file:', pkg_dir, err)
return
end
self.yml = loadstring(pStr)()
self._conf = require('oshine/om@1.?:conf/conf')
self._trs = require('oshine/om@1.?:conf/trs')[self._conf.language]
print("package parse done:==", _json_encode(self.yml))
assert(_is_valid(self.yml.package_name), 'no [package_name] in package.woo,it is not a correct package.')
print('current os:', os)
print('package support platform :', self.yml.platform or 'mac windows linux')
-- check platform
if not self.yml.platform or self.yml.platform == 'all' then
return self
end
for _, v in pairs(_str_split(self.yml.platform, " ")) do
if _trim(v) == os then
return self
end
end
assert(false, 'not support your os:' .. os)
end
--- 获取package.woo配置
function class_installer:yml_conf ()
return self.yml
end
--- 下载tags版本
--- @param ver string @1.? or ?
function class_installer:_download_tags(branch_name, ver, where, pkg, download_prefix)
local pkg_arr = _str_split(pkg, '/')
local username = pkg_arr[1]
local user_package_name = pkg_arr[2]
local download_dir = self._conf.install_dir .. "/.download/"
if not _file_exist(download_dir) then
print('下载缓存目录不存在,创建:', _mkdir(download_dir))
end
local path_name = download_dir .. username .. '.' .. user_package_name .. '.' .. branch_name .. '.zip'
-- https://gitee.com/oshine/murphy/repository/archive/v1.01.zip
if not _file_exist(path_name) then
local r = _wget(path_name .. '_temp', download_prefix, {
headers = { ['User-Agent'] = 'curl/7.74.0 (' .. _os(true) .. '/woo-' .. _ver() .. _time() .. ')' } })
--if not r then
-- print('download fail:', download_prefix, '=>', path_name)
-- return
--end
print(r)
-- 下载完毕后,修改文件名
_mv(path_name .. '_temp', path_name)
else
print('use cache:', path_name)
end
local f = ''
if ver == '@' then
-- 安装master版本
f = 'master'
else
f = branch_name
end
ver = _ltrim(ver, 'v')
local p
if where == 'local' then
-- 本地安装
local unzip_res = _zip('unzip', path_name, './vendor/' .. pkg)
if unzip_res ~= true then
print(self._trs['unzip_fail']:format(path_name, unzip_res))
return
end
p = './vendor/' .. pkg
_mv(p .. user_package_name .. '-' .. f, p .. ver)
else
-- 全局安装
local unzip_res = _zip('unzip', path_name, self._conf.install_dir .. '/' .. pkg)
if unzip_res ~= true then
print(self._trs['unzip_fail']:format(path_name, unzip_res))
return
end
p = self._conf.install_dir .. '/' .. pkg .. '/'
--print('change:===', p .. user_package_name .. '-' .. ver, p .. f)
_mv(p .. user_package_name .. '-' .. f, p .. ver)
end
-- 安装依赖包中的依赖包
require('oshine/om@1.?:installer'):new(p .. ver):_install_pkg({ lan = self._conf.language }, self._curr_where)
--- 当某个包安装完毕后,需要把它的绝对地址写入path.woo
_file_save(p .. ver .. '/path.woo', 'return "' .. p .. ver .. '"')
end
--- 安装成功之后调用
function class_installer:_after_install(pkg, ver)
local v = ver
ver = ver == 'master' and '' or (ver .. '?')
if ver == '@?' then
ver = ''
end
print('after install:==', pkg, ver)
local s, after = pcall(function()
print('pkg:===', pkg .. '@' .. ver .. ':install/after')
return require(pkg .. '@' .. ver .. ':install/after')
end)
--_out('after:===', after,s, '===')
if after and type(after) == 'table' then
after.run(pkg, v, self._conf)
end
end
--- 把需要加入path的环境变量处理下
function class_installer:_env_path_add(pkg, ver, real_path)
if self.yml.env_path then
print('env_path check:', _json_encode(self.yml.env_path))
print('添加环境变量:', real_path)
--- 开始加入环境变量PATH
require('oshine/om@1.?:utils/env_path')(real_path)
else
print('evn 忽略:', pkg, ver, real_path)
end
end
--- 全局导出cmd命令
function class_installer:_export_cmd(pkg, ver, pkg_path)
print("_export_cmd,before copy:===", work_dir, self._conf.install_dir .. '/' .. self.yml.package_name)
--local r, e = _cp(work_dir, self._conf.install_dir .. '/' .. self.yml.package_name)
--print("copy:===", r, e)
-- rename=[cmd/]rename
--_out('export:===', self.yml)
if type(self.yml.export) == 'table' then
print('_export_cmd,export ok:===', _json_encode(self.yml.export))
for i, v in pairs(self.yml.export) do
print('===_export_cmd,export!:===', i, v)
if not self._is_bin_created then
if not _file_exist(pkg_path .. '/../.bin') then
_mkdir(pkg_path .. '/../.bin')
end
self._is_bin_created = true
end
print('_export_cmd,export file:==', pkg_path .. '/../.bin/' .. i, work_dir .. '/cmd/' .. v .. '.woo')
_file_save(pkg_path .. '/../.bin/' .. i, work_dir .. '/cmd/' .. v .. '.woo')
end
else
print('导出,忽略:', self.yml.package_name)
end
end
function class_installer:_error(err)
_color('pre', err, 'red')
end
--- 选择tags版本
--- @param ver string @1.? or ?
function class_installer:_choose_tags(tags_path, ver, where, download_prefix, pkg)
print('choose tags:===', tags_path, ver, where, download_prefix)
local pkg_name = _str_replace(pkg, '/', '.')
local tags_name_cache = self._conf.install_dir .. '/.download/' .. pkg_name
local r, e
if _file_exist(tags_name_cache) then
r = { isCache = true, body = _cat(tags_name_cache, true) }
local time = _sub_ex('n', r.body, ' ')
print('time:===', time)
if _is_valid(time) and 1 * time + 60 * 60 * 3 > _time() then
-- 有效期3小时
print('缓存有效,tags列表,使用缓存:', tags_name_cache)
r.body = _sub_ex('re', r.body, ' ')
else
r = nil
end
end
if (r and not _is_valid(r.body)) or not r then
-- 获取tags列表之前,先看看本地缓存,本地缓存有效期3小时
r, e = woo.http:new():get(tags_path, {
headers = { ['User-Agent'] = ('curl/7.74.0 (%s/woo-%s/%s)'):format(_os(true), _ver(), _time()) } })
end
print(self._trs['installer_choose_tags'])
local re_ver = _str_replace(ver, '?', '.*')
if not e then
print('取到tags list:===', r.body, e)
local res = _json_decode(r.body)
print('got tags list:===', _json_encode(res))
if (not res) then
local sour = _str_index(tags_path, '//gitee.com') ~= -1 and 'gitee.com' or 'github.com'
self:_error(({ en = 'err,your ip be limited by source:%s,msg:%s,now try another source', zh = '错误,您的ip远程获取tags列表被限制,来自源:%s,错误信息:%s,现在重试使用其他源' })[self._conf.language]:format(sour, r.body))
return false -- 返回false就是需要重新使用其他源来下载
end
-- 不是缓存,那么就保存
if not r.isCache then
if ver == '?' then
tags_name_cache = tags_name_cache -- .. '_' .. res.commit.sha
end
-- 获取到列表,先更新下本地缓存
local r_tags = _file_save(tags_name_cache, _time() .. ' ' .. r.body)
if not r_tags then
self:_error('缓存写入失败:', tags_name_cache)
return
end
end
if #res == 0 then
-- choose master branch
-- https://gitee.com/oshine/murphy/repository/archive/master.zip
if _str_index(download_prefix, self._prefix_gitee) ~= -1 then
download_prefix = download_prefix:format('master')
elseif _str_index(download_prefix, self._prefix_github) ~= -1 then
download_prefix = download_prefix:format('heads/master')
end
print(self._trs['installer_choose_result_master']:format(download_prefix), '===')
self:_download_tags('master', '@', where, pkg, download_prefix)
else
local v
-- choose a match tags branch
-- gitee是倒着取版本
for i = #res, 0, -1 do
v = res[i]
local name
if 1 < _str_count(v.name, '.') then
print('version named illegal,can only have one point symbol:' .. v.name, 'eg:v1.0123 v1.34001 v2.301')
return
end
if _begin_with(v.name, 'v') then
name = _str_sub(v.name, 1) * 1
else
name = v.name * 1
end
print('got version:===', name, re_ver)
if name > 0 then
local rv = _re_match('' .. name, re_ver)
if rv[1] then
-- https://gitee.com/oshine/om/repository/archive/v1.011.zip
if _str_index(download_prefix, self._prefix_gitee) ~= -1 then
download_prefix = download_prefix:format(v.name)
elseif _str_index(download_prefix, self._prefix_github) ~= -1 then
download_prefix = download_prefix:format('tags/' .. v.name)
end
print(self._trs['installer_choose_result_tags']:format(v.name, download_prefix))
self:_download_tags(v.name, v.name, where, pkg, download_prefix)
break
end
else
print('version error,what fuck???? name err')
end
end
end
else
print('get tags list error:', e)
end
end
--- 是否已经安装
function class_installer:_check_installed(p, install_version_re, install_version)
local skip
if _file_exist(p) then
-- if installed,juuuuust skip
_ls(p, function(v)
print('目录:', p, _json_encode(v))
print('install ver:===', install_version_re, install_version)
local re_res = _re_match(v.name, install_version_re)
print('install ver:===', _json_encode(re_res))
if #re_res[1] > 0 and v.name == re_res[1][1] or (v.name == '@' and install_version == '?') then
skip = true
return true
end
end, true)
end
print('check ins:==', skip)
return skip
end
--- 安装依赖包根据 package.woo
function class_installer:_install_pkg(param, where_parent)
for pkg, dep in pairs(self.yml.dependencies) do
local install_version, install_where
if _str_index(dep, '|') > -1 then
local sp = _str_split(dep, "|")
if #sp == 2 then
install_where = sp[2]
install_version = sp[1]
else
print(self._trs['install_where_nil']:format(dep))
install_version = sp[1]
end
if _str_index(install_version, '*') > -1 then
_color('pre', 'version can not contain symbol *,pkg ignored:' .. pkg .. ',' .. dep, 'red')
return
end
-- 没有定义安装位置,默认继承父包安装位置
install_where = install_where or 'auto'
if install_where == 'auto' then
install_where = where_parent and where_parent or 'global'
end
install_version = install_version or '?'
end
local install_version_re = _str_replace(install_version, '?', '.*?')
local skip = false
_out(self._conf)
print('pkg:==', self._conf.install_dir, pkg, install_version_re)
if install_where == 'local' then
-- if installed,juuuuust skipm
_ls('./vendor/' .. pkg, function(i, v)
-- v.name = 1.124
-- v.name = @
local re_res = _re_match(v.name, install_version_re)
if #re_res[1] > 0 and v.name == re_res[1][1] or (v.name == '@' and install_version == '?') then
skip = true
return true
end
end)
elseif install_where == 'global' then
skip = class_installer:_check_installed(self._conf.install_dir .. '/' .. pkg, install_version_re, install_version)
else
print('just global and local can be use')
return
end
self._curr_where = install_where
print('must install:===', install_where, where_parent)
if not skip then
print(self._trs['installer_install_dependencies']:format(install_where, install_version))
print('start search pkg:', pkg)
require('oshine/om@' .. self._conf.v .. ':api/package'):new(self._conf):search(pkg, function(data)
_out(pkg .. ' find ok,install now...', data[1])
if not data[1] then
print(self._trs['installer_not_find_pkg']:format(pkg))
return
end
local git_source = data[1].git_source
local git_sources = _str_split(git_source, ',')
if #git_sources == 0 then
print(self._trs['installer_not_find_pkg']:format(pkg), '===')
return
end
-- https://github.com/rust-lang/rust/archive/refs/tags/release-0.6.zip
-- https://github.com/rust-lang/rust/archive/refs/tags/1.38.0.zip
if self._conf.language == 'zh' and _str_index(git_source, self._prefix_gitee) ~= -1 then
for _, v in pairs(git_sources) do
if _str_index(v, self._prefix_gitee) ~= -1 then
self:_choose_tags(self._api_host['gitee']:format(pkg), install_version,
install_where, self._download_zip_addr['gitee']:format(pkg, '%s'), pkg)
break
end
end
elseif self._conf.language == 'en' and _str_index(git_source, self._prefix_github) ~= -1 then
for _, v in pairs(git_sources) do
if _str_index(v, self._prefix_github) ~= -1 then
self:_choose_tags(self._api_host['github']:format(pkg), install_version,
install_where, self._download_zip_addr['github']:format(pkg, '%s'), pkg)
end
break
end
else
-- 随便使用第一个即可
local v = git_sources[1]
if _str_index(v, self._prefix_github) ~= -1 then
self:_choose_tags(self._api_host['github']:format(pkg), install_version,
install_where, self._download_zip_addr['github']:format(pkg, '%s'), pkg)
elseif _str_index(v, self._prefix_gitee) ~= -1 then
self:_choose_tags(self._api_host['gitee']:format(pkg), install_version,
install_where, self._download_zip_addr['gitee']:format(pkg, '%s'), pkg)
end
end
end)
end
end
-- 所有插件安装之后,执行after install
self:_after_install(self.yml.package_name, self._ver)
local pkg = self.yml.package_name
local ver = self._ver
local p = work_dir .. ver
print('p:===================', pkg, ver, p, ver)
--self:_env_path_add(pkg, ver, p .. ver)
--self:_export_cmd(pkg, ver, p)
---- 安装完毕,添加安装成功文件
--_file_save(p .. ver .. '/installed.woo', 'return "' .. _time() .. '"')
end
--- 安装自己,或者某个包
---@param param table
---@param is_self boolean@是否是安装自己
---@param ver string@om的版本好,比如:1.15
function class_installer:install(param, is_self, ver)
local cwm_path = self._conf.install_dir
if not cwm_path then
print(self._trs['om_path_nil'])
return
end
if param.lan then
self._conf.language = param.lan
end
-- before install
--print(pcall(function()
-- local before = require('oshine.om@:install.before')
-- if before then
-- before.run(work_dir, param.language)
-- end
--end))
self._ver = ver
self:_install_pkg(param)
end
return class_installer