login

<     >

2022-02-26 18:15:30 (UTC-03:00)

Marcel Rodrigues <marcelgmr@gmail.com>

add repo scanner

diff --git a/scan.lua b/scan.lua
new file mode 100644
index 0000000..bd4c5a1
--- /dev/null
+++ b/scan.lua
@@ -0,0 +1,69 @@
+local ffi = require "ffi"
+local git = require "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 folders = listdir(path, function (e)
+        return e.d_type == C.DT_DIR and ffi.string(e.d_name):sub(1, 1) ~= "."
+    end)
+    local groups = {}
+    for _, folder in ipairs(folders) do
+        local group_path = path.."/"..folder
+        local git_folders = listdir(group_path, function (e)
+            return e.d_type == C.DT_DIR and (ffi.string(e.d_name):match(".*%.git$") ~= nil)
+        end)
+        local group = {}
+        for _, git_folder in ipairs(git_folders) do
+            local repo_path = group_path.."/"..git_folder
+            local repo_name = git_folder:match("(.*)%.git$")
+            group[repo_name] = git.open(repo_path)
+        end
+        groups[folder] = group
+    end
+    return groups
+end
+
+return {scanrepos=scanrepos}