Created
September 29, 2017 10:08
-
-
Save mrkskwsnck/46b08dddfe7da376a22c317a343ee8d0 to your computer and use it in GitHub Desktop.
Iterate over all user's GitHub repositories and update them locally
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env lua | |
--[[ | |
Dependencies via Luarocks: | |
* luasocket | |
* luasec | |
* luajson | |
* luafilesystem | |
Environment variables to find locally installed rocks: | |
LUA_PATH_5_3="$HOME/.luarocks/share/lua/5.3/?.lua;;" | |
LUA_CPATH_5_3="$HOME/.luarocks/lib/lua/5.3/?.so;;" | |
--]] | |
----[[ CONFIGURATION | |
local userName = "GITHUB_USERNAME" | |
local accessToken = "GITHUB_ACCESS_TOKEN" | |
--]] | |
function updateRepo (r) | |
local success | |
local t = lfs.attributes(r.name) | |
if not t then | |
-- Directory does not exist | |
io.write(string.format("Cloning %s ...", r.name)) | |
io.flush() | |
local gitCmd = string.format("git clone --quiet %s", r.ssh_url) | |
success = assert(os.execute(gitCmd)) | |
else | |
-- Directory exists | |
io.write(string.format("Fetching %s ...", r.name)) | |
io.flush() | |
local cwd = lfs.currentdir() | |
lfs.chdir(r.name) | |
local gitCmd = "git fetch --all --quiet" | |
success = assert(os.execute(gitCmd)) | |
lfs.chdir(cwd) | |
end | |
if success then | |
io.write(" done.\n") | |
else | |
io.write(" failed!\n") | |
end | |
end | |
-- GET REPOSITORIES AND CREATE TASKS | |
function getRepos (userName, accessToken) | |
local reposUri = "https://api.github.com/users/" .. userName .. "/repos" | |
local responseTable = {} | |
local body, code = assert(https.request { | |
url = reposUri, | |
headers = { | |
["Authorization"] = "token " .. accessToken | |
}, | |
sink = ltn12.sink.table(responseTable) | |
}) | |
-- Exiting upon GET failure | |
if code ~= 200 then | |
io.stderr:write(string.format("Service returned HTTP status code %i\n", code)) | |
os.exit(false) | |
end | |
local t = json.decode(table.concat(responseTable)) | |
-- Create task for each repository | |
for _, v in pairs(t) do | |
table.insert(tasks, coroutine.create(function () updateRepo(v) end)) | |
end | |
end | |
-- DISPATCH TASKS AND UPDATE REPOSITORIES | |
function dispatch () | |
local i = 1 | |
while true do | |
-- Pre-check of tasks iterator | |
if tasks[i] == nil then | |
if tasks[1] == nil then | |
break | |
else | |
i = 1 -- Restart loop | |
end | |
end | |
local res = assert(coroutine.resume(tasks[i])) | |
if not res or coroutine.status(tasks[i]) == "dead" then -- Task ended | |
table.remove(tasks, i) | |
else | |
-- Goto next iteration | |
i = i + 1 | |
end | |
end | |
end | |
-- Main | |
https = require("ssl.https") | |
local json = require("json") | |
local lfs = require("lfs") | |
tasks = {} -- Consist of coroutines per repository | |
getRepos(userName, accessToken) | |
io.write(string.format("Updating repositories in: '%s'\n", lfs.currentdir())) | |
dispatch() | |
-- End of Main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment