summaryrefslogtreecommitdiff
path: root/lib/gall/ll.lua
blob: 3a242509c150248f086174a0fae76c1542acbd0c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
-- gall.ll
--
-- Git Abstraction Layer for Lua -- Low level interface
--
-- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org>
--
--

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