This repository was archived by the owner on Nov 3, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathgithub
More file actions
196 lines (168 loc) · 4.63 KB
/
github
File metadata and controls
196 lines (168 loc) · 4.63 KB
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
local github = dofile("apis/github")
local selectedAction = select(1, ...)
local passed = { select(2, ...) }
local subcommands = {
clone = {
usage = "github clone <user>/<repo> [-b <branchname> | -t <tagname>] [<destination>] [-a <username>]",
flags = {
['-b'] = 'branch',
['--branch'] = 'branch',
['-t'] = 'tag',
['--tag'] = 'tag',
['-a'] = 'authed',
['-auth'] = 'authed'
}
},
auth = {
usage = "github auth <user> [<api token> | -d ]",
flags = {
['-d'] = 'delete',
['--delete'] = 'delete'
}
}
}
local action = subcommands[selectedAction]
if not action then
for k, v in pairs(subcommands) do
print(v.usage)
print(" ")
end
return
end
-- make a bar of the form "[====> ] 50%"
function progressbar(f)
local left = "["
local right = ("]%3d%%"):format(f * 100)
local gap = select(1, term.getSize()) - #left - #right
local at = math.floor(f * (gap + 1))
for i = 1, gap do
left = left .. (
i < at and "=" or
i > at and " " or
">"
)
end
return left .. right
end
-- get flag arguments
local function findFlag(arg)
if arg.sub(1,1) == '-' then
if not action.flags[arg] then
return printError(('Unknown flag argument %s'):format(arg))
end
end
return action.flags[arg]
end
local args = {}
local flags = {}
local lastFlagged = 0
for k, arg in pairs(passed) do
if k ~= lastFlagged then
local flagName = findFlag(arg)
if flagName then
flags[flagName] = passed[k + 1] or true
lastFlagged = k + 1 or true
else
table.insert(args, arg)
end
end
end
if flags.branch and flags.tag then
return printError('--branch and --tag cannot both be specified')
end
local function hasEnoughSpace(repoSize, freeSpace)
-- The value reported by github underestimates the one reported by CC. This tries
-- to guess when this matters.
local sizeError = 0.2
local function warnAndContinue()
write("Repository may be too large to download, attempt anyway? [Y/n]: ")
local validAnswers = { [''] = 'yes', y = 'yes', yes = 'yes', n = 'no', no = 'no' }
local input = io.read()
while not validAnswers[input:lower()] do
print("Please type [y]es or [n]o")
input = io.read()
end
return validAnswers[input:lower()] == 'yes'
end
if repoSize > freeSpace then
return false
elseif repoSize * (1 + sizeError) > freeSpace then
return warnAndContinue()
else
return true
end
end
local function sizeStr(bytes)
local unit = 1024
if bytes < unit then
return ("%s byte(s)"):format(bytes)
else
local multi = 10^(1)
local KiB = math.floor((bytes/unit) * multi + 0.5) / multi
return ("%s KiB"):format(KiB)
end
end
if action == subcommands.clone then
-- parse input
local repo, dest = args[1], args[2]
local treeName = flags.branch or flags.tag or 'master'
if not repo then return printError("No repo specified") end
user, repo = repo:match('^(.-)/(.+)$')
if not (user and repo) then return printError("Invalid repo name - should be user/repo") end
dest = shell.resolve(dest or repo)
local auth = nil
if flags.authed then
-- if no user is found auth should remain nil.
auth = github.Auth.get(flags.authed)
end
if flags.authed and not auth then
return printError("Unknown user! Add one with 'git auth'")
elseif flags.authed and not auth:checkToken() then
return printError("Invalid Token!")
end
-- get file listings
local repo = github.repo(user, repo, auth)
print("Discovering files...")
local tree = repo:tree(treeName)
-- download the files
local totalSize = tree:getFullSize()
local freeSpace = fs.getFreeSpace(dest)
if not hasEnoughSpace(totalSize, freeSpace) then
local errStr = "Repository is %s, but only %s are free on this computer. Aborting!"
errStr = errStr:format(sizeStr(totalSize), sizeStr(freeSpace))
return printError(errStr)
end
print("Downloading:")
local size = 0
tree:cloneTo(dest, function(item)
-- called every time a download completes
if getmetatable(item) == github.Blob then
size = size + item.size
term.clearLine()
print(" "..item:fullPath())
term.write(progressbar(size/totalSize))
term.setCursorPos(1, select(2, term.getCursorPos()))
end
end)
term.scroll(1)
return
end
if action == subcommands.auth then
local user, token = args[1], args[2]
if not user then return printError("No user specified.") end
if flags.delete then
github.Auth.delete(user)
print(('Deleted github token for user %s'):format(user))
else
if not token then return printError("No token specified.") end
local auth = github.Auth.new('oauth', user, token)
if auth:checkToken() then
auth:save()
print(('Saved github token for user %s'):format(auth.user))
else
return printError("Invalid token!")
end
end
return
end
print(action.usage)