captive-stack-detector 0.12.4 → 0.12.5
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e5c9cf6e0559903b9b472715ed1d425903be96cdf7ca09c4689a66f63df7b19f
|
|
4
|
+
data.tar.gz: 7146a542cf6d2887063172c47a0d8f85251d3e7e02062969c8ee04882c321398
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d2162dfa8b2aa58308fb3523677fba79ffba3cd7abb7fa980bd2466408bc8347519845ec93bb83b8d751b308e504488c4f2edc56a2147132634ef288de5e78b1
|
|
7
|
+
data.tar.gz: 65b1daea44aa2172b74e215d3d6fd55b87e94ae6dc5115657605dee8ee880dbc5e4f0b2f04db139348cab9c34883a33d07a131e32fe5377db6256368531de625
|
|
@@ -5,9 +5,14 @@ require "uri"
|
|
|
5
5
|
require "base64"
|
|
6
6
|
require "json"
|
|
7
7
|
require_relative "github_tree"
|
|
8
|
+
require_relative "types"
|
|
9
|
+
require_relative "github_response"
|
|
8
10
|
|
|
9
11
|
module CaptiveStackDetector
|
|
10
12
|
class GithubApiClient
|
|
13
|
+
# Un corps illisible (JSON invalide ou sans le champ attendu) vaut une absence.
|
|
14
|
+
UNREADABLE = [ JSON::ParserError, NoMethodError, TypeError ].freeze
|
|
15
|
+
|
|
11
16
|
def initialize(token, repo)
|
|
12
17
|
@token = token
|
|
13
18
|
@repo = repo
|
|
@@ -18,7 +23,7 @@ module CaptiveStackDetector
|
|
|
18
23
|
return nil unless body
|
|
19
24
|
|
|
20
25
|
Base64.decode64(JSON.parse(body)["content"]).force_encoding("utf-8")
|
|
21
|
-
rescue
|
|
26
|
+
rescue *UNREADABLE
|
|
22
27
|
nil
|
|
23
28
|
end
|
|
24
29
|
|
|
@@ -27,7 +32,7 @@ module CaptiveStackDetector
|
|
|
27
32
|
return [] unless body
|
|
28
33
|
|
|
29
34
|
GithubTree.new(body).files_in(dir)
|
|
30
|
-
rescue
|
|
35
|
+
rescue *UNREADABLE
|
|
31
36
|
[]
|
|
32
37
|
end
|
|
33
38
|
|
|
@@ -35,9 +40,10 @@ module CaptiveStackDetector
|
|
|
35
40
|
|
|
36
41
|
def get(path)
|
|
37
42
|
uri = URI("https://api.github.com/repos/#{@repo}/#{path}")
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
GithubResponse.body(Net::HTTP.get_response(uri, "Authorization" => "Bearer #{@token}",
|
|
44
|
+
"Accept" => "application/vnd.github+json"))
|
|
45
|
+
rescue SystemCallError, IOError, SocketError, Timeout::Error, OpenSSL::SSL::SSLError => e
|
|
46
|
+
raise SourceUnavailable.new(:network, detail: e.message)
|
|
41
47
|
end
|
|
42
48
|
end
|
|
43
49
|
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "net/http"
|
|
4
|
+
require_relative "types"
|
|
5
|
+
|
|
6
|
+
module CaptiveStackDetector
|
|
7
|
+
# Ce que veut dire une réponse de l'API GitHub : un corps, une absence, ou un refus nommé.
|
|
8
|
+
# Change avec la façon dont GitHub signale ses erreurs, pas avec ce que l'on y lit.
|
|
9
|
+
module GithubResponse
|
|
10
|
+
# 404 : fichier absent ; 409 : dépôt vide. Tout autre échec vient de GitHub, pas du dépôt.
|
|
11
|
+
ABSENT = [ "404", "409" ].freeze
|
|
12
|
+
REFUSALS = { "401" => :unauthorized, "429" => :rate_limited }.freeze
|
|
13
|
+
|
|
14
|
+
def self.body(res)
|
|
15
|
+
return res.body if res.is_a?(Net::HTTPSuccess)
|
|
16
|
+
return nil if ABSENT.include?(res.code)
|
|
17
|
+
|
|
18
|
+
raise SourceUnavailable.new(refusal_kind(res), status: res.code.to_i)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# GitHub signale un quota épuisé par un 403 ou un 429, avec x-ratelimit-remaining à 0.
|
|
22
|
+
def self.refusal_kind(res)
|
|
23
|
+
return :rate_limited if res["x-ratelimit-remaining"] == "0"
|
|
24
|
+
|
|
25
|
+
REFUSALS.fetch(res.code) { res.is_a?(Net::HTTPServerError) ? :server_error : :forbidden }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -26,4 +26,17 @@ module CaptiveStackDetector
|
|
|
26
26
|
super(reason&.to_s || "unsupported stack")
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
|
+
|
|
30
|
+
# GitHub n'a pas laissé lire le dépôt, ce qui ne dit rien de sa stack. `kind` dit pourquoi,
|
|
31
|
+
# pour que l'appelant l'explique : :unauthorized (jeton refusé), :rate_limited (quota épuisé),
|
|
32
|
+
# :forbidden (accès refusé), :server_error (panne GitHub), :network (pas de réponse).
|
|
33
|
+
class SourceUnavailable < StandardError
|
|
34
|
+
attr_reader :kind, :status
|
|
35
|
+
|
|
36
|
+
def initialize(kind = :network, status: nil, detail: nil)
|
|
37
|
+
@kind = kind
|
|
38
|
+
@status = status
|
|
39
|
+
super(detail || "GitHub illisible : #{kind}#{" (#{status})" if status}")
|
|
40
|
+
end
|
|
41
|
+
end
|
|
29
42
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: captive-stack-detector
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.12.
|
|
4
|
+
version: 0.12.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Captive Studio
|
|
@@ -29,6 +29,7 @@ files:
|
|
|
29
29
|
- lib/captive_stack_detector/gem_package_map.rb
|
|
30
30
|
- lib/captive_stack_detector/gemfile_analyzer.rb
|
|
31
31
|
- lib/captive_stack_detector/github_api_client.rb
|
|
32
|
+
- lib/captive_stack_detector/github_response.rb
|
|
32
33
|
- lib/captive_stack_detector/github_tree.rb
|
|
33
34
|
- lib/captive_stack_detector/js_env_detector.rb
|
|
34
35
|
- lib/captive_stack_detector/js_env_files.rb
|