Class: Bibliothecary::MultiParsers::DependenciesCSV::CSVFile

Inherits:
Object
  • Object
show all
Defined in:
lib/bibliothecary/multi_parsers/dependencies_csv.rb

Overview

Processing a CSV file isn’t as exact as using a real manifest file, but you can get pretty close as long as the data you’re importing is simple.

Constant Summary collapse

HEADERS =

Header structures are:

<field to fill in for dependency> =>

match: [<regexp of incoming column name to match in priority order, highest priority first>...],
[default]: <optional default value for this field>

{
  "platform" => {
    match: [
      /^platform$/i,
    ],
  },
  "name" => {
    match: [
      /^name$/i,
    ],
  },
  # Manifests have versions that can have operators.
  # However, since Bibliothecary only currently supports analyzing a
  # single file as a single thing (either manifest or lockfile)
  # we can't return manifest-y data. Only take the lockfile requirement
  # when processing dependencies.csv for now.
  "requirement" => {
    match: [
      /^(lockfile |)requirement$/i,
      /^version$/i,
    ],
  },
  "type" => {
    default: "runtime",
    match: [
      /^(lockfile |)type$/i,
      /^(manifest |)type$/i,
    ],
  },
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file_contents) ⇒ CSVFile

Returns a new instance of CSVFile.



62
63
64
65
66
67
68
69
# File 'lib/bibliothecary/multi_parsers/dependencies_csv.rb', line 62

def initialize(file_contents)
  @file_contents = file_contents

  @result = nil

  # A Hash of "our field name" => ["header in CSV file", "lower priority header in CSV file"]
  @header_mappings = {}
end

Instance Attribute Details

#resultObject (readonly)

Returns the value of attribute result.



60
61
62
# File 'lib/bibliothecary/multi_parsers/dependencies_csv.rb', line 60

def result
  @result
end

Instance Method Details

#parse!Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/bibliothecary/multi_parsers/dependencies_csv.rb', line 71

def parse!
  table = parse_and_validate_csv_file

  @result = table.map.with_index do |row, idx|
    HEADERS.each_with_object({}) do |(header, info), obj|
      # find the first non-empty field in the row for this header, or nil if not found
      row_data = row[@header_mappings[header]]

      # some column have default data to fall back on
      if row_data
        obj[header.to_sym] = row_data
      elsif info.has_key?(:default)
        # if the default is nil, don't even add the key to the hash
        obj[header.to_sym] = info[:default] if info[:default]
      else
        # use 1-based index just like the 'csv' std lib, and count the headers as first row.
        raise "Missing required field '#{header}' on line #{idx + 2}."
      end
    end
  end
end