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

Class Method Details

.archive_extObject



78
79
80
# File 'lib/archgate/shim.rb', line 78

def archive_ext
  windows? ? "zip" : "tar.gz"
end

.binary_nameObject



74
75
76
# File 'lib/archgate/shim.rb', line 74

def binary_name
  windows? ? "archgate.exe" : "archgate"
end

.binary_pathObject



86
87
88
# File 'lib/archgate/shim.rb', line 86

def binary_path
  File.join(cache_dir, binary_name)
end

.cache_dirObject



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_artifactObject



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_cpuObject



56
57
58
# File 'lib/archgate/shim.rb', line 56

def host_cpu
  RbConfig::CONFIG["host_cpu"]
end

.host_osObject

– 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.message}"
      $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

Returns:

  • (Boolean)


70
71
72
# File 'lib/archgate/shim.rb', line 70

def windows?
  host_os.match?(/mswin|mingw|cygwin/i)
end