diff options
Diffstat (limited to 'love2dToAPK/tools/tools/zbstudio-win/lualibs/dist/git.lua')
-rw-r--r-- | love2dToAPK/tools/tools/zbstudio-win/lualibs/dist/git.lua | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/love2dToAPK/tools/tools/zbstudio-win/lualibs/dist/git.lua b/love2dToAPK/tools/tools/zbstudio-win/lualibs/dist/git.lua new file mode 100644 index 0000000..808f74d --- /dev/null +++ b/love2dToAPK/tools/tools/zbstudio-win/lualibs/dist/git.lua @@ -0,0 +1,306 @@ +-- Encapsulated Git functionality + +module ("dist.git", package.seeall) + +require "git" +local sys = require "dist.sys" +local cfg = require "dist.config" + + +-- Clone the repository from url to dest_dir +function clone(repository_url, dest_dir, depth, branch) + assert(type(repository_url) == "string", "git.clone: Argument 'repository_url' is not a string.") + assert(type(dest_dir) == "string", "git.clone: Argument 'dest_dir' is not a string.") + dest_dir = sys.abs_path(dest_dir) + + local command = "git clone " .. repository_url + + if depth then + assert(type(depth) == "number", "git.clone: Argument 'depth' is not a number.") + command = command .. " --depth " .. depth + end + + if branch then + assert(type(branch) == "string", "git.clone: Argument 'branch' is not a string.") + command = command .. " -b " .. branch + end + + command = command .. " " .. sys.quote(dest_dir) + if sys.exists(dest_dir) then sys.delete(dest_dir) end + sys.make_dir(dest_dir) + + -- change the current working directory to dest_dir + local prev_current_dir = sys.current_dir() + sys.change_dir(dest_dir) + + -- execute git clone + if not cfg.debug then command = command .. " -q " end + local ok, err = sys.exec(command) + + -- change the current working directory back + sys.change_dir(prev_current_dir) + + return ok, err +end + +-- Return table of all refs of the remote repository at the 'git_url'. Ref_type can be "tags" or "heads". +local function get_remote_refs(git_url, ref_type) + assert(type(git_url) == "string", "git.get_remote_refs: Argument 'git_url' is not a string.") + assert(type(ref_type) == "string", "git.get_remote_refs: Argument 'ref_type' is not a string.") + assert(ref_type == "tags" or ref_type == "heads", "git.get_remote_refs: Argument 'ref_type' is not \"tags\" or \"heads\".") + + local refs = {} + + local ok, refs_or_err = pcall(git.protocol.remotes, git_url) + if not ok then return nil, "Error getting refs of the remote repository '" .. git_url .. "': " .. refs_or_err end + + for ref, sha in pairs(refs_or_err) do + if ref:match("%S+/" .. ref_type .. "/%S+") and not ref:match("%^{}") then + table.insert(refs, ref:match("%S+/" .. ref_type .. "/(%S+)")) + end + end + + return refs +end + +-- Return table of all tags of the repository at the 'git_url' +function get_remote_tags(git_url) + return get_remote_refs(git_url, "tags") +end + +-- Return table of all branches of the repository at the 'git_url' +function get_remote_branches(git_url) + return get_remote_refs(git_url, "heads") +end + +-- Checkout specified ref in specified git_repo_dir +function checkout_ref(ref, git_repo_dir, orphaned) + git_repo_dir = git_repo_dir or sys.current_dir() + orphaned = orphaned or false + assert(type(ref) == "string", "git.checkout_ref: Argument 'ref' is not a string.") + assert(type(git_repo_dir) == "string", "git.checkout_ref: Argument 'git_repo_dir' is not a string.") + assert(type(orphaned) == "boolean", "git.checkout_ref: Argument 'orphaned' is not a boolean.") + git_repo_dir = sys.abs_path(git_repo_dir) + + local command = "git checkout " + if orphaned then command = command .. " --orphan " end + command = command .. " " .. ref .. " -f" + if not cfg.debug then command = command .. " -q " end + + local ok, err + if git_repo_dir ~= sys.current_dir() then + local prev_current_dir = sys.current_dir() + sys.change_dir(git_repo_dir) + ok, err = sys.exec(command) + sys.change_dir(prev_current_dir) + else + ok, err = sys.exec(command) + end + + return ok, err +end + +-- Checkout specified sha in specified git_repo_dir +function checkout_sha(sha, git_repo_dir) + git_repo_dir = git_repo_dir or sys.current_dir() + assert(type(sha) == "string", "git.checkout_sha: Argument 'sha' is not a string.") + assert(type(git_repo_dir) == "string", "git.checkout_sha: Argument 'git_repo_dir' is not a string.") + git_repo_dir = sys.abs_path(git_repo_dir) + + local dir_changed, prev_current_dir + + if git_repo_dir ~= sys.current_dir() then + prev_current_dir = sys.current_dir() + sys.change_dir(git_repo_dir) + dir_changed = true + end + + local ok, repo_or_err = pcall(git.repo.open, git_repo_dir) + if not ok then return nil, "Error when opening the git repository '" .. git_repo_dir .. "': " .. repo_or_err end + + local err + ok, err = pcall(repo_or_err.checkout, repo_or_err, sha, git_repo_dir) + if not ok then return nil, "Error when checking out the sha '" .. sha .. "' in the git repository '" .. git_repo_dir .. "': " .. err end + + repo_or_err:close() + if dir_changed then sys.change_dir(prev_current_dir) end + + return true +end + +-- Create an empty git repository in given directory. +function init(dir) + dir = dir or sys.current_dir() + assert(type(dir) == "string", "git.init: Argument 'dir' is not a string.") + dir = sys.abs_path(dir) + + -- create the 'dir' first, since it causes 'git init' to fail on Windows + -- when the parent directory of 'dir' doesn't exist + local ok, err = sys.make_dir(dir) + if not ok then return nil, err end + + local command = "git init " .. sys.quote(dir) + if not cfg.debug then command = command .. " -q " end + return sys.exec(command) +end + +-- Add all files in the 'repo_dir' to the git index. The 'repo_dir' must be +-- in the initialized git repository. +function add_all(repo_dir) + repo_dir = repo_dir or sys.current_dir() + assert(type(repo_dir) == "string", "git.add_all: Argument 'repo_dir' is not a string.") + repo_dir = sys.abs_path(repo_dir) + + local ok, prev_dir, msg + ok, prev_dir = sys.change_dir(repo_dir); + if not ok then return nil, err end + + ok, msg = sys.exec("git add -A -f " .. sys.quote(repo_dir)) + sys.change_dir(prev_dir) + + return ok, msg +end + +-- Commit all indexed files in 'repo_dir' with the given commit 'message'. +-- The 'repo_dir' must be in the initialized git repository. +function commit(message, repo_dir) + repo_dir = repo_dir or sys.current_dir() + message = message or "commit by luadist-git" + assert(type(message) == "string", "git.commit: Argument 'message' is not a string.") + assert(type(repo_dir) == "string", "git.commit: Argument 'repo_dir' is not a string.") + repo_dir = sys.abs_path(repo_dir) + + local ok, prev_dir, msg + ok, prev_dir = sys.change_dir(repo_dir); + if not ok then return nil, err end + + local command = "git commit -m " .. sys.quote(message) + if not cfg.debug then command = command .. " -q " end + ok, msg = sys.exec(command) + sys.change_dir(prev_dir) + + return ok, msg +end + + +-- Rename branch 'old_name' to 'new_name'. -- The 'repo_dir' must be +-- in the initialized git repository and the branch 'new_name' must +-- not already exist in that repository. +function rename_branch(old_name, new_name, repo_dir) + repo_dir = repo_dir or sys.current_dir() + assert(type(old_name) == "string", "git.rename_branch: Argument 'old_name' is not a string.") + assert(type(new_name) == "string", "git.rename_branch: Argument 'new_name' is not a string.") + assert(type(repo_dir) == "string", "git.rename_branch: Argument 'repo_dir' is not a string.") + repo_dir = sys.abs_path(repo_dir) + + local ok, prev_dir, msg + ok, prev_dir = sys.change_dir(repo_dir); + if not ok then return nil, err end + + ok, msg = sys.exec("git branch -m " .. old_name .. " " .. new_name) + sys.change_dir(prev_dir) + + return ok, msg +end + +-- Push the ref 'ref_name' from the 'repo_dir' to the remote git +-- repository 'git_repo_url'. If 'all_tags' is set to true, all tags +-- will be pushed, in addition to the explicitly given ref. +-- If 'delete' is set to 'true' then the explicitly given remote ref +-- will be deleted, not pushed. +function push_ref(repo_dir, ref_name, git_repo_url, all_tags, delete) + repo_dir = repo_dir or sys.current_dir() + all_tags = all_tags or false + delete = delete or false + assert(type(repo_dir) == "string", "git.push_ref: Argument 'repo_dir' is not a string.") + assert(type(git_repo_url) == "string", "git.push_ref: Argument 'git_repo_url' is not a string.") + assert(type(ref_name) == "string", "git.push_ref: Argument 'ref_name' is not a string.") + assert(type(all_tags) == "boolean", "git.push_ref: Argument 'all_tags' is not a boolean.") + assert(type(delete) == "boolean", "git.push_ref: Argument 'delete' is not a boolean.") + repo_dir = sys.abs_path(repo_dir) + + local ok, prev_dir, msg + ok, prev_dir = sys.change_dir(repo_dir); + if not ok then return nil, err end + + local command = "git push " .. git_repo_url + if all_tags then command = command .. " --tags " end + if delete then command = command .. " --delete " end + command = command .. " " .. ref_name .. " -f " + if not cfg.debug then command = command .. " -q " end + + ok, msg = sys.exec(command) + sys.change_dir(prev_dir) + + return ok, msg +end + +-- Creates the tag 'tag_name' in given 'repo_dir', which must be +-- in the initialized git repository +function create_tag(repo_dir, tag_name) + repo_dir = repo_dir or sys.current_dir() + assert(type(repo_dir) == "string", "git.create_tag: Argument 'repo_dir' is not a string.") + assert(type(tag_name) == "string", "git.create_tag: Argument 'tag_name' is not a string.") + repo_dir = sys.abs_path(repo_dir) + + local ok, prev_dir, msg + ok, prev_dir = sys.change_dir(repo_dir); + if not ok then return nil, err end + + ok, msg = sys.exec("git tag " .. tag_name .. " -f ") + sys.change_dir(prev_dir) + + return ok, msg +end + +-- Fetch given 'ref_name' from the remote 'git_repo_url' to the local repository +-- 'repo_dir' and return its sha. 'ref_type' can be "tag" or "head". +local function fetch_ref(repo_dir, git_repo_url, ref_name, ref_type) + repo_dir = repo_dir or sys.current_dir() + assert(type(repo_dir) == "string", "git.fetch_ref: Argument 'repo_dir' is not a string.") + assert(type(git_repo_url) == "string", "git.fetch_ref: Argument 'git_repo_url' is not a string.") + assert(type(ref_name) == "string", "git.fetch_ref: Argument 'ref_name' is not a string.") + assert(type(ref_type) == "string", "git.fetch_ref: Argument 'ref_type' is not a string.") + assert(ref_type == "tag" or ref_type == "head", "git.get_remote_refs: Argument 'ref_type' is not \"tag\" or \"head\".") + repo_dir = sys.abs_path(repo_dir) + + local refstring = "refs/" .. ref_type .. "s/" .. ref_name + + local suppress_fetch_progress = not cfg.debug + local ok, repo_or_err = pcall(git.repo.open, repo_dir) + if not ok then return nil, "Error when opening the git repository '" .. repo_dir .. "': " .. repo_or_err end + + local ok, pack_or_err, sha = pcall(git.protocol.fetch, git_repo_url, repo_or_err, refstring, suppress_fetch_progress) + if not ok then return nil, "Error when fetching ref '" .. refstring .. "' from git repository '" .. git_repo_url .. "': " .. pack_or_err end + + repo_or_err:close() + pack_or_err:close() + + return sha +end + +-- Fetch given 'tag_name' from the remote 'git_repo_url' to the local repository +-- 'repo_dir' and save it as a tag with the same 'tag_name'. +function fetch_tag(repo_dir, git_repo_url, tag_name) + return fetch_ref(repo_dir, git_repo_url, tag_name, "tag") +end + +-- Fetch given 'branch_name' from the remote 'git_repo_url' to the local repository +-- 'repo_dir' and save it as a branch with the same 'branch_name'. +function fetch_branch(repo_dir, git_repo_url, branch_name) + return fetch_ref(repo_dir, git_repo_url, branch_name, "head") +end + +-- Create the git repository and return the repo object (which can be used in checkout_sha etc.) +-- If the 'dir' exists, it's deleted prior to creating the git repository. +function create_repo(dir) + assert(type(dir) == "string", "git.create_repo: Argument 'dir' is not a string.") + + if sys.exists(dir) then sys.delete(dir) end + + local ok, repo_or_err = pcall(git.repo.create, dir) + if not ok then return nil, "Error when creating the git repository '" .. dir .. "': " .. repo_or_err end + + repo_or_err:close() + return true +end |