Commit 327e6c3e authored by David Fernandez's avatar David Fernandez

Merge branch 'helm_extract_file_metadata_service' into 'master'

Add Packages::Helm::ExtractFileMetadataService

See merge request gitlab-org/gitlab!61012
parents 9f5bdd47 e4ea9973
# frozen_string_literal: true
require 'rubygems/package'
module Packages
module Helm
class ExtractFileMetadataService
ExtractionError = Class.new(StandardError)
def initialize(package_file)
@package_file = package_file
end
def execute
raise ExtractionError, 'invalid package file' unless valid_package_file?
metadata
end
private
def valid_package_file?
@package_file &&
@package_file.package&.helm? &&
@package_file.file.size > 0 # rubocop:disable Style/ZeroLengthPredicate
end
def metadata
YAML.safe_load(chart_yaml_content)
rescue Psych::Exception => e
raise ExtractionError, "Error while parsing Chart.yaml: #{e.message}"
end
def chart_yaml_content
@package_file.file.use_open_file do |file|
tar_reader = Gem::Package::TarReader.new(Zlib::GzipReader.new(file))
chart_yaml = tar_reader.find do |entry|
next unless entry.file?
entry.full_name.end_with?('/Chart.yaml')
end
raise ExtractionError, 'Chart.yaml not found within a directory' unless chart_yaml
chart_yaml.read
ensure
tar_reader.close
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Packages::Helm::ExtractFileMetadataService do
let_it_be(:package_file) { create(:helm_package_file) }
let(:service) { described_class.new(package_file) }
let(:expected) do
{
'apiVersion' => 'v2',
'description' => 'File, Block, and Object Storage Services for your Cloud-Native Environment',
'icon' => 'https://rook.io/images/rook-logo.svg',
'name' => 'rook-ceph',
'sources' => ['https://github.com/rook/rook'],
'version' => 'v1.5.8'
}
end
subject { service.execute }
context 'with a valid file' do
it { is_expected.to eq(expected) }
end
context 'without Chart.yaml' do
before do
expect_next_instances_of(Gem::Package::TarReader::Entry, 14) do |entry|
expect(entry).to receive(:full_name).exactly(:once).and_wrap_original do |m, *args|
m.call(*args) + '_suffix'
end
end
end
it { expect { subject }.to raise_error(described_class::ExtractionError, 'Chart.yaml not found within a directory') }
end
context 'with Chart.yaml at root' do
before do
expect_next_instances_of(Gem::Package::TarReader::Entry, 14) do |entry|
expect(entry).to receive(:full_name).exactly(:once) do
'Chart.yaml'
end
end
end
it { expect { subject }.to raise_error(described_class::ExtractionError, 'Chart.yaml not found within a directory') }
end
context 'with an invalid YAML' do
before do
expect_next_instance_of(Gem::Package::TarReader::Entry) do |entry|
expect(entry).to receive(:read).and_return('{')
end
end
it { expect { subject }.to raise_error(described_class::ExtractionError, 'Error while parsing Chart.yaml: (<unknown>): did not find expected node content while parsing a flow node at line 2 column 1') }
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment