2023-04-23 21:23:45 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module Gitlab
|
|
|
|
module Ci
|
|
|
|
module Components
|
|
|
|
class InstancePath
|
|
|
|
include Gitlab::Utils::StrongMemoize
|
|
|
|
|
2023-06-20 00:43:36 +05:30
|
|
|
LATEST_VERSION_KEYWORD = '~latest'
|
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
def self.match?(address)
|
|
|
|
address.include?('@') && address.start_with?(Settings.gitlab_ci['component_fqdn'])
|
|
|
|
end
|
|
|
|
|
|
|
|
attr_reader :host
|
|
|
|
|
|
|
|
def initialize(address:, content_filename:)
|
|
|
|
@full_path, @version = address.to_s.split('@', 2)
|
|
|
|
@content_filename = content_filename
|
|
|
|
@host = Settings.gitlab_ci['component_fqdn']
|
|
|
|
end
|
|
|
|
|
|
|
|
def fetch_content!(current_user:)
|
|
|
|
return unless project
|
|
|
|
return unless sha
|
|
|
|
|
|
|
|
raise Gitlab::Access::AccessDeniedError unless Ability.allowed?(current_user, :download_code, project)
|
|
|
|
|
|
|
|
project.repository.blob_data_at(sha, project_file_path)
|
|
|
|
end
|
|
|
|
|
|
|
|
def project
|
|
|
|
find_project_by_component_path(instance_path)
|
|
|
|
end
|
|
|
|
strong_memoize_attr :project
|
|
|
|
|
|
|
|
def project_file_path
|
|
|
|
return unless project
|
|
|
|
|
|
|
|
component_dir = instance_path.delete_prefix(project.full_path)
|
|
|
|
File.join(component_dir, @content_filename).delete_prefix('/')
|
|
|
|
end
|
|
|
|
|
|
|
|
def sha
|
|
|
|
return unless project
|
2023-06-20 00:43:36 +05:30
|
|
|
return latest_version_sha if version == LATEST_VERSION_KEYWORD
|
2023-04-23 21:23:45 +05:30
|
|
|
|
|
|
|
project.commit(version)&.id
|
|
|
|
end
|
|
|
|
strong_memoize_attr :sha
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
attr_reader :version, :path
|
|
|
|
|
|
|
|
def instance_path
|
|
|
|
@full_path.delete_prefix(host)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Given a path like "my-org/sub-group/the-project/path/to/component"
|
|
|
|
# find the project "my-org/sub-group/the-project" by looking at all possible paths.
|
|
|
|
def find_project_by_component_path(path)
|
|
|
|
possible_paths = [path]
|
|
|
|
|
|
|
|
while index = path.rindex('/') # find index of last `/` in a path
|
|
|
|
possible_paths << (path = path[0..index - 1])
|
|
|
|
end
|
|
|
|
|
|
|
|
# remove shortest path as it is group
|
|
|
|
possible_paths.pop
|
|
|
|
|
|
|
|
::Project.where_full_path_in(possible_paths).take # rubocop: disable CodeReuse/ActiveRecord
|
|
|
|
end
|
2023-06-20 00:43:36 +05:30
|
|
|
|
|
|
|
def latest_version_sha
|
|
|
|
return unless catalog_resource = project&.catalog_resource
|
|
|
|
|
|
|
|
catalog_resource.latest_version&.sha
|
|
|
|
end
|
2023-04-23 21:23:45 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|