Class: FhirPackagesManager::Registry
- Inherits:
-
Object
- Object
- FhirPackagesManager::Registry
- Defined in:
- lib/fhir_packages_manager/registry.rb,
sig/fhir_packages_manager/registry.rbs
Overview
Client for a single FHIR package registry (e.g. https://packages.fhir.org
or https://packages.simplifier.net). Both implement the same npm-style
registry API: GET /<package> returns metadata with a "versions" map and
"dist-tags", and GET /<package>/<version> streams the .tgz tarball.
Constant Summary collapse
- MAX_REDIRECTS =
Returns maximum HTTP redirects followed before raising HttpError.
5
Instance Attribute Summary collapse
-
#base_url ⇒ String
readonly
The registry's base URL, with any trailing slash stripped.
Instance Method Summary collapse
-
#download(name, version, destination_path) ⇒ String
Downloads the package tarball to destination_path, creating parent directories as needed.
- #download_file(url, destination_path) ⇒ void
- #follow(response, url, read_timeout:, redirects_left:) {|arg0, arg1| ... } ⇒ Net::HTTPResponse
- #get(url) ⇒ String
-
#initialize(base_url) ⇒ Registry
constructor
A new instance of Registry.
-
#metadata(name) ⇒ Hash
Fetches (and caches) the full registry metadata document for a package name.
-
#request(url, read_timeout:, redirects_left: MAX_REDIRECTS) {|arg0, arg1| ... } ⇒ Net::HTTPResponse
Issues a GET, yielding (http, uri) to perform it, and follows any redirect response by re-issuing the same block against the new location.
- #resolve_version(meta, version) ⇒ String?
- #save_body(response, destination_path) ⇒ void
-
#tarball_url(name, version) ⇒ String
The tarball's download URL.
-
#version?(name, version = nil) ⇒ String?
The resolved version string if it exists on this registry, or nil if the package or version doesn't exist (never raises).
-
#versions(name) ⇒ Array<String>
Every version published for this package on this registry.
Constructor Details
#initialize(base_url) ⇒ Registry
Returns a new instance of Registry.
21 22 23 24 |
# File 'lib/fhir_packages_manager/registry.rb', line 21 def initialize(base_url) @base_url = base_url.to_s.chomp('/') @metadata_cache = {} # : Hash[String, Hash[untyped, untyped]] end |
Instance Attribute Details
#base_url ⇒ String (readonly)
Returns the registry's base URL, with any trailing slash stripped.
18 19 20 |
# File 'lib/fhir_packages_manager/registry.rb', line 18 def base_url @base_url end |
Instance Method Details
#download(name, version, destination_path) ⇒ String
Downloads the package tarball to destination_path, creating parent directories as needed.
80 81 82 83 84 |
# File 'lib/fhir_packages_manager/registry.rb', line 80 def download(name, version, destination_path) FileUtils.mkdir_p(File.dirname(destination_path)) download_file(tarball_url(name, version), destination_path) destination_path end |
#download_file(url, destination_path) ⇒ void
This method returns an undefined value.
98 99 100 101 102 103 104 |
# File 'lib/fhir_packages_manager/registry.rb', line 98 def download_file(url, destination_path) request(url, read_timeout: 120) do |http, uri| http.request_get(uri.request_uri) do |response| save_body(response, destination_path) if response.is_a?(Net::HTTPSuccess) end end end |
#follow(response, url, read_timeout:, redirects_left:) {|arg0, arg1| ... } ⇒ Net::HTTPResponse
130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/fhir_packages_manager/registry.rb', line 130 def follow(response, url, read_timeout:, redirects_left:, &) case response when Net::HTTPSuccess response when Net::HTTPRedirection location = response['location'] or raise HttpError.new("Redirect from #{url} has no Location header", nil) request(location, read_timeout:, redirects_left: redirects_left - 1, &) else status = response.code.to_i raise HttpError.new("GET #{url} failed: #{status} #{response.}", status) end end |
#get(url) ⇒ String
94 95 96 |
# File 'lib/fhir_packages_manager/registry.rb', line 94 def get(url) request(url, read_timeout: 30) { |http, uri| http.get(uri.request_uri, 'Accept' => 'application/json') }.body end |
#metadata(name) ⇒ Hash
Fetches (and caches) the full registry metadata document for a package name.
32 33 34 35 36 37 38 |
# File 'lib/fhir_packages_manager/registry.rb', line 32 def (name) @metadata_cache[name] ||= JSON.parse(get("#{base_url}/#{name}")) rescue HttpError => e raise PackageNotFoundError, "#{name} not found on #{base_url}" if e.status == 404 raise end |
#request(url, read_timeout:, redirects_left: MAX_REDIRECTS) {|arg0, arg1| ... } ⇒ Net::HTTPResponse
Issues a GET, yielding (http, uri) to perform it, and follows any redirect response by re-issuing the same block against the new location.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/fhir_packages_manager/registry.rb', line 114 def request(url, read_timeout:, redirects_left: MAX_REDIRECTS, &) raise HttpError.new("Too many redirects for #{url}", nil) if redirects_left <= 0 uri = URI(url) raise HttpError.new("Unsupported URL scheme: #{url}", nil) unless uri.is_a?(URI::HTTP) host = uri.host or raise HttpError.new("URL has no host: #{url}", nil) response = Net::HTTP.start(host, uri.port, use_ssl: uri.scheme == 'https', open_timeout: 10, read_timeout: read_timeout) do |http| yield http, uri end follow(response, url, read_timeout:, redirects_left:, &) end |
#resolve_version(meta, version) ⇒ String?
88 89 90 91 92 |
# File 'lib/fhir_packages_manager/registry.rb', line 88 def resolve_version(, version) return .dig('dist-tags', 'latest') if version.nil? || version == 'latest' version end |
#save_body(response, destination_path) ⇒ void
This method returns an undefined value.
106 107 108 109 110 |
# File 'lib/fhir_packages_manager/registry.rb', line 106 def save_body(response, destination_path) File.open(destination_path, 'wb') do |file| response.read_body { |chunk| file.write(chunk) } end end |
#tarball_url(name, version) ⇒ String
Returns the tarball's download URL.
64 65 66 67 68 69 70 |
# File 'lib/fhir_packages_manager/registry.rb', line 64 def tarball_url(name, version) = (name) entry = .dig('versions', version) raise PackageNotFoundError, "#{name}@#{version} not found on #{base_url}" unless entry entry.dig('dist', 'tarball') || "#{base_url}/#{name}/#{version}" end |
#version?(name, version = nil) ⇒ String?
Returns the resolved version string if it exists on this registry, or nil if the package or version doesn't exist (never raises).
44 45 46 47 48 49 50 |
# File 'lib/fhir_packages_manager/registry.rb', line 44 def version?(name, version = nil) = (name) resolved = resolve_version(, version) resolved && ['versions']&.key?(resolved) ? resolved : nil rescue PackageNotFoundError nil end |
#versions(name) ⇒ Array<String>
Returns every version published for this package on this registry.
56 57 58 |
# File 'lib/fhir_packages_manager/registry.rb', line 56 def versions(name) (name)['versions']&.keys || [] end |