Module: Archgate::Shim
- Defined in:
- lib/archgate/shim.rb
Overview
Thin shim that downloads the archgate binary from GitHub Releases on first invocation and then executes it. Zero runtime dependencies – stdlib only.
Constant Summary collapse
- BASE_URL =
"https://github.com/archgate/cli/releases/download"- PLATFORM_MAP =
Platform mapping: [os_pattern, arch_pattern] => artifact name
[ [/darwin|mac/i, /arm64|aarch64/i, "archgate-darwin-arm64"], [/linux/i, /x86_64|x64|amd64/i, "archgate-linux-x64"], [/mswin|mingw|cygwin/i, /x86_64|x64|amd64/i, "archgate-win32-x64"] ].freeze
Class Method Summary collapse
- .archive_ext ⇒ Object
- .binary_name ⇒ Object
- .binary_path ⇒ Object
- .cache_dir ⇒ Object
- .checksum_url(artifact, ext) ⇒ Object
- .detect_artifact ⇒ Object
-
.download_url(artifact, ext) ⇒ Object
– Download / verification ———————————————.
- .fetch(url, limit: 10) ⇒ Object
- .host_cpu ⇒ Object
-
.host_os ⇒ Object
– Platform detection ————————————————–.
- .run(args) ⇒ Object
- .verify_checksum(archive_data, artifact, ext) ⇒ Object
- .windows? ⇒ Boolean
Class Method Details
.archive_ext ⇒ Object
78 79 80 |
# File 'lib/archgate/shim.rb', line 78 def archive_ext windows? ? "zip" : "tar.gz" end |
.binary_name ⇒ Object
74 75 76 |
# File 'lib/archgate/shim.rb', line 74 def binary_name windows? ? "archgate.exe" : "archgate" end |
.binary_path ⇒ Object
86 87 88 |
# File 'lib/archgate/shim.rb', line 86 def binary_path File.join(cache_dir, binary_name) end |
.cache_dir ⇒ Object
82 83 84 |
# File 'lib/archgate/shim.rb', line 82 def cache_dir File.join(Dir.home, ".archgate", "bin") end |
.checksum_url(artifact, ext) ⇒ Object
96 97 98 |
# File 'lib/archgate/shim.rb', line 96 def checksum_url(artifact, ext) "#{download_url(artifact, ext)}.sha256" end |
.detect_artifact ⇒ Object
60 61 62 63 64 65 66 67 68 |
# File 'lib/archgate/shim.rb', line 60 def detect_artifact PLATFORM_MAP.each do |os_pat, arch_pat, artifact| return artifact if host_os.match?(os_pat) && host_cpu.match?(arch_pat) end $stderr.puts "archgate: Unsupported platform: #{host_os}/#{host_cpu}" $stderr.puts "archgate supports darwin/arm64, linux/x64, and win32/x64." exit 2 end |
.download_url(artifact, ext) ⇒ Object
– Download / verification ———————————————
92 93 94 |
# File 'lib/archgate/shim.rb', line 92 def download_url(artifact, ext) "#{BASE_URL}/v#{VERSION}/#{artifact}.#{ext}" end |
.fetch(url, limit: 10) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/archgate/shim.rb', line 100 def fetch(url, limit: 10) raise "too many HTTP redirects" if limit <= 0 uri = URI.parse(url) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = (uri.scheme == "https") request = Net::HTTP::Get.new(uri) request["User-Agent"] = "archgate-cli-ruby" response = http.request(request) case response when Net::HTTPSuccess response.body when Net::HTTPRedirection fetch(response["location"], limit: limit - 1) else raise "GET #{url} returned status #{response.code}" end end |
.host_cpu ⇒ Object
56 57 58 |
# File 'lib/archgate/shim.rb', line 56 def host_cpu RbConfig::CONFIG["host_cpu"] end |
.host_os ⇒ Object
– Platform detection ————————————————–
52 53 54 |
# File 'lib/archgate/shim.rb', line 52 def host_os RbConfig::CONFIG["host_os"] end |
.run(args) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/archgate/shim.rb', line 29 def run(args) binary = binary_path unless File.exist?(binary) begin download_binary rescue StandardError => e $stderr.puts "archgate: failed to download binary: #{e.}" $stderr.puts "Visit https://cli.archgate.dev/getting-started/installation/ for alternative install methods." exit 2 end end if windows? system(binary, *args) exit($?.exitstatus || 1) else Kernel.exec(binary, *args) end end |
.verify_checksum(archive_data, artifact, ext) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/archgate/shim.rb', line 122 def verify_checksum(archive_data, artifact, ext) checksum_data = begin fetch(checksum_url(artifact, ext)) rescue StandardError $stderr.puts "archgate: warning: checksum file not available, skipping verification" return end expected = checksum_data.strip.split(/\s+/).first actual = Digest::SHA256.hexdigest(archive_data) return if expected == actual raise "checksum verification failed for v#{VERSION} (expected #{expected}, got #{actual})" end |
.windows? ⇒ Boolean
70 71 72 |
# File 'lib/archgate/shim.rb', line 70 def windows? host_os.match?(/mswin|mingw|cygwin/i) end |