gitee-cli 0.1.0 → 0.2.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/gitee/cli/Rakefile +15 -4
- data/lib/gitee/cli.rb +32 -9
- data/lib/gitee/gitee4cli/api.rb +283 -85
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ae1cca9c4bcdc7c23af53a0d63cade1609b5c87acd168fa6698c02a08cd84d81
|
4
|
+
data.tar.gz: b42f6f27299a079cd616538c0adb1de06ca5244dfce425248bcd5d096f87ce12
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 513bef5e8aef71deeb9f09fbbbcb71d5fb8192447d002e482d43a27c5077d89f8a9813444946f081d212f2dda41ead331c8956736ef5f55bb2ad97630127feba
|
7
|
+
data.tar.gz: 8a37f84cd4f64a514da54c8eb77c42f88cc4880719bb233c69e648fb058501f247918c1546a3a56759a1391941d63d6c966f24895f34a400082f4576a5bfb03c
|
data/lib/gitee/cli/Rakefile
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# File : Rakefile
|
3
3
|
# Authors : Aoran Zeng <ccmywish@qq.com>
|
4
4
|
# Created on : <2023-04-29>
|
5
|
-
# Last modified : <2023-05-
|
5
|
+
# Last modified : <2023-05-08>
|
6
6
|
#
|
7
7
|
# Rakefile:
|
8
8
|
#
|
@@ -103,13 +103,24 @@ end
|
|
103
103
|
|
104
104
|
namespace "auth" do
|
105
105
|
|
106
|
-
desc "Apply for
|
107
|
-
task :
|
106
|
+
desc "Apply for an access token temporarily"
|
107
|
+
task :temp_apply do
|
108
108
|
puts 'Please visit:', ''
|
109
|
-
print ' ', Gitee::Gitee4CLI::API::
|
109
|
+
print ' ', Gitee::Gitee4CLI::API::API_BASE_URL + '/' + Gitee::Gitee4CLI::API::VERSION + '/swagger'
|
110
110
|
puts puts
|
111
111
|
end
|
112
112
|
|
113
|
+
desc "Apply for an access token using Gitee app"
|
114
|
+
task :apply, [:id, :secret] do |t, id:, secret:|
|
115
|
+
redirect_uri = "http://localhost"
|
116
|
+
res = Gitee::Gitee4CLI::API::Authorization.apply(id, secret, redirect_uri)
|
117
|
+
if res.successful?
|
118
|
+
puts "Success to apply, you can run any command now"
|
119
|
+
else
|
120
|
+
$stderr.puts "Error: " + res.why_failed
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
113
124
|
end
|
114
125
|
|
115
126
|
task default: :help
|
data/lib/gitee/cli.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# File : cli.rb
|
3
3
|
# Authors : Aoran Zeng <ccmywish@qq.com>
|
4
4
|
# Created on : <2023-04-28>
|
5
|
-
# Last modified : <2023-05-
|
5
|
+
# Last modified : <2023-05-08>
|
6
6
|
#
|
7
7
|
# cli:
|
8
8
|
#
|
@@ -32,22 +32,47 @@ module Gitee
|
|
32
32
|
module CLI
|
33
33
|
|
34
34
|
# gitee-cli version
|
35
|
-
VERSION = "0.
|
35
|
+
VERSION = "0.2.0.beta.1"
|
36
|
+
|
37
|
+
DEFAULT_TOKEN_DIR = File.join ENV['AppData'], "Gitee CLI in Ruby"
|
38
|
+
DEFAULT_TOKEN_FILE = File.join DEFAULT_TOKEN_DIR, "sec.json"
|
36
39
|
|
37
40
|
# Read token from local or environment variable
|
38
41
|
#
|
39
|
-
# @return [String] access token for Gitee API
|
42
|
+
# @return [Array<String, String>] Arrary of access token and refresh token for Gitee API
|
43
|
+
#
|
44
|
+
# @note The token file is a JSON file, with the content being like:
|
45
|
+
# {
|
46
|
+
# "access_token": "xxxxxxxxxxxxxxxxxxxxxx",
|
47
|
+
# "token_type": "bearer",
|
48
|
+
# "expires_in": 86400,
|
49
|
+
# "refresh_token": "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
|
50
|
+
# "scope": "user_info projects",
|
51
|
+
# "created_at": 1683393781
|
52
|
+
# }
|
40
53
|
#
|
41
54
|
def self.get_token
|
42
55
|
if tok = ENV['GITEE_TOKEN']
|
43
|
-
return tok
|
56
|
+
return [tok, nil]
|
57
|
+
end
|
58
|
+
|
59
|
+
if @token_already_get
|
60
|
+
return [@access_token, @refresh_token]
|
44
61
|
end
|
45
62
|
|
46
|
-
token_file = ENV['GITEE_TOKEN_FILE']
|
47
63
|
begin
|
48
|
-
|
64
|
+
if not Dir.exist? DEFAULT_TOKEN_DIR
|
65
|
+
Dir.mkdir DEFAULT_TOKEN_DIR
|
66
|
+
end
|
67
|
+
cont = File.read(DEFAULT_TOKEN_FILE).chomp
|
68
|
+
require 'json'
|
69
|
+
json = JSON.parse(cont)
|
70
|
+
@access_token = json['access_token']
|
71
|
+
@refresh_token = json['refresh_token']
|
72
|
+
@token_already_get = true
|
73
|
+
return [@access_token, @refresh_token]
|
49
74
|
rescue Exception => e
|
50
|
-
$stderr.puts "
|
75
|
+
$stderr.puts "Error: Failed to get or parse Gitee token from #{DEFAULT_TOKEN_FILE}"
|
51
76
|
$stderr.puts e.message
|
52
77
|
exit
|
53
78
|
end
|
@@ -55,8 +80,6 @@ module Gitee
|
|
55
80
|
|
56
81
|
# Parse the commandline and run the program
|
57
82
|
#
|
58
|
-
# @noreturn
|
59
|
-
#
|
60
83
|
def self.run
|
61
84
|
argv = ARGV.dup
|
62
85
|
|
data/lib/gitee/gitee4cli/api.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# File : api.rb
|
3
3
|
# Authors : Aoran Zeng <ccmywish@qq.com>
|
4
4
|
# Created on : <2023-04-28>
|
5
|
-
# Last modified : <2023-05-
|
5
|
+
# Last modified : <2023-05-08>
|
6
6
|
#
|
7
7
|
# api:
|
8
8
|
#
|
@@ -10,11 +10,20 @@
|
|
10
10
|
#
|
11
11
|
# ---------------------------------------------------------------
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
# All APIs reside here
|
14
|
+
#
|
15
|
+
# @!macro [new] param_owner
|
16
|
+
# @param [String] owner 仓库所属空间地址(企业、组织或个人的地址path)
|
17
|
+
#
|
18
|
+
# @!macro [new] param_repo
|
19
|
+
# @param [String] repo 仓库路径(path)
|
20
|
+
#
|
15
21
|
module Gitee::Gitee4CLI::API
|
16
22
|
|
17
|
-
|
23
|
+
# API BASE URL
|
24
|
+
API_BASE_URL = ::Gitee::Gitee4CLI::URL + '/api' # "https://gitee.com/api"
|
25
|
+
|
26
|
+
# API version
|
18
27
|
VERSION = "v5"
|
19
28
|
|
20
29
|
# Result type to return to CLI handler
|
@@ -22,11 +31,9 @@ module Gitee::Gitee4CLI::API
|
|
22
31
|
class Result
|
23
32
|
|
24
33
|
# @return [String] The content of a successful API call
|
25
|
-
#
|
26
34
|
attr_reader :content
|
27
35
|
|
28
36
|
# @return [String] The reason of a failed API call
|
29
|
-
#
|
30
37
|
attr_reader :why_failed
|
31
38
|
|
32
39
|
# New a Result object with successful info and its content or failed reason
|
@@ -68,6 +75,9 @@ module Gitee::Gitee4CLI::API
|
|
68
75
|
Created = 201
|
69
76
|
# Delete successfully
|
70
77
|
NoContent = 204
|
78
|
+
|
79
|
+
# Failed to authorize
|
80
|
+
Unauthorized = 401
|
71
81
|
end
|
72
82
|
|
73
83
|
# Private module to be included to provide common utilities for API modules, e.g. GitData
|
@@ -76,39 +86,149 @@ module Gitee::Gitee4CLI::API
|
|
76
86
|
#
|
77
87
|
module CommonUtilities
|
78
88
|
|
79
|
-
# This is for API modules to directly call rather than spell the whole namespaces
|
80
|
-
Reuslt = Gitee::Gitee4CLI::API::Result
|
81
|
-
|
82
89
|
# Simple wrapper to get token
|
83
90
|
#
|
84
|
-
# @return [String]
|
91
|
+
# @return [String] Access token value
|
85
92
|
#
|
86
93
|
def get_token
|
87
|
-
Gitee::CLI.get_token
|
94
|
+
Gitee::CLI.get_token[0]
|
88
95
|
end
|
89
96
|
|
90
|
-
#
|
97
|
+
# Refresh the outdated access token
|
91
98
|
#
|
92
|
-
#
|
93
|
-
# 1. `[Status] @status` status
|
94
|
-
# 2. `[String] @body` response body string
|
99
|
+
# @return [String] New access token
|
95
100
|
#
|
96
|
-
# @
|
97
|
-
# @noreturn
|
101
|
+
# @HTTP [POST] https://gitee.com/oauth/token?grant_type=refresh_token&refresh_token={refresh_token}
|
98
102
|
#
|
99
|
-
|
103
|
+
def refresh_access_token
|
104
|
+
url = Gitee::Gitee4CLI::URL + "/oauth/token?grant_type=refresh_token"
|
105
|
+
refresh_token = Gitee::CLI.get_token[1]
|
106
|
+
|
107
|
+
res = HTTP.post url, form: {refresh_token:}
|
108
|
+
|
109
|
+
status = res.status
|
110
|
+
json_str = res.to_s
|
111
|
+
json_hash = JSON.parse json_str
|
112
|
+
|
113
|
+
if status.code == HttpStatusCode::Ok
|
114
|
+
File.write Gitee::CLI::DEFAULT_TOKEN_FILE, json_str
|
115
|
+
@refreshed = true
|
116
|
+
else
|
117
|
+
$stderr.puts "Error: Failed to refresh access token failed, #{status.code} #{status.reason}"
|
118
|
+
json_hash.each do |k, v|
|
119
|
+
$stderr.puts " #{k}: #{v}"
|
120
|
+
end
|
121
|
+
exit
|
122
|
+
end
|
123
|
+
|
124
|
+
return json_hash['access_token']
|
125
|
+
end
|
126
|
+
|
127
|
+
# We only refresh once, to prevent infinite loop of refreshing token
|
128
|
+
#
|
129
|
+
# @return [Boolean] If we had already refreshed
|
100
130
|
#
|
101
|
-
def
|
131
|
+
def already_refreshed?
|
132
|
+
@refreshed
|
133
|
+
end
|
134
|
+
|
135
|
+
# Make a direct request, not being wrapped
|
136
|
+
#
|
137
|
+
# @return
|
138
|
+
# 1. [Status] `@status` status
|
139
|
+
# 2. [String] `@body` response body string
|
140
|
+
#
|
141
|
+
# @note 这个函数不同于`make_api_request`,后者经过包装,请求路径均相对于API,会读取本地的token。
|
142
|
+
# 而此函数的请求将相对于Gitee根路径,不会读取本地token。
|
143
|
+
#
|
144
|
+
def make_direct_request
|
145
|
+
require 'http'
|
146
|
+
url = [Gitee::Gitee4CLI::URL, @path].join('/')
|
102
147
|
instance_exec {
|
103
|
-
|
104
|
-
|
105
|
-
|
148
|
+
res = HTTP.send @action.to_sym, url, :form => @params
|
149
|
+
@status, @body = res.status, res.to_s
|
150
|
+
}
|
151
|
+
end
|
152
|
+
|
153
|
+
# Make a request for some specific API
|
154
|
+
#
|
155
|
+
# @return
|
156
|
+
# 1. [Status] `@status` status
|
157
|
+
# 2. [String] `@body` response body string
|
158
|
+
#
|
159
|
+
# @note This is only called by module functions
|
160
|
+
#
|
161
|
+
def make_api_request
|
106
162
|
|
107
|
-
|
108
|
-
# binding.irb
|
163
|
+
url = [API_BASE_URL, VERSION, @path].join('/')
|
109
164
|
|
110
|
-
|
165
|
+
require 'http'
|
166
|
+
|
167
|
+
tok_outdated = false
|
168
|
+
|
169
|
+
instance_exec {
|
170
|
+
|
171
|
+
if not ENV['GITEE_TOKEN']
|
172
|
+
json_str = File.read Gitee::CLI::DEFAULT_TOKEN_FILE
|
173
|
+
json_hash = JSON.parse json_str
|
174
|
+
created_at = json_hash['created_at']
|
175
|
+
duration = json_hash['expires_in']
|
176
|
+
|
177
|
+
will_expire_at_for_MACHINE = created_at + duration
|
178
|
+
will_expire_at_for_HUMAN = Time.at(will_expire_at_for_MACHINE).strftime "%Y-%m-%d %H:%M"
|
179
|
+
|
180
|
+
now = Time.new.to_s
|
181
|
+
if now.to_i + 30 <= will_expire_at_for_MACHINE
|
182
|
+
# We assume we at most spent 30s to issue and wait for a request to finish
|
183
|
+
else
|
184
|
+
# Directly refresh, because the access token must be outdated
|
185
|
+
tok_outdated = true
|
186
|
+
@params['access_token'] = refresh_access_token
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
loop do
|
192
|
+
|
193
|
+
res = HTTP.send @action.to_sym, url, :form => @params
|
194
|
+
@status, @body = res.status, res.to_s
|
195
|
+
|
196
|
+
break if @status.code != HttpStatusCode::Unauthorized
|
197
|
+
|
198
|
+
if ENV['GITEE_TOKEN']
|
199
|
+
$stderr.puts "Error: The GITEE_TOKEN (access token) you give is something wrong, maybe outdated, please check it."
|
200
|
+
exit
|
201
|
+
end
|
202
|
+
|
203
|
+
err_json_hash = JSON.parse @body
|
204
|
+
|
205
|
+
if already_refreshed?
|
206
|
+
if tok_outdated
|
207
|
+
$stderr.puts <<~ERR
|
208
|
+
Error: We've already refreshed the local access token (because it had been outdated).
|
209
|
+
But Gitee still returned '401 Unauthorized'. Please check the refresh token.
|
210
|
+
ERR
|
211
|
+
else
|
212
|
+
$stderr.puts <<~ERR
|
213
|
+
Error: The local access token is not outdated (Will expire at #{will_expire_at_for_HUMAN}).
|
214
|
+
But Gitee returned '401 Unauthorized', so we've refreshed access token and re-request.
|
215
|
+
However Gitee returned the same again. Please check the refresh token."
|
216
|
+
ERR
|
217
|
+
end
|
218
|
+
err_json_hash.each do |k, v|
|
219
|
+
$stderr.puts " #{k}: #{v}"
|
220
|
+
end
|
221
|
+
exit
|
222
|
+
end
|
223
|
+
|
224
|
+
# NOTE: We retry only if no GITEE_TOKEN has been provided
|
225
|
+
# Re-request using the new access token
|
226
|
+
@params['access_token'] = refresh_access_token
|
227
|
+
end
|
228
|
+
|
229
|
+
return @status, @body
|
111
230
|
}
|
231
|
+
|
112
232
|
end
|
113
233
|
|
114
234
|
end
|
@@ -116,6 +236,84 @@ module Gitee::Gitee4CLI::API
|
|
116
236
|
# Make it only accessible from inside
|
117
237
|
private_constant :CommonUtilities
|
118
238
|
|
239
|
+
|
240
|
+
# Gitee-cli APIs forged to use authorzation in Gitee
|
241
|
+
#
|
242
|
+
# @see https://gitee.com/api/v5/oauth_doc#/
|
243
|
+
#
|
244
|
+
module Authorization
|
245
|
+
|
246
|
+
extend CommonUtilities
|
247
|
+
|
248
|
+
# Apply for a for a Gitee Application
|
249
|
+
#
|
250
|
+
# @param [String] Client ID
|
251
|
+
# @param [String] Client Secret
|
252
|
+
# @param [String] Redirect URI
|
253
|
+
#
|
254
|
+
# @return [Result] JSON响应体
|
255
|
+
#
|
256
|
+
# @HTTP [GET] https://gitee.com/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code This is the first step, launched in web browser
|
257
|
+
#
|
258
|
+
# @HTTP [POST] https://gitee.com/oauth/token?grant_type=authorization_code&code={code}&client_id={client_id}&redirect_uri={redirect_uri}&client_secret={client_secret} This is the second step, posted by ourself
|
259
|
+
#
|
260
|
+
def self.apply(client_id, client_secret, redirect_uri)
|
261
|
+
|
262
|
+
require 'socket'
|
263
|
+
# Start HTTP server
|
264
|
+
server = TCPServer.new 80
|
265
|
+
|
266
|
+
path = sprintf "/oauth/authorize?client_id=%s&redirect_uri=%s&response_type=code", client_id, redirect_uri
|
267
|
+
url = Gitee::Gitee4CLI::URL + path
|
268
|
+
|
269
|
+
require 'launchy'
|
270
|
+
Launchy.open url # Non-block
|
271
|
+
|
272
|
+
socket = server.accept
|
273
|
+
# puts "Accepted"
|
274
|
+
|
275
|
+
first_line = socket.readline(chomp: true)
|
276
|
+
|
277
|
+
html = "<html>\r\n" +
|
278
|
+
"<h1>Gitee CLI</h1>\r\n" +
|
279
|
+
" <p><b>Success to get authorization code from Gitee.</b></p>\r\n" +
|
280
|
+
" <p>You can close this page now.</p>\r\n" +
|
281
|
+
"</html>"
|
282
|
+
|
283
|
+
socket.write "HTTP/1.1 200 OK\r\n" +
|
284
|
+
"Content-Type: text/html; charset=utf-8\r\n" +
|
285
|
+
"Content-Length: #{html.bytesize}\r\n"
|
286
|
+
|
287
|
+
socket.write "\r\n" # Separate headers from the body
|
288
|
+
socket.write html
|
289
|
+
socket.close
|
290
|
+
|
291
|
+
# e.g. "GET /?code=123456789 HTTP/1.1"
|
292
|
+
request = first_line
|
293
|
+
grant_auth_code = request.split[1].split('code=')[1]
|
294
|
+
|
295
|
+
|
296
|
+
@path = "oauth/token"
|
297
|
+
@params = {
|
298
|
+
grant_type: 'authorization_code',
|
299
|
+
code: grant_auth_code,
|
300
|
+
client_id:, redirect_uri:, client_secret:
|
301
|
+
}
|
302
|
+
@action = 'post'
|
303
|
+
make_direct_request
|
304
|
+
|
305
|
+
# @body is the JSON string
|
306
|
+
if @status.code == HttpStatusCode::Ok
|
307
|
+
File.write Gitee::CLI::DEFAULT_TOKEN_FILE, @body.to_s
|
308
|
+
Result[true, "success"]
|
309
|
+
else
|
310
|
+
Result[false, @status.to_s]
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
|
316
|
+
|
119
317
|
# GitData APIs
|
120
318
|
#
|
121
319
|
# @see https://gitee.com/api/v5/swagger#/getV5ReposOwnerRepoGitBlobsSha
|
@@ -128,9 +326,9 @@ module Gitee::Gitee4CLI::API
|
|
128
326
|
|
129
327
|
# Get file Blob
|
130
328
|
#
|
131
|
-
#
|
132
|
-
#
|
133
|
-
# @param
|
329
|
+
# @!macro param_repo
|
330
|
+
# @!macro param_owner
|
331
|
+
# @param [String] sha 文件的 Blob SHA,可通过[获取仓库具体路径下的内容(tree)]API获取
|
134
332
|
# @param [Boolean] recursive 赋值为1递归获取目录
|
135
333
|
#
|
136
334
|
# @return [String] JSON响应体
|
@@ -141,14 +339,14 @@ module Gitee::Gitee4CLI::API
|
|
141
339
|
access_token = get_token
|
142
340
|
recursive = recursive ? 1 : 0
|
143
341
|
@params = {access_token:, recursive:}
|
144
|
-
@path =
|
145
|
-
|
342
|
+
@path = sprintf "repos/%s/%s/git/blobs/%s", owner, repo, sha
|
343
|
+
make_api_request
|
146
344
|
end
|
147
345
|
|
148
346
|
# Get directory Tree
|
149
347
|
#
|
150
|
-
#
|
151
|
-
#
|
348
|
+
# @!macro param_owner
|
349
|
+
# @!macro param_repo
|
152
350
|
# @param [String] sha 可以是分支名(如master)、Commit或者目录Tree的SHA值
|
153
351
|
# @param [Boolean] recursive 赋值为1递归获取目录
|
154
352
|
#
|
@@ -163,15 +361,15 @@ module Gitee::Gitee4CLI::API
|
|
163
361
|
recursive = recursive ? 1 : 0
|
164
362
|
@params = {access_token:, recursive:}
|
165
363
|
@path = sprintf "repos/%s/%s/git/trees/%s", owner, repo, sha
|
166
|
-
|
364
|
+
make_api_request
|
167
365
|
end
|
168
366
|
|
169
367
|
# Get Gitee metrics for a repository
|
170
368
|
#
|
171
|
-
#
|
172
|
-
#
|
369
|
+
# @!macro param_owner
|
370
|
+
# @!macro param_repo
|
173
371
|
#
|
174
|
-
# @return [Result]
|
372
|
+
# @return [Result] JSON响应体
|
175
373
|
#
|
176
374
|
# @HTTP [GET] https://gitee.com/api/v5/repos/{owner}/{repo}/git/gitee_metrics
|
177
375
|
#
|
@@ -182,7 +380,7 @@ module Gitee::Gitee4CLI::API
|
|
182
380
|
@params = {access_token:}
|
183
381
|
@path = sprintf "repos/%s/%s/git/gitee_metrics", owner, repo
|
184
382
|
@action = 'get'
|
185
|
-
|
383
|
+
make_api_request
|
186
384
|
end
|
187
385
|
|
188
386
|
end
|
@@ -198,12 +396,12 @@ module Gitee::Gitee4CLI::API
|
|
198
396
|
include CommonUtilities
|
199
397
|
end
|
200
398
|
|
201
|
-
# Get all branches
|
399
|
+
# Get all branches from a owner's repo
|
202
400
|
#
|
203
|
-
#
|
204
|
-
#
|
401
|
+
# @!macro param_owner
|
402
|
+
# @!macro param_repo
|
205
403
|
#
|
206
|
-
# @return [Result]
|
404
|
+
# @return [Result] JSON响应体
|
207
405
|
#
|
208
406
|
# @HTTP [GET] https://gitee.com/api/v5/repos/{owner}/{repo}/branches
|
209
407
|
#
|
@@ -212,7 +410,7 @@ module Gitee::Gitee4CLI::API
|
|
212
410
|
@params = {access_token:}
|
213
411
|
@path = sprintf "repos/%s/%s/branches", owner, repo
|
214
412
|
@action = 'get'
|
215
|
-
|
413
|
+
make_api_request
|
216
414
|
if @status.code == 200
|
217
415
|
# 'json' is already required somewhere, maybe from 'http.rb'
|
218
416
|
Result[true, JSON.parse(@body)]
|
@@ -221,13 +419,14 @@ module Gitee::Gitee4CLI::API
|
|
221
419
|
end
|
222
420
|
end
|
223
421
|
|
224
|
-
# @
|
225
|
-
# Create a new branch
|
422
|
+
# @todo
|
423
|
+
# Create a new branch from a owner's repo
|
226
424
|
#
|
227
|
-
# @param [String] owner 仓库所属空间地址(企业、组织或个人的地址)
|
228
|
-
# @param [String] repo 仓库路径(path)
|
229
425
|
#
|
230
|
-
#
|
426
|
+
# @!macro param_owner
|
427
|
+
# @!macro param_repo
|
428
|
+
#
|
429
|
+
# @return [Result] JSON响应体
|
231
430
|
#
|
232
431
|
# @HTTP [POST] https://gitee.com/api/v5/repos/{owner}/{repo}/branches
|
233
432
|
#
|
@@ -235,18 +434,18 @@ module Gitee::Gitee4CLI::API
|
|
235
434
|
access_token = get_token
|
236
435
|
@params = {access_token:}
|
237
436
|
@path = sprintf "repos/%s/%s/branches", owner, repo
|
238
|
-
|
239
|
-
# TODO
|
437
|
+
make_api_request
|
438
|
+
# TODO post the request
|
240
439
|
end
|
241
440
|
|
242
|
-
# @
|
243
|
-
# Get a branch
|
441
|
+
# @todo
|
442
|
+
# Get a specific branch from a owner's repo
|
244
443
|
#
|
245
|
-
#
|
246
|
-
#
|
247
|
-
# @param
|
444
|
+
# @!macro param_owner
|
445
|
+
# @!macro param_repo
|
446
|
+
# @param [String] branch 分支名称
|
248
447
|
#
|
249
|
-
# @return [Result]
|
448
|
+
# @return [Result] JSON响应体
|
250
449
|
#
|
251
450
|
# @HTTP [GET] https://gitee.com/api/v5/repos/{owner}/{repo}/branches/{branch}
|
252
451
|
#
|
@@ -255,15 +454,15 @@ module Gitee::Gitee4CLI::API
|
|
255
454
|
@params = {access_token:}
|
256
455
|
@path = sprintf "repos/%s/%s/branches/%s", owner, repo, branch
|
257
456
|
@action = 'get'
|
258
|
-
|
457
|
+
make_api_request
|
259
458
|
end
|
260
459
|
|
261
|
-
# Delete a repo
|
460
|
+
# Delete a owner's repo
|
262
461
|
#
|
263
|
-
#
|
264
|
-
#
|
462
|
+
# @!macro param_owner
|
463
|
+
# @!macro param_repo
|
265
464
|
#
|
266
|
-
# @return [Result]
|
465
|
+
# @return [Result] JSON响应体
|
267
466
|
#
|
268
467
|
# @HTTP [DELETE] https://gitee.com/api/v5/repos/{owner}/{repo}
|
269
468
|
#
|
@@ -272,7 +471,7 @@ module Gitee::Gitee4CLI::API
|
|
272
471
|
@params = {access_token:}
|
273
472
|
@path = sprintf "repos/%s/%s", owner, repo
|
274
473
|
@action = 'delete'
|
275
|
-
|
474
|
+
make_api_request
|
276
475
|
if @status.code == HttpStatusCode::NoContent
|
277
476
|
Result[true, nil]
|
278
477
|
else
|
@@ -280,30 +479,30 @@ module Gitee::Gitee4CLI::API
|
|
280
479
|
end
|
281
480
|
end
|
282
481
|
|
283
|
-
# @
|
284
|
-
# Clear a repo
|
482
|
+
# @todo
|
483
|
+
# Clear a owner's repo
|
285
484
|
#
|
286
|
-
#
|
287
|
-
#
|
485
|
+
# @!macro param_owner
|
486
|
+
# @!macro param_repo
|
288
487
|
#
|
289
|
-
# @return
|
488
|
+
# @return [String] JSON响应体
|
290
489
|
#
|
291
|
-
# @HTTP
|
490
|
+
# @HTTP [PUT] https://gitee.com/api/v5/repos/{owner}/{repo}/clear
|
292
491
|
#
|
293
492
|
def self.clear(owner, repo)
|
294
493
|
access_token = get_token
|
295
494
|
@params = {access_token:}
|
296
495
|
@path = sprintf "repos/%s/%s/clear", owner, repo
|
297
496
|
@action = 'put'
|
298
|
-
|
299
|
-
# TODO put
|
497
|
+
make_api_request
|
498
|
+
# TODO: put
|
300
499
|
end
|
301
500
|
|
302
|
-
#
|
501
|
+
# Create a new repo for myself identified by access token
|
303
502
|
#
|
304
|
-
#
|
503
|
+
# @!macro param_repo
|
305
504
|
#
|
306
|
-
# @return [Result]
|
505
|
+
# @return [Result] JSON响应体
|
307
506
|
#
|
308
507
|
# @HTTP [POST] https://gitee.com/api/v5/user/repos
|
309
508
|
#
|
@@ -312,7 +511,7 @@ module Gitee::Gitee4CLI::API
|
|
312
511
|
@params = {access_token:, name: repo}
|
313
512
|
@path = "user/repos"
|
314
513
|
@action = 'post'
|
315
|
-
|
514
|
+
make_api_request
|
316
515
|
if @status.code == HttpStatusCode::Created
|
317
516
|
Result[true, JSON.parse(@body)]
|
318
517
|
else
|
@@ -320,12 +519,12 @@ module Gitee::Gitee4CLI::API
|
|
320
519
|
end
|
321
520
|
end
|
322
521
|
|
323
|
-
# Get the README from a repo
|
522
|
+
# Get the README from a owner's repo
|
324
523
|
#
|
325
|
-
#
|
326
|
-
#
|
524
|
+
# @!macro param_owner
|
525
|
+
# @!macro param_repo
|
327
526
|
#
|
328
|
-
# @return [Result]
|
527
|
+
# @return [Result] JSON响应体
|
329
528
|
#
|
330
529
|
# @HTTP [GET] https://gitee.com/api/v5/repos/{owner}/{repo}/readme
|
331
530
|
#
|
@@ -334,7 +533,7 @@ module Gitee::Gitee4CLI::API
|
|
334
533
|
@params = {access_token:}
|
335
534
|
@path = sprintf "repos/%s/%s/readme", owner, repo
|
336
535
|
@action = 'get'
|
337
|
-
|
536
|
+
make_api_request
|
338
537
|
if @status.code == HttpStatusCode::Ok
|
339
538
|
Result[true, JSON.parse(@body)]
|
340
539
|
else
|
@@ -342,21 +541,20 @@ module Gitee::Gitee4CLI::API
|
|
342
541
|
end
|
343
542
|
end
|
344
543
|
|
345
|
-
#
|
346
544
|
# List repos from a user
|
347
545
|
#
|
348
|
-
# @param
|
546
|
+
# @param [String] username 用户名
|
349
547
|
#
|
350
|
-
# @return [
|
548
|
+
# @return [Result] JSON响应体
|
351
549
|
#
|
352
|
-
# @HTTP
|
550
|
+
# @HTTP [GET] https://gitee.com/api/v5/users/{username}/repos
|
353
551
|
#
|
354
|
-
def self.list_for_user(
|
552
|
+
def self.list_for_user(username)
|
355
553
|
access_token = get_token
|
356
554
|
@params = {access_token:, per_page: 50} # default per_page set to 50 (max 100)
|
357
|
-
@path = sprintf "users/%s/repos",
|
555
|
+
@path = sprintf "users/%s/repos", username
|
358
556
|
@action = 'get'
|
359
|
-
|
557
|
+
make_api_request
|
360
558
|
if @status.code == HttpStatusCode::Ok
|
361
559
|
Result[true, JSON.parse(@body)]
|
362
560
|
else
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitee-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0.beta.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aoran Zeng
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '5.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: launchy
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.5'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.5'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: tty-markdown
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,9 +98,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
98
|
version: 3.1.0
|
85
99
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
|
-
- - "
|
101
|
+
- - ">"
|
88
102
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
103
|
+
version: 1.3.1
|
90
104
|
requirements: []
|
91
105
|
rubygems_version: 3.4.8
|
92
106
|
signing_key:
|