diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-10-07 09:10:18 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-10-07 09:10:18 +0000 |
commit | 2a296e6d58ee5da98c8da39dab93cb4c5537139d (patch) | |
tree | 8be8ca82d9675a00515fbb9d19836f1baab26d0e /app | |
parent | 8e656d0d45692211f17b7d55364e192cd94cae0b (diff) | |
download | gitlab-ce-2a296e6d58ee5da98c8da39dab93cb4c5537139d.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r-- | app/services/packages/rpm/parse_package_service.rb | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/app/services/packages/rpm/parse_package_service.rb b/app/services/packages/rpm/parse_package_service.rb new file mode 100644 index 00000000000..689a161a81a --- /dev/null +++ b/app/services/packages/rpm/parse_package_service.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +module Packages + module Rpm + class ParsePackageService + include ::Gitlab::Utils::StrongMemoize + + BUILD_ATTRIBUTES_METHOD_NAMES = %i[changelogs requirements provides].freeze + STATIC_ATTRIBUTES = %i[name version release summary description arch + license sourcerpm group buildhost packager vendor].freeze + + CHANGELOGS_RPM_KEYS = %i[changelogtext changelogtime].freeze + REQUIREMENTS_RPM_KEYS = %i[requirename requireversion requireflags].freeze + PROVIDES_RPM_KEYS = %i[providename provideflags provideversion].freeze + + def initialize(package_file) + @rpm = RPM::File.new(package_file) + end + + def execute + raise ArgumentError, 'Unable to parse package' unless valid_package? + + { + files: rpm.files || [], + epoch: package_tags[:epoch] || '0', + changelogs: build_changelogs, + requirements: build_requirements, + provides: build_provides + }.merge(extract_static_attributes) + end + + private + + attr_reader :rpm + + def valid_package? + rpm.files && package_tags && true + rescue RuntimeError + # if arr-pm throws an error due to an incorrect file format, + # we just want this validation to fail rather than throw an exception + false + end + + def package_tags + strong_memoize(:package_tags) do + rpm.tags + end + end + + def extract_static_attributes + STATIC_ATTRIBUTES.each_with_object({}) do |attribute, hash| + hash[attribute] = package_tags[attribute] + end + end + + # Define methods for building RPM attribute data from parsed package + # Transform + # changelogtime: [123, 234], + # changelogname: ["First", "Second"] + # changelogtext: ["Work1", "Work2"] + # Into + # changelog: [ + # {changelogname: "First", changelogtext: "Work1", changelogtime: 123}, + # {changelogname: "Second", changelogtext: "Work2", changelogtime: 234} + # ] + BUILD_ATTRIBUTES_METHOD_NAMES.each do |resource| + define_method("build_#{resource}") do + resource_keys = self.class.const_get("#{resource.upcase}_RPM_KEYS", false).dup + return [] if resource_keys.any? { package_tags[_1].blank? } + + first_attributes = package_tags[resource_keys.first] + zipped_data = first_attributes.zip(*resource_keys[1..].map { package_tags[_1] }) + build_hashes(resource_keys, zipped_data) + end + end + + def build_hashes(resource_keys, zipped_data) + zipped_data.map do |data| + resource_keys.zip(data).to_h + end + end + end + end +end |