summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-10-07 09:10:18 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-10-07 09:10:18 +0000
commit2a296e6d58ee5da98c8da39dab93cb4c5537139d (patch)
tree8be8ca82d9675a00515fbb9d19836f1baab26d0e /app
parent8e656d0d45692211f17b7d55364e192cd94cae0b (diff)
downloadgitlab-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.rb84
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