local ffi = require "ffi"
local git = require "cogit.git"
ffi.cdef[[
typedef unsigned long ino_t;
typedef unsigned long off_t;
struct dirent {
ino_t d_ino; /* Inode number */
off_t d_off; /* Not an offset; see below */
unsigned short d_reclen; /* Length of this record */
unsigned char d_type; /* Type of file; not supported
by all filesystem types */
char d_name[256]; /* Null-terminated filename */
};
int scandir(const char *restrict dirp,
struct dirent ***restrict namelist,
int (*filter)(const struct dirent *),
int (*compar)(const struct dirent **,
const struct dirent **));
int alphasort(const struct dirent **a, const struct dirent **b);
enum {
DT_UNKNOWN = 0,
DT_FIFO = 1,
DT_CHR = 2,
DT_DIR = 4,
DT_BLK = 6,
DT_REG = 8,
DT_LNK = 10,
DT_SOCK = 12,
};
]]
local C = ffi.C
local function listdir(path, filter)
local c_filter = filter and function (entry)
return filter(entry)
end
local pentries = ffi.new("struct dirent **[1]")
local n = C.scandir(path, pentries, c_filter, C.alphasort)
local entries = pentries[0]
local list = {}
for i = 1, n do
table.insert(list, ffi.string(entries[i-1].d_name))
end
return list
end
local function scanrepos(path)
local git_folders = listdir(path, function (e)
return e.d_type == C.DT_DIR and (ffi.string(e.d_name):match(".*%.git$") ~= nil)
end)
local repos = {}
for _, git_folder in ipairs(git_folders) do
local repo_path = path.."/"..git_folder
local repo_name = git_folder:match("(.*)%.git$")
local repo = git.open(repo_path)
local desc = io.open(repo_path.."/description"):read()
if desc:match("%w*") == "Unnamed" then desc = "" end
table.insert(repos, {name=repo_name, desc=desc, repo=repo})
end
return repos
end
return {scanrepos=scanrepos}