-- gall.ll -- -- Git Abstraction Layer for Lua -- Low level interface -- -- Copyright 2012 Daniel Silverstone -- -- local sp = require "luxio.subprocess" local util = require "gall.util" local git2 if os.getenv "GALL_DISABLE_GIT2" then git2 = nil else ok, git2 = pcall(require, "gall.ll.git2") if not ok then git2 = nil end end local assert = assert local git_exe = "git" local function _rungit(t) assert(t.repo, "No repository?") local proc_args = { env = {}, git_exe, unpack(t) } for k, v in pairs(t.env or {}) do proc_args.env[k] = v end proc_args.env.GIT_DIR = t.repo if t.stdin then proc_args.stdin = t.stdin end if t.stdout then proc_args.stdout = sp.PIPE end if t.stderr then proc_args.stderr = sp.PIPE end local proc = sp.spawn_simple(proc_args) local stdout, stderr if t.stdout then stdout = proc.stdout:read("*a") proc.stdout:close() if type(t.stdout) == "function" then stdout = t.stdout(stdout) end end if t.stderr then stderr = proc.stderr:read("*a") proc.stderr:close() if type(t.stderr) == "function" then stderr = t.stderr(stderr) end end local how, why = proc:wait() assert(how == "exit", "Not cleanly exited") return why, stdout, stderr end local function get_set_git(e) if e then git_exe = e end return git_exe end local function _chomp(s) local rest = s:match("^(.*)\n$") return rest or s end local mod_ret = { rungit = _rungit, get_set_git = get_set_git, chomp = _chomp, git2 = git2, } local simple_cmds = { "cat-file", "symbolic-ref", "show-ref", "hash-object", "ls-tree", "init", "merge-base", "rev-list", "config" } for _, s in pairs(simple_cmds) do local ss = s:gsub("%-", "_") local function ss_fn(_t) local t = util.deep_copy(_t) table.insert(t, 1, s) t.stdout = _chomp return _rungit(t) end mod_ret[ss] = ss_fn end return mod_ret