class Capsium::Package::Store
A package store directory (ARCHITECTURE.md section 4a): a directory of “<name>-<version>.cap” files plus an optional index.json mapping dependency GUID -> file name. Dependencies resolve to the newest version satisfying their semver range; an index.json entry pins the GUID to a specific file (still range-checked).
Constants
- CAP_GLOB
- CatalogEntry
-
One store .cap with its identity per its metadata.json.
- INDEX_FILE
Attributes
String
Public Class Methods
() → Store?
Source
# File lib/capsium/package/store.rb, line 25 def self.default dir = ENV.fetch("CAPSIUM_STORE", nil) dir.nil? || dir.empty? ? nil : new(dir) end
The store configured via the CAPSIUM_STORE environment variable, or nil when unset.
(String dir) → void
Source
# File lib/capsium/package/store.rb, line 30 def initialize(dir) unless File.directory?(dir) raise DependencyError, "Package store directory not found: #{dir}" end @dir = dir end
Public Instance Methods
() → Array[CatalogEntry]
Source
# File lib/capsium/package/store.rb, line 61 def catalog @catalog ||= Dir.glob(File.join(@dir, CAP_GLOB)).map do |path| catalog_entry(path) end end
Every .cap in the store with its metadata identity (memoized).
(String guid, String range_string) → String
Source
# File lib/capsium/package/store.rb, line 40 def find(guid, range_string) range = VersionRange.parse(range_string) indexed = indexed_path(guid) return indexed_satisfying(indexed, guid, range_string, range) if indexed candidates = catalog.select { |entry| entry.guid == guid } if candidates.empty? raise DependencyNotFoundError, "no package for dependency #{guid} in store #{@dir}" end satisfying = candidates.select { |entry| range.satisfied_by?(entry.version) } return satisfying.max_by(&:version).path unless satisfying.empty? versions = candidates.map { |entry| entry.version.to_s }.sort.join(", ") raise UnsatisfiableDependencyError, "no version of #{guid} satisfies '#{range_string}' " \ "(store has: #{versions})" end
The newest .cap providing the dependency GUID whose version satisfies the range string.
(String source_path, guid: String guid, file_name: String file_name) → String
Source
# File lib/capsium/package/store.rb, line 72 def install(source_path, guid:, file_name:) destination = File.join(@dir, file_name) tmp = "#{destination}.tmp-#{Process.pid}" FileUtils.cp(source_path, tmp) File.rename(tmp, destination) record_index(guid, file_name) destination end
Installs the .cap at source_path into the store as file_name (conventionally “<name>-<version>.cap”), records guid -> file_name in index.json (atomically, tmp + rename) and returns the installed path. Used by registry installs (Capsium::Registry#install).