giterm 2.0.3 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/giterm +86 -26
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a01a43a0c33b199d4c4295839aeaa21accde4c8e9dee216c635ecc7835176e53
|
|
4
|
+
data.tar.gz: 1f0ac3d3d407e7e25e1e13513b67fff172b84d82d3ca15a70067941c4b685128
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5c421275ade0738dbe055be7e0b2581471610111d125dfee77e99fb8a6a711e8416f5cf2d225a7fda1b745ebf2c41dc0c23159d37f861d2fcd09f29f20e0f1da
|
|
7
|
+
data.tar.gz: 003f4737089d19deecbac244b25201ca5fcacb97642c64abdb0f100c9b97c3abbe6519dd201f4e15e9940e0448d02f075419085f6499a1d81661ed2054c1b128
|
data/giterm
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# Author: Geir Isene <g@isene.com> (adapted from RTFM)
|
|
8
8
|
# Github: https://github.com/isene/GiTerm
|
|
9
9
|
# License: Public domain
|
|
10
|
-
@version = '2.0.
|
|
10
|
+
@version = '2.0.4'
|
|
11
11
|
|
|
12
12
|
# SAVE & STORE TERMINAL {{{1
|
|
13
13
|
ORIG_STTY = `stty -g 2>/dev/null`.chomp rescue ''
|
|
@@ -911,7 +911,26 @@ def github_request_http(endpoint)
|
|
|
911
911
|
|
|
912
912
|
JSON.parse(body)
|
|
913
913
|
else
|
|
914
|
-
|
|
914
|
+
error_msg = case response.code
|
|
915
|
+
when '401'
|
|
916
|
+
'Authentication failed (token expired or invalid). Press T to update token.'
|
|
917
|
+
when '403'
|
|
918
|
+
remaining = response['X-RateLimit-Remaining']
|
|
919
|
+
if remaining == '0'
|
|
920
|
+
reset_time = response['X-RateLimit-Reset']
|
|
921
|
+
reset_in = reset_time ? ((reset_time.to_i - Time.now.to_i) / 60.0).ceil : '?'
|
|
922
|
+
"GitHub API rate limit exceeded. Resets in ~#{reset_in} minutes."
|
|
923
|
+
else
|
|
924
|
+
"Access forbidden (403). Check token permissions."
|
|
925
|
+
end
|
|
926
|
+
when '404'
|
|
927
|
+
'Resource not found (404). Repository may be private or deleted.'
|
|
928
|
+
when '429'
|
|
929
|
+
'Too many requests (429). Please wait a moment and retry.'
|
|
930
|
+
else
|
|
931
|
+
"GitHub API error: #{response.code} - #{response.message}"
|
|
932
|
+
end
|
|
933
|
+
{ error: error_msg }
|
|
915
934
|
end
|
|
916
935
|
end
|
|
917
936
|
rescue JSON::ParserError => e
|
|
@@ -931,33 +950,62 @@ end
|
|
|
931
950
|
|
|
932
951
|
def github_request_curl(endpoint)
|
|
933
952
|
begin
|
|
934
|
-
# Build curl command
|
|
953
|
+
# Build curl command with separate connect and total timeouts
|
|
935
954
|
url = "https://api.github.com#{endpoint}"
|
|
936
|
-
curl_cmd = "curl -s -
|
|
955
|
+
curl_cmd = "curl -s --connect-timeout 10 --max-time 20 " \
|
|
956
|
+
"-w '\\n%{http_code}' " \
|
|
937
957
|
"-H 'Authorization: token #{@github_token}' " \
|
|
938
958
|
"-H 'Accept: application/vnd.github.v3+json' " \
|
|
939
959
|
"-H 'User-Agent: GiTerm/1.0' " \
|
|
940
960
|
"'#{url}'"
|
|
941
|
-
|
|
961
|
+
|
|
942
962
|
# Debug: log the curl command (without showing full token)
|
|
943
963
|
debug_cmd = curl_cmd.sub(@github_token, "#{@github_token[0..10]}...")
|
|
944
964
|
log_debug("Executing curl: #{debug_cmd}")
|
|
945
|
-
|
|
965
|
+
|
|
946
966
|
# Capture both stdout and stderr for better debugging
|
|
947
|
-
|
|
967
|
+
raw_result = `#{curl_cmd} 2>&1`
|
|
948
968
|
exit_code = $?.exitstatus
|
|
949
|
-
|
|
950
|
-
if exit_code == 0
|
|
951
|
-
|
|
969
|
+
|
|
970
|
+
if exit_code == 0
|
|
971
|
+
# Extract HTTP status code from the last line (-w appends it)
|
|
972
|
+
lines = raw_result.rstrip.split("\n")
|
|
973
|
+
http_code = lines.last.strip
|
|
974
|
+
body = lines[0...-1].join("\n")
|
|
975
|
+
|
|
976
|
+
if http_code == '200' && !body.empty?
|
|
977
|
+
JSON.parse(body)
|
|
978
|
+
elsif body.empty?
|
|
979
|
+
{ error: 'Empty response body from GitHub API.' }
|
|
980
|
+
else
|
|
981
|
+
error_msg = case http_code
|
|
982
|
+
when '401'
|
|
983
|
+
'Authentication failed (token expired or invalid). Press T to update token.'
|
|
984
|
+
when '403'
|
|
985
|
+
parsed = JSON.parse(body) rescue {}
|
|
986
|
+
if parsed['message']&.include?('rate limit')
|
|
987
|
+
'GitHub API rate limit exceeded. Wait a few minutes and retry.'
|
|
988
|
+
else
|
|
989
|
+
"Access forbidden (403). Check token permissions."
|
|
990
|
+
end
|
|
991
|
+
when '404'
|
|
992
|
+
'Resource not found (404). Repository may be private or deleted.'
|
|
993
|
+
when '429'
|
|
994
|
+
'Too many requests (429). Please wait a moment and retry.'
|
|
995
|
+
else
|
|
996
|
+
"GitHub API error (HTTP #{http_code})."
|
|
997
|
+
end
|
|
998
|
+
{ error: error_msg }
|
|
999
|
+
end
|
|
952
1000
|
else
|
|
953
1001
|
error_msg = case exit_code
|
|
954
|
-
when
|
|
955
|
-
when
|
|
956
|
-
when
|
|
957
|
-
when
|
|
958
|
-
else "
|
|
1002
|
+
when 6 then 'Could not resolve host. Check network connection.'
|
|
1003
|
+
when 7 then 'Failed to connect to GitHub. Check network connection.'
|
|
1004
|
+
when 28 then 'Request timed out. GitHub may be slow or unreachable.'
|
|
1005
|
+
when 35 then 'SSL/TLS connection error.'
|
|
1006
|
+
else "Network error (curl exit code: #{exit_code})."
|
|
959
1007
|
end
|
|
960
|
-
{ error:
|
|
1008
|
+
{ error: error_msg }
|
|
961
1009
|
end
|
|
962
1010
|
rescue JSON::ParserError => e
|
|
963
1011
|
{ error: "Invalid JSON from curl: #{e.message}" }
|
|
@@ -1348,15 +1396,21 @@ def github_issues
|
|
|
1348
1396
|
return if @selected_repo.empty?
|
|
1349
1397
|
|
|
1350
1398
|
result = github_request("/repos/#{@selected_repo}/issues?state=open&per_page=50")
|
|
1351
|
-
|
|
1352
|
-
if result[:error]
|
|
1399
|
+
|
|
1400
|
+
if result.is_a?(Hash) && result[:error]
|
|
1353
1401
|
@p_left.say(result[:error].fg(196))
|
|
1402
|
+
@p_bottom.say('Failed to load issues.')
|
|
1354
1403
|
return
|
|
1355
1404
|
end
|
|
1356
|
-
|
|
1405
|
+
|
|
1406
|
+
unless result.is_a?(Array)
|
|
1407
|
+
@p_left.say('Unexpected response format from GitHub API.'.fg(196))
|
|
1408
|
+
return
|
|
1409
|
+
end
|
|
1410
|
+
|
|
1357
1411
|
result.each do |issue|
|
|
1358
1412
|
next if issue['pull_request'] # Skip PRs
|
|
1359
|
-
|
|
1413
|
+
|
|
1360
1414
|
@github_issues << {
|
|
1361
1415
|
number: issue['number'],
|
|
1362
1416
|
title: issue['title'],
|
|
@@ -1435,12 +1489,18 @@ def github_pull_requests
|
|
|
1435
1489
|
return if @selected_repo.empty?
|
|
1436
1490
|
|
|
1437
1491
|
result = github_request("/repos/#{@selected_repo}/pulls?state=open&per_page=50")
|
|
1438
|
-
|
|
1439
|
-
if result[:error]
|
|
1492
|
+
|
|
1493
|
+
if result.is_a?(Hash) && result[:error]
|
|
1440
1494
|
@p_left.say(result[:error].fg(196))
|
|
1495
|
+
@p_bottom.say('Failed to load pull requests.')
|
|
1441
1496
|
return
|
|
1442
1497
|
end
|
|
1443
|
-
|
|
1498
|
+
|
|
1499
|
+
unless result.is_a?(Array)
|
|
1500
|
+
@p_left.say('Unexpected response format from GitHub API.'.fg(196))
|
|
1501
|
+
return
|
|
1502
|
+
end
|
|
1503
|
+
|
|
1444
1504
|
result.each do |pr|
|
|
1445
1505
|
@github_prs << {
|
|
1446
1506
|
number: pr['number'],
|
|
@@ -1557,14 +1617,14 @@ def github_search_repositories
|
|
|
1557
1617
|
# Perform the search
|
|
1558
1618
|
result = github_request("/search/repositories?q=#{CGI.escape(query)}&sort=stars&order=desc&per_page=50")
|
|
1559
1619
|
|
|
1560
|
-
if result[:error]
|
|
1620
|
+
if result.is_a?(Hash) && result[:error]
|
|
1561
1621
|
@p_left.clear
|
|
1562
1622
|
@p_left.say("Search Error: #{result[:error]}".fg(196))
|
|
1563
1623
|
return
|
|
1564
1624
|
end
|
|
1565
|
-
|
|
1625
|
+
|
|
1566
1626
|
# Process search results
|
|
1567
|
-
if result['items'] && result['items'].any?
|
|
1627
|
+
if result.is_a?(Hash) && result['items'] && result['items'].any?
|
|
1568
1628
|
result['items'].each do |repo|
|
|
1569
1629
|
@github_search_results << {
|
|
1570
1630
|
id: repo['id'],
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: giterm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Geir Isene
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: "."
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-03-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rcurses
|
|
@@ -54,8 +54,8 @@ dependencies:
|
|
|
54
54
|
version: '13.0'
|
|
55
55
|
description: 'GiTerm is a powerful terminal interface for Git and GitHub, providing
|
|
56
56
|
an intuitive TUI for repository management, issue tracking, and pull request handling.
|
|
57
|
-
Version 2.0.
|
|
58
|
-
|
|
57
|
+
Version 2.0.4: Improved GitHub API error recovery with specific messages for auth,
|
|
58
|
+
rate-limit, and network failures.'
|
|
59
59
|
email:
|
|
60
60
|
- g@isene.com
|
|
61
61
|
executables:
|