Commit ebef583d authored by Steve Abrams's avatar Steve Abrams

RubyGems metadata and models

Adds the rubygems_metadata table and models as
a basis for the RubyGems package registry
parent 67b531f5
...@@ -17,6 +17,7 @@ class Packages::Package < ApplicationRecord ...@@ -17,6 +17,7 @@ class Packages::Package < ApplicationRecord
has_one :maven_metadatum, inverse_of: :package, class_name: 'Packages::Maven::Metadatum' has_one :maven_metadatum, inverse_of: :package, class_name: 'Packages::Maven::Metadatum'
has_one :nuget_metadatum, inverse_of: :package, class_name: 'Packages::Nuget::Metadatum' has_one :nuget_metadatum, inverse_of: :package, class_name: 'Packages::Nuget::Metadatum'
has_one :composer_metadatum, inverse_of: :package, class_name: 'Packages::Composer::Metadatum' has_one :composer_metadatum, inverse_of: :package, class_name: 'Packages::Composer::Metadatum'
has_one :rubygems_metadatum, inverse_of: :package, class_name: 'Packages::Rubygems::Metadatum'
has_many :build_infos, inverse_of: :package has_many :build_infos, inverse_of: :package
has_many :pipelines, through: :build_infos has_many :pipelines, through: :build_infos
has_one :debian_publication, inverse_of: :package, class_name: 'Packages::Debian::Publication' has_one :debian_publication, inverse_of: :package, class_name: 'Packages::Debian::Publication'
...@@ -64,7 +65,9 @@ class Packages::Package < ApplicationRecord ...@@ -64,7 +65,9 @@ class Packages::Package < ApplicationRecord
if: :debian_package? if: :debian_package?
validate :forbidden_debian_changes, if: :debian? validate :forbidden_debian_changes, if: :debian?
enum package_type: { maven: 1, npm: 2, conan: 3, nuget: 4, pypi: 5, composer: 6, generic: 7, golang: 8, debian: 9 } enum package_type: { maven: 1, npm: 2, conan: 3, nuget: 4, pypi: 5,
composer: 6, generic: 7, golang: 8, debian: 9,
rubygems: 10 }
scope :with_name, ->(name) { where(name: name) } scope :with_name, ->(name) { where(name: name) }
scope :with_name_like, ->(name) { where(arel_table[:name].matches(name)) } scope :with_name_like, ->(name) { where(arel_table[:name].matches(name)) }
......
# frozen_string_literal: true
module Packages
module Rubygems
class Metadatum < ApplicationRecord
self.table_name = 'packages_rubygems_metadata'
self.primary_key = :package_id
belongs_to :package, -> { where(package_type: :rubygems) }, inverse_of: :rubygems_metadatum
validates :package, presence: true
validate :rubygems_package_type
private
def rubygems_package_type
unless package&.rubygems?
errors.add(:base, _('Package type must be RubyGems'))
end
end
end
end
end
---
title: Add rubygems metadata table
merge_request: 52639
author:
type: added
# frozen_string_literal: true
class AddRubygemsMaxFileSizeToPlanLimits < ActiveRecord::Migration[6.0]
DOWNTIME = false
def change
add_column :plan_limits, :rubygems_max_file_size, :bigint, default: 3.gigabytes, null: false
end
end
# frozen_string_literal: true
class CreatePackagesRubygemsMetadata < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def up
create_table_with_constraints :packages_rubygems_metadata, id: false do |t|
t.timestamps_with_timezone
t.references :package, primary_key: true, index: false, default: nil, null: false, foreign_key: { to_table: :packages_packages, on_delete: :cascade }, type: :bigint
t.text :authors
t.text :files
t.text :summary
t.text :description
t.text :email
t.text :homepage
t.text :licenses
t.text :metadata
t.text :author
t.text :bindir
t.text :cert_chain
t.text :executables
t.text :extensions
t.text :extra_rdoc_files
t.text :platform
t.text :post_install_message
t.text :rdoc_options
t.text :require_paths
t.text :required_ruby_version
t.text :required_rubygems_version
t.text :requirements
t.text :rubygems_version
t.text :signing_key
t.text_limit :authors, 255
t.text_limit :files, 255
t.text_limit :summary, 1024
t.text_limit :description, 1024
t.text_limit :email, 255
t.text_limit :homepage, 255
t.text_limit :licenses, 255
t.text_limit :metadata, 255
t.text_limit :author, 255
t.text_limit :bindir, 255
t.text_limit :cert_chain, 255
t.text_limit :executables, 255
t.text_limit :extensions, 255
t.text_limit :extra_rdoc_files, 255
t.text_limit :platform, 255
t.text_limit :post_install_message, 255
t.text_limit :rdoc_options, 255
t.text_limit :require_paths, 255
t.text_limit :required_ruby_version, 255
t.text_limit :required_rubygems_version, 255
t.text_limit :requirements, 255
t.text_limit :rubygems_version, 255
t.text_limit :signing_key, 255
end
end
def down
drop_table :packages_rubygems_metadata
end
end
4105ae45742c2eda67fe5c54256732e55555ab7832e4cbf0fcb041599c23bd29
\ No newline at end of file
ec6832ba26fca8d8427383cd0189765191a0a7f17bb78d61b900c5b541d5725e
\ No newline at end of file
...@@ -15255,6 +15255,58 @@ CREATE TABLE packages_pypi_metadata ( ...@@ -15255,6 +15255,58 @@ CREATE TABLE packages_pypi_metadata (
CONSTRAINT check_379019d5da CHECK ((char_length(required_python) <= 255)) CONSTRAINT check_379019d5da CHECK ((char_length(required_python) <= 255))
); );
CREATE TABLE packages_rubygems_metadata (
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
package_id bigint NOT NULL,
authors text,
files text,
summary text,
description text,
email text,
homepage text,
licenses text,
metadata text,
author text,
bindir text,
cert_chain text,
executables text,
extensions text,
extra_rdoc_files text,
platform text,
post_install_message text,
rdoc_options text,
require_paths text,
required_ruby_version text,
required_rubygems_version text,
requirements text,
rubygems_version text,
signing_key text,
CONSTRAINT check_0154a18c82 CHECK ((char_length(description) <= 1024)),
CONSTRAINT check_22814c771b CHECK ((char_length(email) <= 255)),
CONSTRAINT check_242293030e CHECK ((char_length(extensions) <= 255)),
CONSTRAINT check_27619a7922 CHECK ((char_length(rubygems_version) <= 255)),
CONSTRAINT check_3d1b6f3a39 CHECK ((char_length(post_install_message) <= 255)),
CONSTRAINT check_545f7606f9 CHECK ((char_length(required_rubygems_version) <= 255)),
CONSTRAINT check_5988451714 CHECK ((char_length(executables) <= 255)),
CONSTRAINT check_5f9c84ea17 CHECK ((char_length(platform) <= 255)),
CONSTRAINT check_64f1cecf05 CHECK ((char_length(requirements) <= 255)),
CONSTRAINT check_6ac7043c50 CHECK ((char_length(extra_rdoc_files) <= 255)),
CONSTRAINT check_6ff3abe325 CHECK ((char_length(cert_chain) <= 255)),
CONSTRAINT check_7cb01436df CHECK ((char_length(licenses) <= 255)),
CONSTRAINT check_8be21d92e7 CHECK ((char_length(summary) <= 1024)),
CONSTRAINT check_946cb96acb CHECK ((char_length(homepage) <= 255)),
CONSTRAINT check_9824fc9efc CHECK ((char_length(bindir) <= 255)),
CONSTRAINT check_994b68eb64 CHECK ((char_length(authors) <= 255)),
CONSTRAINT check_9d42fa48ae CHECK ((char_length(signing_key) <= 255)),
CONSTRAINT check_b0f4f8c853 CHECK ((char_length(files) <= 255)),
CONSTRAINT check_b7b296b420 CHECK ((char_length(author) <= 255)),
CONSTRAINT check_bf16b21a47 CHECK ((char_length(rdoc_options) <= 255)),
CONSTRAINT check_ca641a3354 CHECK ((char_length(required_ruby_version) <= 255)),
CONSTRAINT check_ea02f4800f CHECK ((char_length(metadata) <= 255)),
CONSTRAINT check_f76bad1a9a CHECK ((char_length(require_paths) <= 255))
);
CREATE TABLE packages_tags ( CREATE TABLE packages_tags (
id bigint NOT NULL, id bigint NOT NULL,
package_id integer NOT NULL, package_id integer NOT NULL,
...@@ -15466,7 +15518,8 @@ CREATE TABLE plan_limits ( ...@@ -15466,7 +15518,8 @@ CREATE TABLE plan_limits (
project_feature_flags integer DEFAULT 200 NOT NULL, project_feature_flags integer DEFAULT 200 NOT NULL,
ci_max_artifact_size_api_fuzzing integer DEFAULT 0 NOT NULL, ci_max_artifact_size_api_fuzzing integer DEFAULT 0 NOT NULL,
ci_pipeline_deployments integer DEFAULT 500 NOT NULL, ci_pipeline_deployments integer DEFAULT 500 NOT NULL,
pull_mirror_interval_seconds integer DEFAULT 300 NOT NULL pull_mirror_interval_seconds integer DEFAULT 300 NOT NULL,
rubygems_max_file_size bigint DEFAULT '3221225472'::bigint NOT NULL
); );
CREATE SEQUENCE plan_limits_id_seq CREATE SEQUENCE plan_limits_id_seq
...@@ -20510,6 +20563,9 @@ ALTER TABLE ONLY packages_packages ...@@ -20510,6 +20563,9 @@ ALTER TABLE ONLY packages_packages
ALTER TABLE ONLY packages_pypi_metadata ALTER TABLE ONLY packages_pypi_metadata
ADD CONSTRAINT packages_pypi_metadata_pkey PRIMARY KEY (package_id); ADD CONSTRAINT packages_pypi_metadata_pkey PRIMARY KEY (package_id);
ALTER TABLE ONLY packages_rubygems_metadata
ADD CONSTRAINT packages_rubygems_metadata_pkey PRIMARY KEY (package_id);
ALTER TABLE ONLY packages_tags ALTER TABLE ONLY packages_tags
ADD CONSTRAINT packages_tags_pkey PRIMARY KEY (id); ADD CONSTRAINT packages_tags_pkey PRIMARY KEY (id);
...@@ -25522,6 +25578,9 @@ ALTER TABLE ONLY scim_identities ...@@ -25522,6 +25578,9 @@ ALTER TABLE ONLY scim_identities
ALTER TABLE ONLY packages_debian_project_distributions ALTER TABLE ONLY packages_debian_project_distributions
ADD CONSTRAINT fk_rails_94b95e1f84 FOREIGN KEY (creator_id) REFERENCES users(id) ON DELETE SET NULL; ADD CONSTRAINT fk_rails_94b95e1f84 FOREIGN KEY (creator_id) REFERENCES users(id) ON DELETE SET NULL;
ALTER TABLE ONLY packages_rubygems_metadata
ADD CONSTRAINT fk_rails_95a3f5ce78 FOREIGN KEY (package_id) REFERENCES packages_packages(id) ON DELETE CASCADE;
ALTER TABLE ONLY packages_pypi_metadata ALTER TABLE ONLY packages_pypi_metadata
ADD CONSTRAINT fk_rails_9698717cdd FOREIGN KEY (package_id) REFERENCES packages_packages(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_9698717cdd FOREIGN KEY (package_id) REFERENCES packages_packages(id) ON DELETE CASCADE;
......
...@@ -17769,6 +17769,11 @@ enum PackageTypeEnum { ...@@ -17769,6 +17769,11 @@ enum PackageTypeEnum {
Packages from the PyPI package manager Packages from the PyPI package manager
""" """
PYPI PYPI
"""
Packages from the Rubygems package manager
"""
RUBYGEMS
} }
""" """
......
...@@ -52356,6 +52356,12 @@ ...@@ -52356,6 +52356,12 @@
"description": "Packages from the Debian package manager", "description": "Packages from the Debian package manager",
"isDeprecated": false, "isDeprecated": false,
"deprecationReason": null "deprecationReason": null
},
{
"name": "RUBYGEMS",
"description": "Packages from the Rubygems package manager",
"isDeprecated": false,
"deprecationReason": null
} }
], ],
"possibleTypes": null "possibleTypes": null
...@@ -5121,6 +5121,7 @@ Rotation length unit of an on-call rotation. ...@@ -5121,6 +5121,7 @@ Rotation length unit of an on-call rotation.
| `NPM` | Packages from the NPM package manager | | `NPM` | Packages from the NPM package manager |
| `NUGET` | Packages from the Nuget package manager | | `NUGET` | Packages from the Nuget package manager |
| `PYPI` | Packages from the PyPI package manager | | `PYPI` | Packages from the PyPI package manager |
| `RUBYGEMS` | Packages from the Rubygems package manager |
### PipelineConfigSourceEnum ### PipelineConfigSourceEnum
......
...@@ -20853,6 +20853,9 @@ msgstr "" ...@@ -20853,6 +20853,9 @@ msgstr ""
msgid "Package type must be PyPi" msgid "Package type must be PyPi"
msgstr "" msgstr ""
msgid "Package type must be RubyGems"
msgstr ""
msgid "PackageRegistry|%{boldStart}Allow duplicates%{boldEnd} - Packages with the same name and version are accepted." msgid "PackageRegistry|%{boldStart}Allow duplicates%{boldEnd} - Packages with the same name and version are accepted."
msgstr "" msgstr ""
......
...@@ -21,6 +21,23 @@ FactoryBot.define do ...@@ -21,6 +21,23 @@ FactoryBot.define do
end end
end end
factory :rubygems_package do
sequence(:name) { |n| "my_gem_#{n}" }
sequence(:version) { |n| "1.#{n}" }
package_type { :rubygems }
after :create do |package|
create :package_file, :gem, package: package
create :package_file, :gemspec, package: package
end
trait(:with_metadatum) do
after :build do |pkg|
pkg.rubygems_metadatum = build(:rubygems_metadatum)
end
end
end
factory :debian_package do factory :debian_package do
sequence(:name) { |n| "package-#{n}" } sequence(:name) { |n| "package-#{n}" }
sequence(:version) { |n| "1.0-#{n}" } sequence(:version) { |n| "1.0-#{n}" }
......
...@@ -221,6 +221,22 @@ FactoryBot.define do ...@@ -221,6 +221,22 @@ FactoryBot.define do
size { 300.kilobytes } size { 300.kilobytes }
end end
trait(:gem) do
package
file_fixture { 'spec/fixtures/packages/rubygems/package-0.0.1.gem' }
file_name { 'package-0.0.1.gem' }
file_sha1 { '5fe852b2a6abd96c22c11fa1ff2fb19d9ce58b57' }
size { 4.kilobytes }
end
trait(:gemspec) do
package
file_fixture { 'spec/fixtures/packages/rubygems/package.gemspec' }
file_name { 'package.gemspec' }
file_sha1 { '5fe852b2a6abd96c22c11fa1ff2fb19d9ce58b57' }
size { 242.bytes }
end
trait(:pypi) do trait(:pypi) do
package package
file_fixture { 'spec/fixtures/packages/pypi/sample-project.tar.gz' } file_fixture { 'spec/fixtures/packages/pypi/sample-project.tar.gz' }
......
# frozen_string_literal: true
FactoryBot.define do
factory :rubygems_metadatum, class: 'Packages::Rubygems::Metadatum' do
package { association(:rubygems_package) }
authors { FFaker::Name.name }
email { FFaker::Internet.email }
end
end
# frozen_string_literal: true
Gem::Specification.new do |s|
s.name = %q{package}
s.authors = ["Tanuki Steve"]
s.version = "0.0.1"
s.date = %q{2011-09-29}
s.summary = %q{package is the best}
s.files = [
"lib/package.rb"
]
s.required_ruby_version = '>= 2.7.0'
s.rubygems_version = '>= 1.8.11'
s.require_paths = ["lib"]
end
...@@ -4,6 +4,6 @@ require 'spec_helper' ...@@ -4,6 +4,6 @@ require 'spec_helper'
RSpec.describe GitlabSchema.types['PackageTypeEnum'] do RSpec.describe GitlabSchema.types['PackageTypeEnum'] do
it 'exposes all package types' do it 'exposes all package types' do
expect(described_class.values.keys).to contain_exactly(*%w[MAVEN NPM CONAN NUGET PYPI COMPOSER GENERIC GOLANG DEBIAN]) expect(described_class.values.keys).to contain_exactly(*%w[MAVEN NPM CONAN NUGET PYPI COMPOSER GENERIC GOLANG DEBIAN RUBYGEMS])
end end
end end
...@@ -17,6 +17,7 @@ RSpec.describe Packages::Package, type: :model do ...@@ -17,6 +17,7 @@ RSpec.describe Packages::Package, type: :model do
it { is_expected.to have_one(:debian_publication).inverse_of(:package).class_name('Packages::Debian::Publication') } it { is_expected.to have_one(:debian_publication).inverse_of(:package).class_name('Packages::Debian::Publication') }
it { is_expected.to have_one(:debian_distribution).through(:debian_publication).source(:distribution).inverse_of(:packages).class_name('Packages::Debian::ProjectDistribution') } it { is_expected.to have_one(:debian_distribution).through(:debian_publication).source(:distribution).inverse_of(:packages).class_name('Packages::Debian::ProjectDistribution') }
it { is_expected.to have_one(:nuget_metadatum).inverse_of(:package) } it { is_expected.to have_one(:nuget_metadatum).inverse_of(:package) }
it { is_expected.to have_one(:rubygems_metadatum).inverse_of(:package) }
end end
describe '.with_composer_target' do describe '.with_composer_target' do
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Packages::Rubygems::Metadatum, type: :model do
describe 'relationships' do
it { is_expected.to belong_to(:package) }
end
describe 'validations' do
it { is_expected.to validate_presence_of(:package) }
describe '#rubygems_package_type' do
it 'will not allow a package with a different package_type' do
package = build('conan_package')
rubygems_metadatum = build('rubygems_metadatum', package: package)
expect(rubygems_metadatum).not_to be_valid
expect(rubygems_metadatum.errors.to_a).to include('Package type must be RubyGems')
end
end
end
end
...@@ -190,6 +190,7 @@ RSpec.shared_examples 'filters on each package_type' do |is_project: false| ...@@ -190,6 +190,7 @@ RSpec.shared_examples 'filters on each package_type' do |is_project: false|
let_it_be(:package7) { create(:generic_package, project: project) } let_it_be(:package7) { create(:generic_package, project: project) }
let_it_be(:package8) { create(:golang_package, project: project) } let_it_be(:package8) { create(:golang_package, project: project) }
let_it_be(:package9) { create(:debian_package, project: project) } let_it_be(:package9) { create(:debian_package, project: project) }
let_it_be(:package9) { create(:rubygems_package, project: project) }
Packages::Package.package_types.keys.each do |package_type| Packages::Package.package_types.keys.each do |package_type|
context "for package type #{package_type}" do context "for package type #{package_type}" do
......
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