From 774980f0d1a660d3f33c97c2fe4d31fb5128f59e Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 14 Jan 2025 00:44:52 +0800 Subject: [PATCH] support sparse-checkout for git --- xmake/core/package/package.lua | 10 +++++++++- xmake/modules/devel/git/checkout.lua | 10 +++++++++- .../private/action/require/impl/actions/download.lua | 10 +++++----- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/xmake/core/package/package.lua b/xmake/core/package/package.lua index f7b49db3897..9c505fdb5f8 100644 --- a/xmake/core/package/package.lua +++ b/xmake/core/package/package.lua @@ -351,11 +351,19 @@ function _instance:url_version(url) return self:extraconf("urls", url, "version") end --- get the excludes list of url for the archive extractor, @note need raw url +-- get the excludes paths of url +-- @note it supports the path pattern, but it only supports for archiver. function _instance:url_excludes(url) return self:extraconf("urls", url, "excludes") end +-- get the includes paths of url +-- @note it does not support the path pattern, and it only supports for git url now. +-- @see https://github.com/xmake-io/xmake/issues/6071 +function _instance:url_includes(url) + return self:extraconf("urls", url, "includes") +end + -- get the http headers of url, @note need raw url function _instance:url_http_headers(url) return self:extraconf("urls", url, "http_headers") diff --git a/xmake/modules/devel/git/checkout.lua b/xmake/modules/devel/git/checkout.lua index 61919e4229f..38cc11845c7 100644 --- a/xmake/modules/devel/git/checkout.lua +++ b/xmake/modules/devel/git/checkout.lua @@ -20,6 +20,7 @@ -- imports import("core.base.option") +import("core.base.semver") import("lib.detect.find_tool") -- checkout to given branch, tag or commit @@ -38,7 +39,7 @@ import("lib.detect.find_tool") -- function main(commit, opt) opt = opt or {} - local git = assert(find_tool("git"), "git not found!") + local git = assert(find_tool("git", {version = true}), "git not found!") local argv = {} if opt.fsmonitor then table.insert(argv, "-c") @@ -48,6 +49,13 @@ function main(commit, opt) table.insert(argv, "core.fsmonitor=false") end + -- @see https://github.com/xmake-io/xmake/issues/6071 + -- https://github.blog/open-source/git/bring-your-monorepo-down-to-size-with-sparse-checkout/ + if opt.includes and git.version and semver.compare(git.version, "2.25") >= 0 then + os.vrunv(git.program, {"sparse-checkout", "init", "--cone"}, {curdir = opt.repodir}) + os.vrunv(git.program, table.join({"sparse-checkout", "set"}, opt.includes), {curdir = opt.repodir}) + end + table.insert(argv, "checkout") table.insert(argv, commit) os.vrunv(git.program, argv, {curdir = opt.repodir}) diff --git a/xmake/modules/private/action/require/impl/actions/download.lua b/xmake/modules/private/action/require/impl/actions/download.lua index 9e04d07a982..dca9d7545d4 100644 --- a/xmake/modules/private/action/require/impl/actions/download.lua +++ b/xmake/modules/private/action/require/impl/actions/download.lua @@ -125,7 +125,7 @@ function _checkout(package, url, sourcedir, opt) git.clone(url, {treeless = true, checkout = false, longpaths = longpaths, outputdir = packagedir}) -- attempt to checkout the given version - git.checkout(revision, {repodir = packagedir}) + git.checkout(revision, {repodir = packagedir, includes = opt.url_includes}) -- update all submodules if os.isfile(path.join(packagedir, ".gitmodules")) and opt.url_submodules ~= false then @@ -260,11 +260,7 @@ end -- download codes from script function _download_from_script(package, script, opt) - - -- do download script(package, opt) - - -- trace tty.erase_line_to_start().cr() cprint("${yellow} => ${clear}download %s .. ${color.success}${text.success}", opt.url) end @@ -314,6 +310,7 @@ function main(package, opt) for idx, url in ipairs(urls) do local url_alias = package:url_alias(url) local url_excludes = package:url_excludes(url) + local url_includes = package:url_includes(url) local url_http_headers = package:url_http_headers(url) local url_submodules = package:extraconf("urls", url, "submodules") @@ -349,16 +346,19 @@ function main(package, opt) url = url, url_alias = url_alias, url_excludes = url_excludes, + url_includes = url_includes, url_submodules = url_submodules}) elseif git.checkurl(url) then _checkout(package, url, sourcedir, { url_alias = url_alias, + url_includes = url_includes, url_submodules = url_submodules}) else _download(package, url, sourcedir, { download_only = opt.download_only, url_alias = url_alias, url_excludes = url_excludes, + url_includes = url_includes, url_http_headers = url_http_headers}) end return true