--!A cross-platform build utility based on Lua -- -- Licensed under the Apache License, Version 2.0 (the "License"); -- you may not use this file except in compliance with the License. -- You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- -- Unless required by applicable law or agreed to in writing, software -- distributed under the License is distributed on an "AS IS" BASIS, -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- See the License for the specific language governing permissions and -- limitations under the License. -- -- Copyright (C) 2015-present, Xmake Open Source Community. -- -- @author ruki -- @file main.lua -- -- imports import("core.base.option") import("core.project.config") import("core.project.project") import("core.platform.platform") import("core.package.repository") import("devel.git") import("net.proxy") import("async.runjobs") import("private.action.require.impl.environment") import("private.service.remote_build.action", {alias = "remote_build_action"}) function _clear_quick_search_cache(is_global) if is_global then import("private.xrepo.quick_search.cache") cache.clear() end end -- add repository url function _add(name, url, branch, is_global) -- remove previous repository if exists local repodir = path.join(repository.directory(is_global), name) if os.isdir(repodir) then os.rmdir(repodir) end -- enter environment environment.enter() -- clone repository if not os.isdir(url) then local remoteurl = proxy.mirror(url) or url git.clone(remoteurl, {verbose = option.get("verbose"), branch = branch, outputdir = repodir, autocrlf = false}) end -- add url repository.add(name, url, branch, is_global) -- trace cprint("${color.success}add %s repository(%s): %s%s ok!", (is_global and "global" or "local"), name, url, branch and (" " .. branch) or "") -- leave environment environment.leave() -- clear quick search cache _clear_quick_search_cache(is_global) end -- remove repository url function _remove(name, is_global) -- remove url repository.remove(name, is_global) -- remove repository local repodir = path.join(repository.directory(is_global), name) if os.isdir(repodir) then os.rmdir(repodir) end -- clear quick search cache _clear_quick_search_cache(is_global) cprint("${bright}remove %s repository(%s): ok!", (is_global and "global" or "local"), name) end -- update repositories function _update() -- enter environment environment.enter() -- trace local name = option.get("name") if name then cprintf("updating repository ${bright}%s${clear} .. ", name) else printf("updating repositories .. ") end if option.get("verbose") then print("") end -- create a pull task local task = function () -- get all repositories (local first) local repos = table.join(repository.repositories({global = false}), repository.repositories({global = true})) if name then for _, repo in ipairs(repos) do if repo:name() == name then repos = {repo} break end end end -- pull all repositories local pulled = {} for _, repo in ipairs(repos) do local repodir = repo:directory() if not pulled[repodir] then if os.isdir(repodir) then -- only update the local repository with the remote url if not os.isdir(repo:url()) then -- check and update remote URL if it differs from repo:url() local current_url = git.remote.get_url({repodir = repodir}) local expected_url = repo:url() if current_url ~= expected_url then vprint("updating remote URL for repository(%s): %s -> %s", repo:name(), current_url or "", expected_url) git.remote.set_url(expected_url, {repodir = repodir}) end vprint("pulling repository(%s): %s to %s ..", repo:name(), repo:url(), repodir) git.reset({verbose = option.get("verbose"), repodir = repodir, hard = true}) git.pull({verbose = option.get("verbose"), branch = repo:branch(), repodir = repodir, force = true}) io.save(path.join(repodir, "updated"), {}) end else vprint("cloning repository(%s): %s to %s ..", repo:name(), repo:url(), repodir) local remoteurl = proxy.mirror(repo:url()) or repo:url() git.clone(remoteurl, {verbose = option.get("verbose"), branch = repo:branch(), outputdir = repodir, autocrlf = false}) io.save(path.join(repodir, "updated"), {}) end pulled[repodir] = true end end -- clear quick search cache _clear_quick_search_cache(true) end -- pull repositories if option.get("verbose") then task() else runjobs("update repo", task, {waiting_indicator = true, isolate = true}) end -- leave environment environment.leave() cprint("${green}ok") end -- clear all repositories function _clear(is_global) -- clear all urls repository.clear(is_global) -- remove all repositories local repodir = repository.directory(is_global) if os.isdir(repodir) then os.rmdir(repodir) end -- clear quick search cache _clear_quick_search_cache(is_global) cprint("${color.success}clear %s repositories: ok!", (is_global and "global" or "local")) end -- list all repositories function _list(is_global) local count = 0 for _, position in ipairs(is_global and "global" or {"local", "global"}) do print("%s repositories:", position) for _, repo in pairs(repository.repositories({global = position == "global"})) do print(" %s %s%s", repo:name(), repo:url(), repo:branch() and (" " .. repo:branch()) or "") count = count + 1 end print("") end print("%d repositories were found!", count) end -- get the repository directory function _directory(is_global) print(repository.directory(is_global)) end -- load project function _load_project() -- enter project directory os.cd(project.directory()) -- load config config.load() -- load platform platform.load(config.plat()) end -- main function main() -- do action for remote? if remote_build_action.enabled() then return remote_build_action() end -- load project if operate local repositories if not option.get("global") then _load_project() end -- add repository url if option.get("add") then _add(option.get("name"), option.get("url"), option.get("branch"), option.get("global")) -- remove repository url elseif option.get("remove") then _remove(option.get("name"), option.get("global")) -- update repository url elseif option.get("update") then _update() -- clear all repositories elseif option.get("clear") then _clear(option.get("global")) -- list all repositories elseif option.get("list") then _list(option.get("global")) -- show repo directory else _directory(option.get("global")) end end