mpsd.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. #!/usr/bin/lua
  2. local talimatci= require("talimat")
  3. local rules= require("rules")
  4. -- Variables
  5. local talimat_file="talimat"
  6. local noexec=false
  7. local talimat_dir=""
  8. local isd=""
  9. local talimat_path=""
  10. local thash=""
  11. local start_task_no=1
  12. local _signs={[0]="+",[1]="-",[2]="!",[8]="Server issued an error response.(wget)"}
  13. local task_queue={
  14. "talimat_meta",
  15. "dirs_create" ,
  16. "fetch_sources" ,
  17. "check_sources" ,
  18. "extract_sources" ,
  19. "build_package",
  20. "install_package",
  21. "strip_files",
  22. "compress_manpages",
  23. "delete_files",
  24. "copy_scripts",
  25. "generate_meta",
  26. "generate_content",
  27. "generate_package",
  28. "dirs_delete"
  29. }
  30. -- Helper functions
  31. function _error(msg)
  32. print(msg)
  33. os.exit()
  34. end
  35. function shell(command)
  36. local handle=io.popen(command)
  37. local result=handle:read('*all')
  38. handle:close()
  39. -- komut çıktısı sonu yeni satır karakterin silinmesi - en sondaki \n
  40. if result:sub(-1) == "\n" then
  41. --result=result:gsub("\n", "")
  42. result=result:sub(1,-2)
  43. end
  44. return result
  45. end
  46. --- Check if a file or directory exists in this path
  47. function exists(file)
  48. local ok, err, code = os.rename(file, file)
  49. if not ok then
  50. if code == 13 then
  51. -- Permission denied, but it exists
  52. return true
  53. end
  54. end
  55. return ok, err
  56. end
  57. function string:addline(line)
  58. return self..line.."\n"
  59. end
  60. function string:split(delimiter)
  61. local result = {}
  62. if delimiter == "." then
  63. for i in string.gmatch(self, "[^%.]+") do
  64. table.insert(result,i)
  65. end
  66. else
  67. local from = 1
  68. local delim_from, delim_to = string.find( self, delimiter, from )
  69. while delim_from do
  70. table.insert( result, string.sub( self, from , delim_from-1 ) )
  71. from = delim_to + 1
  72. delim_from, delim_to = string.find( self, delimiter, from )
  73. end
  74. table.insert( result, string.sub( self, from ) )
  75. end
  76. return result
  77. end
  78. -- check a variable in an array
  79. function table.has(tab,val)
  80. for index, value in ipairs(tab) do
  81. if value == val then return true end
  82. end
  83. return false
  84. end
  85. function create_talimat(tdir)
  86. local template=[===[
  87. [paket]
  88. tanim = %s paketi
  89. paketci = milisarge
  90. grup = kütüphane
  91. url = https://mls.akdeniz.edu.tr
  92. [gerek]
  93. derleme =
  94. calisma =
  95. [kaynak]
  96. 1 = kaynak_adresi
  97. [sha256]
  98. 1 =
  99. [derle]
  100. tip = gnu
  101. [pakur]
  102. tip = gnu
  103. ]===]
  104. local isim =tdir:split("#")[1]
  105. local surum =tdir:split("#")[2]:split("-")[1]
  106. local devir =tdir:split("#")[2]:split("-")[2]
  107. if isim and surum and devir then
  108. shell("mkdir -pv "..tdir)
  109. end
  110. local file = io.open(tdir.."/talimat", "w")
  111. io.output(file)
  112. io.write(template:format(isim))
  113. io.close(file)
  114. print(tdir.." için şablon talimat oluşturuldu")
  115. end
  116. -------------------------------------------------- ---
  117. -- talimat metalarını export olarak çıktı almak için
  118. function talimat_meta()
  119. local t=""
  120. t=t:addline("##### talimat vars #####")
  121. for _,cmd in ipairs(rules.export.talimat(talimat.paket)) do
  122. t=t:addline(cmd)
  123. end
  124. return t
  125. end
  126. function dirs_create()
  127. local t=""
  128. t=t:addline("##### create dirs #####")
  129. t=t:addline(rules.make_dirs.archive())
  130. t=t:addline(rules.make_dirs.pkg())
  131. t=t:addline(rules.make_dirs.src())
  132. t=t:addline(rules.make_dirs.pkg_meta())
  133. return t
  134. end
  135. function prepare_sources()
  136. -- create srcobj, address store_name
  137. local t={}
  138. local key, address, store, place
  139. for _,val in ipairs(talimat.kaynak) do
  140. key=val:split("@@")[1]
  141. val=val:split("@@")[2]
  142. if rules.source[key] ~= nil then
  143. --apply rule
  144. val=rules.source[key](talimat,val)
  145. end
  146. --parse applied source string
  147. address=val:split("::")[1]
  148. store=val:split("::")[2]
  149. if store == nil then
  150. store=val:split("/")[#val:split("/")]
  151. end
  152. place="url"
  153. if key == "git" or key == "github" then place="git" end
  154. if key == "dosya" or key == "file" then place="file" end
  155. if place == "url" then store=rules.dirs.archive..store end
  156. if place == "file" then
  157. address=talimat_dir.."/"..address
  158. store=rules.dirs.src.."/"..store
  159. end
  160. -- add sources table
  161. table.insert(t,{fetch=place,address=address,store=store})
  162. end
  163. return t
  164. -- print(srcobj.fetch,srcobj.address,srcobj.store)
  165. end
  166. function fetch_sources()
  167. local t=""
  168. local sources=prepare_sources()
  169. t=t:addline("##### fetch sources #####")
  170. t=t:addline(talimat_meta())
  171. t=t:addline(rules.export.source_aliases)
  172. if sources == {} then
  173. _error("source list is not ready")
  174. end
  175. local afetch
  176. for _,srcobj in ipairs(sources) do
  177. --if srcobj.fetch == "url" then srcobj.store=rules.dirs.archive..srcobj.store end
  178. --if srcobj.fetch == "file" then
  179. -- srcobj.address=talimat_dir.."/"..srcobj.address
  180. -- srcobj.store=rules.dirs.src.."/"..srcobj.store
  181. --end
  182. if rules.fetch[srcobj.fetch] ~= nil then
  183. --t=t:addline(rules.fetch.check(srcobj))
  184. --apply rule
  185. afetch=rules.fetch[srcobj.fetch](srcobj)
  186. else
  187. _error("unknown fetch way:"..srcobj.fetch)
  188. end
  189. t=t:addline(afetch)
  190. end
  191. return t
  192. end
  193. function check_sources()
  194. local t=""
  195. -- apply talimat variables
  196. t=t:addline(talimat_meta())
  197. local sources=prepare_sources()
  198. t=t:addline("##### check sources #####")
  199. if sources == {} then
  200. _error("source list is not ready")
  201. end
  202. local achk
  203. local hashes={"sha256","sha512"}
  204. for _,hasht in ipairs(hashes) do
  205. if talimat[hasht] ~= nil then
  206. for index,_hash in ipairs(talimat[hasht]) do
  207. if sources[index] ~= nil then
  208. --if sources[index]["fetch"] == "file" then sources[index]["store"]=rules.dirs.src.."/"..sources[index]["store"] end
  209. --if sources[index]["fetch"] == "url" then sources[index]["store"]=rules.dirs.archive..sources[index]["store"] end
  210. achk=rules.hash[hasht](sources[index]["store"],_hash)
  211. t=t:addline(achk)
  212. end
  213. end
  214. end
  215. end
  216. return t
  217. end
  218. function extract_sources()
  219. local t=""
  220. -- apply talimat variables
  221. t=t:addline(talimat_meta())
  222. local sources=prepare_sources()
  223. t=t:addline("##### extract sources #####")
  224. if sources == {} then
  225. _error("source list is not ready")
  226. end
  227. local aext, suffix
  228. local archive_suffix={"gz","xz","lz","bz2"}
  229. -- archive file type only todo!!!
  230. for _,srcobj in ipairs(sources) do
  231. -- detect file type from suffix (todo!!! magic, mime type)
  232. suffix=srcobj.store:split(".")[#srcobj.store:split(".")]
  233. -- extract dir, store name
  234. if table.has(archive_suffix,suffix) then
  235. aext=rules.extract.bsdtar(rules.dirs.src,srcobj.store)
  236. t=t:addline(aext)
  237. end
  238. end
  239. return t
  240. end
  241. function build_package()
  242. local t=""
  243. t=t:addline("##### build sources #####")
  244. -- apply global env
  245. -- need(export_dir-make_dir)
  246. -- need(talimat_export)
  247. t=t:addline("set -x")
  248. for _,cmd in ipairs(rules.export.dirs()) do
  249. t=t:addline(cmd)
  250. end
  251. -- apply talimat variables
  252. t=t:addline(talimat_meta())
  253. -- apply build environments
  254. for key,_ in pairs(rules.build_env) do
  255. --print("----",export)
  256. t=t:addline(rules.build_env[key]())
  257. end
  258. -- default enter source directory
  259. t=t:addline(rules.change.dir(rules.dirs.src))
  260. if talimat.paket.arsiv then
  261. t=t:addline(rules.change.dir(rules.dirs.src..talimat.paket.arsiv))
  262. else
  263. t=t:addline(rules.change.dir(rules.package.archive))
  264. end
  265. -- create srcobj, address store_name
  266. local key
  267. -- traverse orderly
  268. for _,val in ipairs(talimat.derle) do
  269. key=val:split("@@")[1]
  270. val=val:split("@@")[2]
  271. if rules.build[key] ~= nil then
  272. --apply rule
  273. val=rules.build[key](talimat,val)
  274. end
  275. if rules.build_env[key] ~= nil then
  276. --apply rule
  277. val=rules.build_env[key](val)
  278. end
  279. t=t:addline(val)
  280. end
  281. --t=t:addline("set +x")
  282. return t
  283. end
  284. function install_package()
  285. local t=""
  286. t=t:addline("##### install package #####")
  287. t=t:addline("set -x")
  288. -- apply global env
  289. for _,cmd in ipairs(rules.export.dirs()) do
  290. t=t:addline(cmd)
  291. end
  292. -- apply talimat variables
  293. t=t:addline(talimat_meta())
  294. -- default enter source directory
  295. t=t:addline(rules.change.dir(rules.dirs.src))
  296. if talimat.paket.arsiv then
  297. t=t:addline(rules.change.dir(rules.dirs.src..talimat.paket.arsiv))
  298. else
  299. t=t:addline(rules.change.dir(rules.package.archive))
  300. end
  301. -- create srcobj, address store_name
  302. local key
  303. for _,val in ipairs(talimat.pakur) do
  304. key=val:split("@@")[1]
  305. val=val:split("@@")[2]
  306. if rules.install[key] ~= nil then
  307. --apply rule
  308. val=rules.install[key](talimat,val)
  309. end
  310. t=t:addline(val)
  311. end
  312. --t=t:addline("set +x")
  313. return t
  314. end
  315. function strip_files()
  316. local t=""
  317. t=t:addline("##### strip files #####")
  318. if rules.strip.status then
  319. t=t:addline(rules.strip.files(rules.dirs.pkg,rules.strip.blacklist))
  320. end
  321. return t
  322. end
  323. function compress_manpages()
  324. local t=""
  325. t=t:addline("##### compress manpages #####")
  326. t=t:addline(rules.compress.man(rules.dirs.pkg))
  327. return t
  328. end
  329. function delete_files()
  330. local t=""
  331. t=t:addline("##### delete files #####")
  332. t=t:addline(rules.delete.files_un(rules.dirs.pkg))
  333. return t
  334. end
  335. function copy_scripts()
  336. local t=""
  337. t=t:addline("##### copy scripts #####")
  338. t=t:addline(rules.copy.scripts(talimat.dir,rules.dirs.pkg,rules.dirs.pkg_meta))
  339. return t
  340. end
  341. function generate_meta()
  342. local t=""
  343. t=t:addline("##### generate meta #####")
  344. t=t:addline(talimat_meta())
  345. t=t:addline(rules.find.libdepends(rules.dirs.pkg,rules.dirs.pkg_meta))
  346. t=t:addline(rules.find.pkglibs())
  347. local size=rules.calculate.size(rules.dirs.pkg)
  348. t=t:addline(rules.generate.meta_info(rules.dirs.pkg,rules.dirs.pkg_meta,size,thash))
  349. return t
  350. end
  351. function generate_content()
  352. local t=""
  353. t=t:addline("##### generate content #####")
  354. t=t:addline(rules.generate.content_info(rules.dirs.pkg))
  355. return t
  356. end
  357. function generate_package()
  358. local t=""
  359. t=t:addline("##### generate package #####")
  360. t=t:addline(talimat_meta())
  361. t=t:addline(rules.generate.package(rules.dirs.pkg,rules.dirs.pkg_meta))
  362. return t
  363. end
  364. function dirs_delete()
  365. local t=""
  366. t=t:addline("##### delete dirs #####")
  367. t=t:addline(rules.delete.dir(rules.dirs.pkg))
  368. t=t:addline(rules.delete.dir(rules.dirs.src))
  369. return t
  370. end
  371. function create_yur()
  372. local file = io.open(("/tmp/%s.yur"):format(isd), "w")
  373. io.output(file)
  374. local operf="Operation file generated by MPSD 2.0 [%s]\n"
  375. operf=operf:format(os.date())
  376. for _,task in ipairs(task_queue) do
  377. operf=operf.."\n".._G[task]()
  378. end
  379. io.write(operf)
  380. io.close(file)
  381. end
  382. function run()
  383. --create yururluk file
  384. create_yur()
  385. local totalsec=0
  386. for taskno,task in ipairs(task_queue) do
  387. local task_cmd=""
  388. task_cmd=_G[task]()
  389. if start_task_no <= taskno then
  390. if noexec then
  391. print(task_cmd)
  392. print("##### ----------- #####")
  393. else
  394. local stime=os.time()
  395. print("--------------")
  396. print(task:upper())
  397. print("---------------------------------------------------")
  398. print("start time",os.date())
  399. print()
  400. local a,b,c,exno=pcall(os.execute,task_cmd)
  401. --print(a,b,c,exno)
  402. print()
  403. print("finish time",os.date())
  404. totalsec=totalsec+(os.time()-stime)
  405. print("STATUS:",_signs[exno],exno,"sn: "..tostring(os.time()-stime))
  406. print("---------------------------------------------------")
  407. if exno ~= 0 then
  408. break
  409. end
  410. end
  411. print()
  412. end
  413. end
  414. print("Total min:",math.floor(totalsec/60*100)/100)
  415. end
  416. -- logging mpsd.lua talimatdir | tee /tmp/package.log
  417. -------------- main start ---------------
  418. talimat_dir=arg[1]
  419. if talimat_dir == nil then _error("talimat dizini belirtilmedi!") end
  420. if #arg > 1 then
  421. for i = 2,#arg do
  422. if arg[i] == "--print" or arg[i] == "-p" then
  423. noexec=true
  424. elseif arg[i] == "--create" or arg[i] == "-c" then
  425. create_talimat(talimat_dir)
  426. os.exit()
  427. elseif arg[i] == "--generate" or arg[i] == "-g" then
  428. -- resume since instal_package task
  429. start_task_no=7
  430. end
  431. end
  432. end
  433. if exists(talimat_dir) == nil then _error("geçersiz talimat dizini!") end
  434. talimat_dir=shell("readlink -f "..talimat_dir)
  435. isd=shell("basename "..talimat_dir)
  436. talimat_path=talimat_dir.."/"..talimat_file
  437. thash=shell("sha256sum "..talimat_path.." | awk '{print $1}'")
  438. if exists(talimat_path) == nil then _error("talimat dosyası bulunmadı!") end
  439. talimat=talimatci.load(talimat_path,{"derle","pakur","kaynak"})
  440. talimat.dir=talimat_dir
  441. talimat.paket.isim=isd:split("#")[1]
  442. talimat.paket.surum=isd:split("#")[2]:split("-")[1]
  443. talimat.paket.devir=isd:split("#")[2]:split("-")[2]
  444. -- start to process tasks
  445. run()