class Merritt::Manifest

A Merritt manifest file

Constants

CHECKM_0_7

Checkm 0.7 conformance level

COLSEP

checkm column separator

The copyright notice for this gem

NAME

The name of this gem

PROFILE_BASE_URI

Base for all recognized profile URIs

VERSION

The version of this gem

Attributes

conformance[R]

@return [String] the conformance level

entries[R]

@return [Array<Hash<String, Object>>] the entries

fields[R]

@return [Array<String>] the field names, in the form prefix:fieldname

prefixes[R]

@return [Hash{Symbol => URI}] a map from namespace prefixes to their URIs

profile[R]

@return [URI] the profile URI

Public Class Methods

new(conformance: CHECKM_0_7, profile:, prefixes: {}, fields: [], entries: []) click to toggle source

Creates a new manifest. Note that the prefix, field, and entry arrays are copied on initialization, as are the individual entry hashes.

@param conformance [String] the conformance level. Defaults to {CHECKM_0_7}. @param profile [URI, String] the profile URI. Must begin with @param prefixes [Hash{String,Symbol => URI, String}] a map from namespace prefixes to their URIs @param fields Array<String> a list of field names, in the form prefix:fieldname @param entries [Array<Hash<String, Object><] A list of entries, each of which is a hash keyed by

a prefixed fieldname defined in `fields`. Nil values are allowed.

@raise [ArgumentError] if `profile` does not begin with {PROFILE_BASE_URI} @raise [ArgumentError] if `fields` cannot be parsed as prefix:fieldname, or if one or more prefixes

is not mapped to a URI in `prefixes`

@raise [URI::InvalidURIError] if `profile` cannot be parsed as a URI

# File lib/merritt/manifest.rb, line 41
def initialize(conformance: CHECKM_0_7, profile:, prefixes: {}, fields: [], entries: [])
  @conformance = conformance
  @profile = normalize_profile_uri(profile).freeze
  @prefixes = normalize_prefixes(prefixes).freeze
  @fields = validate_fields(fields).freeze
  @entries = normalize_entries(entries).freeze
end

Public Instance Methods

write_to(io) click to toggle source

Writes this manifest to the specified IO @param io [IO] the IO to write to

# File lib/merritt/manifest.rb, line 51
def write_to(io)
  write_sc(io, conformance)
  write_sc(io, 'profile', profile)
  prefixes.each { |prefix, url| write_sc(io, 'prefix', "#{prefix}:", url) }
  write_sc(io, 'fields', *fields)
  entries.each { |entry| io.puts(entry_line(entry)) }
  write_sc(io, 'eof')
end
write_to_string() click to toggle source

Writes this manifest as a string @return [String] the manifest file contents as a string

# File lib/merritt/manifest.rb, line 62
def write_to_string
  io = StringIO.new
  write_to(io)
  io.string
end

Private Instance Methods

entry_line(entry) click to toggle source
# File lib/merritt/manifest.rb, line 73
def entry_line(entry)
  fields.map { |f| entry[f] }.join(COLSEP).sub(/[| ]+\z/, '')
end
normalize_entries(entries) click to toggle source
# File lib/merritt/manifest.rb, line 87
def normalize_entries(entries)
  entries.each_with_index.map do |entry, i|
    raise ArgumentError, "Nil entry at index #{i}" unless entry
    normalize_entry(entry)
  end
end
normalize_entry(entry) click to toggle source
# File lib/merritt/manifest.rb, line 94
def normalize_entry(entry)
  normalized = {}
  fields.each do |f|
    next unless (value = entry[f])
    normalized[f] = value
  end
  raise ArgumentError, "No fields found in entry #{entry}" if normalized.empty?
  normalized
end
normalize_prefixes(prefixes) click to toggle source
# File lib/merritt/manifest.rb, line 115
def normalize_prefixes(prefixes)
  return {} unless prefixes
  prefixes.map { |k, v| [k.to_sym, Util.to_uri(v)] }.to_h
end
normalize_profile_uri(profile) click to toggle source
# File lib/merritt/manifest.rb, line 120
def normalize_profile_uri(profile)
  profile_uri = Util.to_uri(profile)
  raise ArgumentError, "Invalid profile: #{profile || 'nil'}" unless profile_uri &&
    profile_uri.to_s.start_with?(PROFILE_BASE_URI)
  profile_uri.clone # defensive copy
end
validate_field(field) click to toggle source
# File lib/merritt/manifest.rb, line 108
def validate_field(field)
  prefix, fieldname = field.split(':')
  raise ArgumentError "Unknown prefix in field '#{field}': #{prefix}" unless prefixes.key?(prefix.to_sym)
  raise ArgumentError "Field '#{field}' cannot be parsed as prefix:fieldname" unless fieldname
  field
end
validate_fields(fields) click to toggle source
# File lib/merritt/manifest.rb, line 104
def validate_fields(fields)
  fields.map { |f| validate_field(f) }
end
write_sc(io, comment, *columns) click to toggle source

writes a checkm “structured comment” @param io [IO] the IO to write to @param comment [String] the comment @param columns [nil, Array<String>] columns to follow the initial comment

# File lib/merritt/manifest.rb, line 81
def write_sc(io, comment, *columns)
  io << '#%' << comment
  io << COLSEP << columns.join(COLSEP) unless columns.empty?
  io << "\n"
end