Add gitlab support in scripts/new.lua (#2136)

* Add gitlab suppor

* Refactor scripts/new.lua

This adds better extensibility for the future, if we want to add more
git providers.

Also, the code now looks more idiomatic and clean.

* refactor(new.lua): simplify options table formatting
refactor(new.lua): simplify get_gitlab_data function by removing unnecessary comments and returns
refactor(new.lua): simplify get_github_data function by removing unnecessary comments and returns
refactor(new.lua): simplify generate_package function by removing unnecessary comments and returns
The changes in this commit simplify the formatting of the options table and remove unnecessary comments and returns from the get_gitlab_data, get_github_data, and generate_package functions. These changes improve the readability and maintainability of the code.

refactor(new.lua): simplify build system detection and installation
feat(new.lua): add support for more build systems and dependencies
The build system detection and installation code has been simplified by using a table of build systems and their corresponding dependencies and installation functions. This allows for easier addition of new build systems and dependencies. The script now supports more build systems such as Meson and Bazel, and their respective dependencies.

* Update new.lua

* Update new.lua

* Update new.lua

---------

Co-authored-by: Pablo <pablo.hugen@bry.com.br>
Co-authored-by: ruki <waruqi@gmail.com>
pull/2144/head
Pablo Alessandro Santos Hugen 1 year ago committed by GitHub
parent 72d53cafe3
commit 878da0d63a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 282
      scripts/new.lua

@ -1,6 +1,7 @@
import("core.base.option")
import("core.base.semver")
import("core.base.json")
import("core.base.hashset")
import("lib.detect.find_tool")
import("lib.detect.find_file")
import("net.http")
@ -11,174 +12,251 @@ local options = {
{nil, "repo", "v", nil, "Set repository name.",
"e.g. ",
" - github:xmake-io/xmake",
" - brew:zlib"}
" - gitlab:xmake-io/xmake"}
}
function _generate_package_from_github(reponame)
-- get repository info
local gh = assert(find_tool("gh"), "gh not found!")
local repoinfo = os.iorunv(gh.program, {"repo", "view", reponame, "--json",
"description,homepageUrl,licenseInfo,url,sshUrl,name,latestRelease"})
-- function to get Gitlab data
function get_gitlab_data(reponame)
local glab = assert(find_tool("glab"), "glab not found!")
local host = os.iorunv(glab.program, {"config", "get", "host"}):trim()
local graphql_query = 'query={ project(fullPath: "' .. reponame .. '") { description webUrl sshUrlToRepo name } }'
local repoinfo = os.iorunv(glab.program, {"api", "graphql", "-f", graphql_query})
local data = {}
if repoinfo then
repoinfo = json.decode(repoinfo)
if repoinfo.data and repoinfo.data.project then
-- extract required data and restructure it
local project_data = repoinfo.data.project
data = {
description = project_data.description,
homepageUrl = project_data.webUrl,
licenseInfo = "MIT", -- NOTE: Find a way to get the project license in gitlab
url = project_data.webUrl,
sshUrl = project_data.sshUrlToRepo,
name = project_data.name,
}
repoinfo.data.project = data
end
end
return {host = host, data = data}
end
local function get_github_data(reponame)
local gh = assert(find_tool("gh"), "gh not found!")
local host = "github.com"
local data = os.iorunv(gh.program, {
"repo",
"view",
reponame,
"--json",
"description,homepageUrl,licenseInfo,url,sshUrl,name,latestRelease",
})
if data then
data = json.decode(data)
end
vprint(repoinfo)
return {data = data, host = host}
end
function generate_package(reponame, get_data)
local repo_data = get_data(reponame)
local data = repo_data.data
local host = repo_data.host
-- generate package header
local packagename = assert(repoinfo.name, "package name not found!"):lower()
local packagefile = path.join("packages", packagename:sub(1, 1), packagename, "xmake.lua")
local packagename = assert(data.name, "package name not found!"):lower()
local packagefile = path.join("packages", string.sub(packagename, 1, 1), packagename, "xmake.lua")
local file = io.open(packagefile, "w")
-- define package and homepage
file:print('package("%s")', packagename)
local homepage = repoinfo.homepageUrl
if homepage == nil or homepage == "" then
homepage = repoinfo.url
end
local homepage = data.homepageUrl and data.homepageUrl ~= "" and data.homepageUrl or data.url
if homepage then
file:print(' set_homepage("%s")', homepage)
end
local description = repoinfo.description or ("The " .. packagename .. " package")
local description = data.description or ("The " .. packagename .. " package")
file:print(' set_description("%s")', description)
local licensekey = type(repoinfo.licenseInfo) == "table" and repoinfo.licenseInfo.key
if licensekey then
-- define license if available
if type(data.licenseInfo) == "table" and data.licenseInfo.key then
local licenses = {
["apache-2.0"] = "Apache-2.0",
["lgpl-2.0"] = "LGPL-2.0",
["lgpl-2.1"] = "LGPL-2.1",
zlib = "zlib",
mit = "MIT"
mit = "MIT",
}
local license = licenses[licensekey]
local license = licenses[data.licenseInfo.key]
if license then
file:print(' set_license("%s")', license)
end
end
file:print("")
-- generate package urls and versions
-- define package URLs and versions
local repodir
local has_xmake
local has_cmake
local has_meson
local has_bazel
local has_autoconf
local need_autogen
local latest_release = repoinfo.latestRelease
local has_xmake, has_cmake, has_meson, has_bazel, has_autoconf, need_autogen
local latest_release = data.latestRelease
if type(latest_release) == "table" then
local url = ("https://github.com/%s/archive/refs/tags/%s.tar.gz"):format(reponame, latest_release.tagName)
local giturl = ("https://github.com/%s.git"):format(reponame)
file:write(' add_urls("https://github.com/' .. reponame .. '/archive/refs/tags/$(version).tar.gz",\n')
file:print(' "%s")', giturl)
local url = string.format("https://%s/%s/archive/refs/tags/%s.tar.gz", host, reponame, latest_release.tagName)
local giturl = string.format("https://%s/%s.git", host, reponame)
local tmpfile = os.tmpfile({ramdisk = false}) .. ".tar.gz"
repodir = tmpfile .. ".dir"
file:write(' add_urls("https://' .. host .. '/' .. reponame .. '/-/archive/$(version).tar.gz",\n')
file:print(' "%s")\n', giturl)
print("downloading %s", url)
http.download(url, tmpfile)
file:print(' add_versions("%s", "%s")', latest_release.tagName, hash.sha256(tmpfile))
archive.extract(tmpfile, repodir)
os.rm(tmpfile)
else
local giturl = ("https://github.com/%s.git"):format(reponame)
repodir = os.tmpfile({ramdisk = false})
local giturl = string.format("git@%s:%s.git", host, reponame)
repodir = os.tmpfile({ ramdisk = false })
file:print(' add_urls("%s")', giturl)
print("downloading %s", giturl)
git.clone(giturl, {outputdir = repodir, depth = 1})
local commit = git.lastcommit({repodir = repodir})
local version = try{ function() return os.iorunv("git", {"log", "-1", "--date=format:%Y.%m.%d", "--format=%ad"}, {curdir = repodir}) end}
git.clone(giturl, { outputdir = repodir, depth = 1 })
local commit = git.lastcommit({ repodir = repodir })
local version = try {
function()
return os.iorunv("git", {
"log",
"-1",
"--date=format:%Y.%m.%d",
"--format=%ad",
}, { curdir = repodir })
end
}
if version then
file:print(' add_versions("%s", "%s")', version:trim(), commit)
end
end
local build_systems = {
["xmake.lua"] = {
deps = {},
install = function(configs, package)
return [=[
io.writefile("xmake.lua", [[
add_rules("mode.release", "mode.debug")
target("%s")
set_kind("$(kind)")
add_files("src/*.c")
add_headerfiles("src/(*.h)")
]])
if package:config("shared") then
configs.kind = "shared"
end
import("package.tools.xmake").install(package, configs)]=]
end,
},
["CMakeLists.txt"] = {
deps = {"cmake"},
install = function(configs, package)
return [[
table.insert(configs, "-DCMAKE_BUILD_TYPE=" .. (package:is_debug() and "Debug" or "Release"))
table.insert(configs, "-DBUILD_SHARED_LIBS=" .. (package:config("shared") and "ON" or "OFF"))
import("package.tools.cmake").install(package, configs)]]
end,
},
["configure,configure.ac,autogen.sh"] = {
deps = {"autoconf", "automake", "libtool"},
install = function(configs, package)
return [[
table.insert(configs, "--enable-shared=" .. (package:config("shared") and "yes" or "no"))
if package:is_debug() then
table.insert(configs, "--enable-debug")
end
import("package.tools.autoconf").install(package, configs)]]
end,
},
["meson.build"] = {
deps = {"meson", "ninja"},
install = function(configs, package)
return [[
table.insert(configs, "-Ddefault_library=" .. (package:config("shared") and "shared" or "static"))
import("package.tools.meson").install(package, configs)]]
end,
},
["BUILD,BUILD.bazel"] = {
deps = {"bazel"},
install = function(configs, package)
return 'import("package.tools.bazel").install(package, configs)'
end,
}
}
-- detect build system
local build_system = nil
if repodir then
local files = os.files(path.join(repodir, "*")) or {}
table.join2(files, os.files(path.join(repodir, "*", "*")))
for _, file in ipairs(files) do
local filename = path.filename(file)
if filename == "xmake.lua" then
has_xmake = true
elseif filename == "CMakeLists.txt" then
has_cmake = true
elseif filename == "configure" then
has_autoconf = true
elseif filename == "autogen.sh" or filename == "configure.ac" then
need_autogen = true
has_autoconf = true
elseif filename == "meson.build" then
has_meson = true
elseif filename == "BUILD" or filename == "BUILD.bazel" then
has_bazel = true
for k, v in pairs(build_systems) do
local filenames = hashset.from(k:split(","))
if filenames:has(filename) then
build_system = v
break
end
end
end
os.rm(repodir)
end
if not build_system then
build_system = build_systems["xmake.lua"]
end
-- add dependencies
if has_cmake then
file:print("")
file:print(' add_deps("cmake")')
elseif has_meson then
file:print("")
file:print(' add_deps("meson", "ninja")')
elseif need_autogen then
file:print("")
file:print(' add_deps("autoconf", "automake", "libtool")')
elseif has_bazel then
file:print("")
file:print(' add_deps("bazel")')
if build_system then
file:print('')
local deps = table.wrap(build_system.deps)
if deps and #deps > 0 then
file:print(' add_deps("' .. table.concat(deps, '", "') .. '")')
end
end
-- generate install scripts
file:print("")
file:print(" on_install(function (package)")
file:print(" local configs = {}")
if has_cmake then
file:print(' table.insert(configs, "-DCMAKE_BUILD_TYPE=" .. (package:debug() and "Debug" or "Release"))')
file:print(' table.insert(configs, "-DBUILD_SHARED_LIBS=" .. (package:config("shared") and "ON" or "OFF"))')
file:print(' import("package.tools.cmake").install(package, configs)')
elseif has_autoconf then
file:print(' table.insert(configs, "--enable-shared=" .. (package:config("shared") and "yes" or "no"))')
file:print(' if package:debug() then')
file:print(' table.insert(configs, "--enable-debug")')
file:print(' end')
file:print(' import("package.tools.autoconf").install(package, configs)')
elseif has_meson then
file:print(' table.insert(configs, "-Ddefault_library=" .. (package:config("shared") and "shared" or "static"))')
file:print(' import("package.tools.meson").install(package, configs)')
elseif has_bazel then
file:print(' import("package.tools.bazel").install(package, configs)')
else
file:print(' io.writefile("xmake.lua", [[')
file:print(' add_rules("mode.release", "mode.debug")')
file:print(' target("%s")', packagename)
file:write(' set_kind("$(kind)")\n')
file:print(' add_files("src/*.c")')
file:print(' add_headerfiles("src/(*.h)")')
file:print(' ]])')
file:print(' if package:config("shared") then')
file:print(' configs.kind = "shared"')
file:print(' end')
file:print(' import("package.tools.xmake").install(package, configs)')
file:print('')
file:print(' on_install(function (package)')
file:print(' local configs = {}')
if build_system then
file:print(build_system.install(configs, package))
end
file:print(" end)")
file:print(' end)')
-- generate test scripts
file:print("")
file:print(" on_test(function (package)")
file:print('')
file:print(' on_test(function (package)')
file:print(' assert(package:has_cfuncs("foo", {includes = "foo.h"}))')
file:print(" end)")
file:print(' end)')
file:close()
io.cat(packagefile)
cprint("${bright}%s generated!", packagefile)
end
function main(...)
local opt = option.parse(table.pack(...), options, "New a package.", "",
"Usage: xmake l scripts/new.lua [options]")
local repo = opt.repo
if repo and repo:startswith("github:") then
_generate_package_from_github(repo:sub(8))
else
raise("we need set repository name first!")
local opt = option.parse(table.pack(...), options, "New a package.", "", "Usage: xmake l scripts/new.lua [options]")
local repo = assert(opt.repo, "repository name must be set!")
local reponame = repo:sub(8)
if repo:startswith("github:") then
generate_package(reponame, get_github_data)
return
end
if repo:startswith("gitlab:") then
generate_package(reponame, get_gitlab_data)
return
end
raise("unsupported repository source. only 'github' and 'gitlab' are supported.")
end

Loading…
Cancel
Save