Class: FhirPackagesManager::Manager

Inherits:
Object
  • Object
show all
Defined in:
lib/fhir_packages_manager/manager.rb,
sig/fhir_packages_manager/manager.rbs

Overview

Orchestrates checking availability across a set of registries, honoring an ignore list, and downloading tarballs into a destination folder.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(registries:, destination:, ignore_list: nil) ⇒ Manager

Returns a new instance of Manager.

Parameters:

  • registries (Array<String, Registry>)

    one or more registry base URLs and/or Registry instances, checked in the order given

  • destination (String)

    folder downloaded tarballs are written into

  • ignore_list (IgnoreList, nil) (defaults to: nil)

    packages/versions to skip in #fetch

  • registries: (Array[String | Registry])
  • destination: (String)
  • ignore_list: (IgnoreList, nil) (defaults to: nil)

Raises:

  • (ArgumentError)

    if registries is nil or empty



21
22
23
24
25
26
27
# File 'lib/fhir_packages_manager/manager.rb', line 21

def initialize(registries:, destination:, ignore_list: nil)
  raise ArgumentError, 'at least one registry is required' if registries.nil? || registries.empty?

  @registries = registries.map { |entry| entry.is_a?(Registry) ? entry : Registry.new(entry) }
  @destination = destination.to_s
  @ignore_list = ignore_list
end

Instance Attribute Details

#destinationString (readonly)

Returns the folder packages are downloaded into.

Returns:

  • (String)

    the folder packages are downloaded into



12
13
14
# File 'lib/fhir_packages_manager/manager.rb', line 12

def destination
  @destination
end

#ignore_listIgnoreList? (readonly)

Returns packages/versions skipped by #fetch.

Returns:



14
15
16
# File 'lib/fhir_packages_manager/manager.rb', line 14

def ignore_list
  @ignore_list
end

#registriesArray<Registry> (readonly)

Returns registries checked, in the order given to #initialize.

Returns:



10
11
12
# File 'lib/fhir_packages_manager/manager.rb', line 10

def registries
  @registries
end

Instance Method Details

#available?(name, version = nil) ⇒ Boolean

Returns true if any configured registry has this package/version.

Parameters:

  • name (String)

    the package name

  • version (String, nil) (defaults to: nil)

    a specific version, or nil/"latest" for the newest

Returns:

  • (Boolean)

    true if any configured registry has this package/version



32
33
34
# File 'lib/fhir_packages_manager/manager.rb', line 32

def available?(name, version = nil)
  !find_registry(name, version).nil?
end

#available_versions(registry, name) ⇒ Array[String]

Parameters:

Returns:

  • (Array[String])


114
115
116
# File 'lib/fhir_packages_manager/manager.rb', line 114

def available_versions(registry, name)
  raw_versions(registry, name).reject { |version| ignored?(Package.new(name, version)) }
end

#candidate_versions(name) ⇒ Array[String]

Parameters:

  • name (String)

Returns:

  • (Array[String])


124
125
126
# File 'lib/fhir_packages_manager/manager.rb', line 124

def candidate_versions(name)
  registries.flat_map { |registry| raw_versions(registry, name) }.uniq
end

#download_path(package) ⇒ String

Parameters:

Returns:

  • (String)


135
136
137
# File 'lib/fhir_packages_manager/manager.rb', line 135

def download_path(package)
  File.join(destination, "#{package.name}-#{package.version}.tgz")
end

#download_result(package, found) ⇒ FetchResult

Parameters:

Returns:



139
140
141
142
143
144
145
146
# File 'lib/fhir_packages_manager/manager.rb', line 139

def download_result(package, found)
  registry, resolved_version = found
  name = package.name
  resolved_package = Package.new(name, resolved_version)
  target = download_path(resolved_package)
  registry.download(name, resolved_version, target)
  FetchResult.new(package: resolved_package, status: :downloaded, registry: registry.base_url, path: target)
end

#fetch(package) ⇒ FetchResult

Fetches a single package. Skips it if it's on the ignore list, otherwise downloads its tarball into #destination.

Parameters:

  • package (String, Package)

    a "name@version" string, a bare name (latest), or a Package

Returns:



53
54
55
# File 'lib/fhir_packages_manager/manager.rb', line 53

