Module: Atradio::Native

Defined in:
lib/atradio/native.rb

Class Method Summary collapse

Class Method Details

.archObject



32
33
34
35
36
37
38
39
# File 'lib/atradio/native.rb', line 32

def arch
  a = RbConfig::CONFIG["host_cpu"]
  case a
  when /x86_64|amd64/ then "x86_64"
  when /arm64|aarch64/ then "aarch64"
  else a
  end
end

.cache_dir(tag) ⇒ Object



57
58
59
60
# File 'lib/atradio/native.rb', line 57

def cache_dir(tag)
  base = ENV["XDG_CACHE_HOME"] || File.join(Dir.home, ".cache")
  File.join(base, "atradio", tag)
end

.download_verify(repo, tag, triple, sha, dest) ⇒ Object

Raises:



83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/atradio/native.rb', line 83

def download_verify(repo, tag, triple, sha, dest)
  url = "https://github.com/#{repo}/releases/download/#{tag}/libatradio_uniffi-#{triple}.#{ext}"
  body = fetch(url)
  got = Digest::SHA256.hexdigest(body)
  raise Error, "checksum mismatch for #{triple}: want #{sha}, got #{got}" unless got == sha

  FileUtils.mkdir_p(File.dirname(dest))
  tmp = "#{dest}.download"
  File.binwrite(tmp, body)
  File.chmod(0o755, tmp)
  File.rename(tmp, dest)
end

.extObject



24
25
26
27
28
29
30
# File 'lib/atradio/native.rb', line 24

def ext
  case RbConfig::CONFIG["host_os"]
  when /darwin/ then "dylib"
  when /mswin|mingw|cygwin/ then "dll"
  else "so"
  end
end

.fetch(url, limit = 5) ⇒ Object

Raises:



96
97
98
99
100
101
102
103
104
105
# File 'lib/atradio/native.rb', line 96

def fetch(url, limit = 5)
  raise Error, "too many redirects" if limit.zero?

  res = Net::HTTP.get_response(URI(url))
  case res
  when Net::HTTPSuccess then res.body
  when Net::HTTPRedirection then fetch(res["location"], limit - 1)
  else raise Error, "download failed (#{res.code}) for #{url}"
  end
end

.lib_dirObject



53
54
55
# File 'lib/atradio/native.rb', line 53

def lib_dir
  File.expand_path("..", __dir__) # sdk/ruby/lib
end

.manifestObject



62
63
64
# File 'lib/atradio/native.rb', line 62

def manifest
  JSON.parse(File.read(File.join(lib_dir, "manifest.json")))
end

.resolveObject

Absolute path to a loadable native library, fetching it if necessary.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/atradio/native.rb', line 67

def resolve
  local = File.join(lib_dir, "libatradio_uniffi.#{ext}")
  return local if File.exist?(local)

  m = manifest
  t = triple
  sha = m.dig("checksums", t) or
    raise Error, "no prebuilt native lib for #{t} (manifest has no checksum)"
  tag = m["tag"]
  dest = File.join(cache_dir(tag), "libatradio_uniffi-#{t}.#{ext}")
  return dest if File.exist?(dest) && Digest::SHA256.file(dest).hexdigest == sha

  download_verify(m["repo"], tag, t, sha, dest)
  dest
end

.tripleObject

Canonical target triple matching the release asset names.



42
43
44
45
46
47
48
49
50
51
# File 'lib/atradio/native.rb', line 42

def triple
  case RbConfig::CONFIG["host_os"]
  when /darwin/ then "#{arch}-apple-darwin"
  when /linux/ then "#{arch}-linux-gnu"
  when /freebsd/ then "#{arch}-unknown-freebsd"
  when /netbsd/ then "#{arch}-unknown-netbsd"
  when /openbsd/ then "#{arch}-unknown-openbsd"
  else raise Error, "unsupported platform: #{RbConfig::CONFIG["host_os"]}"
  end
end