Commit 6828a063 authored by Giorgenes Gelatti's avatar Giorgenes Gelatti Committed by Igor Drozdov

Adds version cache field to composer metadata

Refactor composer json classes and adds
SHA cache metadata field for future
storage of cached values.
parent a09aa50a
......@@ -20,33 +20,17 @@ module Packages
end
def package_versions(packages = @packages)
{ 'packages' => { packages.first.name => package_versions_map(packages) } }
package_versions_index(packages).as_json
end
private
def package_versions_map(packages)
packages.each_with_object({}) do |package, map|
map[package.version] = package_metadata(package)
end
def package_versions_sha(packages = @packages)
package_versions_index(packages).sha
end
def package_metadata(package)
json = package.composer_metadatum.composer_json
json.merge('dist' => package_dist(package), 'uid' => package.id, 'version' => package.version)
end
def package_dist(package)
sha = package.composer_metadatum.target_sha
archive_api_path = api_v4_projects_packages_composer_archives_package_name_path({ id: package.project_id, package_name: package.name, format: '.zip' }, true)
{
'type' => 'zip',
'url' => expose_url(archive_api_path) + "?sha=#{sha}",
'reference' => sha,
'shasum' => ''
}
def package_versions_index(packages)
::Gitlab::Composer::VersionIndex.new(packages)
end
def providers_map
......@@ -59,10 +43,6 @@ module Packages
map
end
def package_versions_sha(packages)
Digest::SHA256.hexdigest(package_versions(packages).to_json)
end
def provider_sha
Digest::SHA256.hexdigest(provider.to_json)
end
......
---
title: Add version cache field to composer metadata
merge_request: 50906
author:
type: other
# frozen_string_literal: true
class AddVersionShaCacheToComposerMetadata < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def up
with_lock_retries do
add_column :packages_composer_metadata, :version_cache_sha, :binary, null: true
end
end
def down
with_lock_retries do
remove_column :packages_composer_metadata, :version_cache_sha, :binary
end
end
end
2278b1e4e19b5306e4b616eb87b622427ef2dcf73dae761739cb3106d5e64718
\ No newline at end of file
......@@ -14668,7 +14668,8 @@ ALTER SEQUENCE packages_build_infos_id_seq OWNED BY packages_build_infos.id;
CREATE TABLE packages_composer_metadata (
package_id bigint NOT NULL,
target_sha bytea NOT NULL,
composer_json jsonb DEFAULT '{}'::jsonb NOT NULL
composer_json jsonb DEFAULT '{}'::jsonb NOT NULL,
version_cache_sha bytea
);
CREATE TABLE packages_conan_file_metadata (
......
# frozen_string_literal: true
module Gitlab
module Composer
class VersionIndex
include API::Helpers::RelatedResourcesHelpers
def initialize(packages)
@packages = packages
end
def as_json(_options = nil)
{ 'packages' => { @packages.first.name => package_versions_map } }
end
def sha
Digest::SHA256.hexdigest(to_json)
end
private
def package_versions_map
@packages.each_with_object({}) do |package, map|
map[package.version] = package_metadata(package)
end
end
def package_metadata(package)
json = package.composer_metadatum.composer_json
json.merge('dist' => package_dist(package), 'uid' => package.id, 'version' => package.version)
end
def package_dist(package)
sha = package.composer_metadatum.target_sha
archive_api_path = api_v4_projects_packages_composer_archives_package_name_path({ id: package.project_id, package_name: package.name, format: '.zip' }, true)
{
'type' => 'zip',
'url' => expose_url(archive_api_path) + "?sha=#{sha}",
'reference' => sha,
'shasum' => ''
}
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Composer::VersionIndex do
let_it_be(:package_name) { 'sample-project' }
let_it_be(:json) { { 'name' => package_name } }
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, :custom_repo, files: { 'composer.json' => json.to_json }, group: group) }
let_it_be(:package1) { create(:composer_package, :with_metadatum, project: project, name: package_name, version: '1.0.0', json: json) }
let_it_be(:package2) { create(:composer_package, :with_metadatum, project: project, name: package_name, version: '2.0.0', json: json) }
let(:branch) { project.repository.find_branch('master') }
let(:packages) { [package1, package2] }
describe '#as_json' do
subject(:index) { described_class.new(packages).as_json }
def expected_json(package)
{
'dist' => {
'reference' => branch.target,
'shasum' => '',
'type' => 'zip',
'url' => "http://localhost/api/v4/projects/#{project.id}/packages/composer/archives/#{package.name}.zip?sha=#{branch.target}"
},
'name' => package.name,
'uid' => package.id,
'version' => package.version
}
end
it 'returns the packages json' do
packages = index['packages'][package_name]
expect(packages['1.0.0']).to eq(expected_json(package1))
expect(packages['2.0.0']).to eq(expected_json(package2))
end
end
describe '#sha' do
subject(:sha) { described_class.new(packages).sha }
it 'returns the json SHA' do
expect(sha).to match /^[A-Fa-f0-9]{64}$/
end
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