checkupdate.lua 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import("core.base.semver")
  2. import("net.http")
  3. import("devel.git")
  4. import("private.action.require.impl.utils.filter")
  5. function shasum_of(package, url, version)
  6. local shasum
  7. local tmpfile = os.tmpfile()
  8. package:version_set(version)
  9. url = filter.handle(url, package)
  10. local ok = try { function() http.download(url, tmpfile); return true end }
  11. if ok and os.isfile(tmpfile) and os.filesize(tmpfile) > 1024 then
  12. shasum = hash.sha256(tmpfile)
  13. end
  14. os.tryrm(tmpfile)
  15. return shasum
  16. end
  17. function _is_valid_version(version)
  18. if not semver.is_valid(version) then
  19. return false
  20. end
  21. local v = semver.new(version)
  22. local prerelease = v:prerelease()
  23. if prerelease and #prerelease > 0 then
  24. return false
  25. end
  26. return true
  27. end
  28. function _get_version_and_shasum(package, url, version_latest)
  29. if version_latest then
  30. local has_prefix_v = false
  31. for _, version in ipairs(package:versions()) do
  32. if version:startswith("v") then
  33. has_prefix_v = true
  34. end
  35. if semver.compare(version, version_latest) >= 0 then
  36. version_latest = nil
  37. break
  38. end
  39. end
  40. if version_latest then
  41. if has_prefix_v and not version_latest:startswith("v") then
  42. version_latest = "v" .. version_latest
  43. elseif not has_prefix_v and version_latest:startswith("v") then
  44. version_latest = version_latest:sub(2)
  45. end
  46. end
  47. end
  48. if version_latest then
  49. local shasum = shasum_of(package, url, version_latest)
  50. if shasum then
  51. return version_latest, shasum
  52. end
  53. end
  54. end
  55. function _check_version_from_github_tags(package, url)
  56. local repourl = url:match("https://github%.com/.-/.-/")
  57. if repourl then
  58. print("checking version from github tags %s ..", repourl)
  59. local version_latest
  60. local tags = try {function() return git.tags(repourl) end}
  61. if not tags then
  62. return false -- failed to get tags
  63. end
  64. for _, tag in ipairs(tags) do
  65. if _is_valid_version(tag) and (not version_latest or semver.compare(tag, version_latest) > 0) then
  66. version_latest = tag
  67. end
  68. end
  69. if version_latest then
  70. return _get_version_and_shasum(package, url, version_latest)
  71. end
  72. end
  73. end
  74. function _check_version_from_github_releases(package, url)
  75. local repourl = url:match("https://github%.com/.-/.-/")
  76. if repourl then
  77. print("checking version from github releases %s ..", repourl)
  78. local list = try {function() return os.iorunv("gh", {"release", "list", "--exclude-drafts", "--exclude-pre-releases", "-R", repourl}) end}
  79. if not list then
  80. list = try {function() return os.iorunv("gh", {"release", "list", "-R", repourl}) end}
  81. end
  82. if not list then
  83. return false -- failed to get tags
  84. end
  85. if list then
  86. local version_latest
  87. for _, line in ipairs(list:split("\n")) do
  88. local splitinfo = line:split("%s+")
  89. local release = splitinfo[1]
  90. local version = splitinfo[#splitinfo - 1]
  91. if not version or not _is_valid_version(version) and _is_valid_version(release) then
  92. version = release
  93. end
  94. if version and _is_valid_version(version) then
  95. version_latest = version
  96. break
  97. end
  98. end
  99. if version_latest then
  100. return _get_version_and_shasum(package, url, version_latest)
  101. end
  102. end
  103. end
  104. end
  105. function _version_is_behind_conditions(package)
  106. local scriptfile = path.join(package:scriptdir(), "xmake.lua")
  107. local file = io.open(scriptfile)
  108. for line in file:lines() do
  109. local pos = line:find("add_versions", 1, true) or line:find("add_versionfiles", 1, true)
  110. if pos and pos > 5 then
  111. return true
  112. end
  113. end
  114. file:close()
  115. end
  116. function main(package)
  117. local checkers = {
  118. ["https://github%.com/.-/.-/archive/refs/tags/.*"] = _check_version_from_github_tags,
  119. ["https://github%.com/.-/.-/releases/download/.*"] = _check_version_from_github_releases
  120. }
  121. for _, url in ipairs(package:urls()) do
  122. for pattern, checker in pairs(checkers) do
  123. if url:match(pattern) and not _version_is_behind_conditions(package) then
  124. return checker(package, url)
  125. end
  126. end
  127. end
  128. end