class Manifest
Records the content and import mappings of a static package projection.
Definitions
def self.build(base:, imports:, packages:)
Build a deterministic manifest.
Signature
-
parameter
baseString The public URL prefix for static packages.
-
parameter
importsHash(String, String) The import-map entries.
-
parameter
packagesHash(String, Hash) The installed package metadata.
-
returns
Manifest The generated manifest.
Implementation
def self.build(base:, imports:, packages:)
data = {
"format" => 1,
"base" => base,
"imports" => imports.sort.to_h,
"packages" => packages.sort.to_h,
}
data["digest"] = Digest::SHA256.hexdigest(JSON.generate(data))
new(data)
end
def self.load(root)
Load a manifest from a static output directory.
Signature
-
parameter
rootString | Pathname The static output directory.
-
returns
Manifest The loaded manifest.
-
raises
CheckError If the manifest is missing or malformed.
Implementation
def self.load(root)
path = Pathname.new(root) + FILENAME
new(JSON.parse(path.read))
rescue Errno::ENOENT
raise CheckError, "Static package manifest does not exist at #{path}!"
rescue JSON::ParserError => error
raise CheckError, "Could not parse #{path}: #{error.message}"
end
def initialize(data)
Initialize a manifest with its serialized data.
Signature
-
parameter
dataHash The manifest data.
Implementation
def initialize(data)
@data = data
end
attr :data
Signature
-
attribute
Hash The serialized manifest data.
def write(root)
Write the manifest into a static output directory.
Signature
-
parameter
rootString | Pathname The static output directory.
-
returns
Integer The number of bytes written.
Implementation
def write(root)
path = Pathname.new(root) + FILENAME
path.write(JSON.pretty_generate(@data) + "\n")
end
def import_map
Extract the browser import map.
Signature
-
returns
Hash An import-map object containing the configured imports.
Implementation
def import_map
{"imports" => @data.fetch("imports", {})}
end
def valid_tree?(root)
Check whether every manifested file exists with the expected content.
Signature
-
parameter
rootString | Pathname The static output directory.
-
returns
Boolean Whether the directory exactly matches the manifest.
Implementation
def valid_tree?(root)
root = Pathname.new(root)
expected = []
@data.fetch("packages").each do |name, package|
package.fetch("files").each do |relative_path, digest|
path = root + name + relative_path
expected << path.relative_path_from(root).to_s
return false unless path.file?
return false unless Digest::SHA256.file(path).hexdigest == digest
end
end
actual = root.glob("**/*", File::FNM_DOTMATCH).select(&:file?).map do |path|
path.relative_path_from(root).to_s
end
actual.delete(FILENAME)
actual.sort == expected.sort
end