def fetch(package)
  fetch_package(Package.parse(package))
end

#fetch_all(packages) ⇒ Array<FetchResult>

Returns one result per package, in the same order.

Parameters:

Returns:

  • (Array<FetchResult>)

    one result per package, in the same order



59
60
61
# File 'lib/fhir_packages_manager/manager.rb', line 59

def fetch_all(packages)
  packages.map { |package| fetch(package) }
end

#fetch_package(package) ⇒ FetchResult

Parameters:

Returns:



99
100
101
102
103
104
105
106
107
108
# File 'lib/fhir_packages_manager/manager.rb', line 99

def fetch_package(package)
  return FetchResult.new(package: package, status: :ignored) if ignored?(package)

  found = find_registry(package.name, package.version)
  return FetchResult.new(package: package, status: :not_found) unless found

  download_result(package, found)
rescue HttpError => e
  FetchResult.new(package: package, status: :error, error: e.message)
end

#find_registry(name, version = nil) ⇒ Array(Registry, String)?

Returns the first registry that has this package/version, paired with the resolved version string; nil if none of them do.

Parameters:

  • name (String)

    the package name

  • version (String, nil) (defaults to: nil)

    a specific version, or nil/"latest" for the newest

Returns:

  • (Array(Registry, String), nil)

    the first registry that has this package/version, paired with the resolved version string; nil if none of them do



40
41
42
43
44
45
46
# File 'lib/fhir_packages_manager/manager.rb', line 40

def find_registry(name, version = nil)
  registries.each do |registry|
    resolved = registry.version?(name, version)
    return [registry, resolved] if resolved
  end
  nil
end

#ignored?(package) ⇒ Boolean

Parameters:

Returns:

  • (Boolean)


110
111
112
# File 'lib/fhir_packages_manager/manager.rb', line 110

def ignored?(package)
  !!ignore_list&.ignored?(package.name, package.version)
end

#list_versions(name) ⇒ Hash{String => Array<String>}

Lists every version of a package published across all configured registries, skipping registries that don't have it at all and filtering out any ignored versions.

Parameters:

  • name (String)

    the package name

Returns:

  • (Hash{String => Array<String>})

    versions, keyed by registry base_url, for registries that have at least one non-ignored version; empty if the whole package is ignored or no registry has it

Raises:

  • (HttpError)

    if a registry that does have the package fails for another reason (mirrors #find_registry/Registry#version?, which likewise only treat "not found" as an expected, non-raising outcome)



73
74
75
76
77
78
79
80
81
# File 'lib/fhir_packages_manager/manager.rb', line 73

def list_versions(name)
  result = {} # : Hash[String, Array[String]]
  return result if ignored?(Package.new(name, nil))

  registries.each_with_object(result) do |registry, found|
    versions = available_versions(registry, name)
    found[registry.base_url] = versions unless versions.empty?
  end
end

#raw_versions(registry, name) ⇒ Array[String]

Parameters:

Returns:

  • (Array[String])


118
119
120
121
122
# File 'lib/fhir_packages_manager/manager.rb', line 118

def raw_versions(registry, name)
  registry.versions(name)
rescue PackageNotFoundError
  []
end

#sync(name) ⇒ Array<FetchResult>

Downloads every non-ignored version of a package that isn't already present in #destination (as name-version.tgz, the same convention #fetch downloads use). A whole-package ignore skips it entirely, without querying any registry; an individual ignored version instead surfaces as a normal :ignored FetchResult, same as #fetch.

Parameters:

  • name (String)

    the package name

Returns:

  • (Array<FetchResult>)

    one result per version considered, across all registries



90
91
92
93
94
95
# File 'lib/fhir_packages_manager/manager.rb', line 90

def sync(name)
  whole_package = Package.new(name, nil)
  return [FetchResult.new(package: whole_package, status: :ignored)] if ignored?(whole_package)

  candidate_versions(name).map { |version| sync_version(Package.new(name, version)) }
end

#sync_version(package) ⇒ FetchResult

Parameters:

Returns:



128
129
130
131
132
133
# File 'lib/fhir_packages_manager/manager.rb', line 128

def sync_version(package)
  existing_path = download_path(package)
  return FetchResult.new(package: package, status: :skipped, path: existing_path) if File.exist?(existing_path)

  fetch(package)
end