Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions app/models/hosts/gerrit.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
module Hosts
class Gerrit < Base
IGNORABLE_EXCEPTIONS = [Faraday::ResourceNotFound, Faraday::ConnectionFailed, Faraday::TimeoutError]

def self.api_missing_error_class
Faraday::ResourceNotFound
end

def icon
'git'
end

def url(repository)
"#{@host.url.to_s.chomp('/')}/plugins/gitiles/#{CGI.escape(repository.full_name)}"
end

def html_url(repository)
url(repository)
end

def raw_url(repository, sha = nil)
sha ||= repository.default_branch.presence || 'HEAD'
"#{url(repository)}/+/#{CGI.escape(sha)}/"
end

def blob_url(repository, sha = nil)
raw_url(repository, sha)
end

def download_url(repository, branch = nil, kind = 'branch')
ref = branch.presence || repository.default_branch.presence || 'HEAD'
"#{url(repository)}/+archive/#{CGI.escape(ref)}.tar.gz"
end

def fetch_repository(id_or_name, _token = nil)
name = id_or_name.to_s
resp = api_client.get("/projects/#{CGI.escape(name)}")
return nil unless resp.success?

map_repository_data(gerrit_json(resp.body))
rescue *IGNORABLE_EXCEPTIONS
nil
end

def map_repository_data(data)
{
uuid: data['id'] || data['name'],
full_name: data['name'] || data['id'],
owner: data['parent'],
description: data['description'],
default_branch: data['branches']&.dig('HEAD') || 'master',
fork: false,
archived: data['state'] == 'READ_ONLY',
private: false,
scm: 'git',
has_issues: false,
has_wiki: false,
pull_requests_enabled: false,
topics: [],
created_at: nil,
updated_at: nil,
pushed_at: nil,
metadata: {
state: data['state'],
parent: data['parent'],
web_links: data['web_links']
}.compact
}
end

def load_repo_names(limit = 100, prefix = nil)
params = { n: limit }
params[:p] = prefix if prefix.present?
resp = api_client.get('/projects/', params)
return [] unless resp.success?

gerrit_json(resp.body).keys
rescue *IGNORABLE_EXCEPTIONS
[]
end

def crawl_repositories
load_repo_names.each { |name| @host.sync_repository(name) }
end

def crawl_repositories_async
load_repo_names.each { |name| @host.sync_repository_async(name) }
end

def download_tags(repository)
nil
end

def download_releases(repository)
nil
end

def host_version
resp = api_client.get('/config/server/version')
return gerrit_json(resp.body) if resp.success?
rescue
nil
end

def api_client
Faraday.new(@host.url, request: { timeout: 30 }) do |conn|
conn.response :raise_error
end
end

private

def gerrit_json(body)
JSON.parse(body.to_s.sub(/\A\)\]\}'\n?/, ''))
end
end
end
4 changes: 4 additions & 0 deletions db/seeds.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
default_hosts = [
{name: 'gerrit.osmocom.org', url: 'https://gerrit.osmocom.org', kind: 'gerrit'},
{name: 'gerrit.cloudera.org', url: 'https://gerrit.cloudera.org', kind: 'gerrit'},
{name: 'gerrit.rockbox.org', url: 'https://gerrit.rockbox.org', kind: 'gerrit'},
{name: 'review.coreboot.org', url: 'https://review.coreboot.org', kind: 'gerrit'},
{name: 'GitHub', url: 'https://github.com', kind: 'github'},
{name: 'GitLab.com', url: 'https://gitlab.com', kind: 'gitlab'},
{name: 'Bitbucket.org', url: 'https://bitbucket.org', kind: 'bitbucket'},
Expand Down
40 changes: 40 additions & 0 deletions test/models/gerrit_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require "test_helper"

class GerritTest < ActiveSupport::TestCase
setup do
@host = Host.new(name: 'Coreboot Gerrit', url: 'https://review.coreboot.org', kind: 'gerrit')
@gerrit = Hosts::Gerrit.new(@host)
end

test 'maps gerrit project data to repository attributes' do
data = {
'id' => 'coreboot',
'name' => 'coreboot',
'parent' => 'All-Projects',
'description' => 'coreboot main repository',
'state' => 'ACTIVE',
'branches' => { 'HEAD' => 'main' },
'web_links' => [{ 'name' => 'gitweb', 'url' => 'https://review.coreboot.org/plugins/gitiles/coreboot' }]
}

mapped = @gerrit.map_repository_data(data)

assert_equal 'coreboot', mapped[:uuid]
assert_equal 'coreboot', mapped[:full_name]
assert_equal 'All-Projects', mapped[:owner]
assert_equal 'coreboot main repository', mapped[:description]
assert_equal 'main', mapped[:default_branch]
assert_equal 'git', mapped[:scm]
assert_equal false, mapped[:has_issues]
assert_equal [], mapped[:topics]
assert_equal 'ACTIVE', mapped[:metadata][:state]
end

test 'builds gerrit gitiles URLs' do
repository = Repository.new(host: @host, full_name: 'coreboot', default_branch: 'main')

assert_equal 'https://review.coreboot.org/plugins/gitiles/coreboot', @gerrit.url(repository)
assert_equal 'https://review.coreboot.org/plugins/gitiles/coreboot/+/main/', @gerrit.raw_url(repository)
assert_equal 'https://review.coreboot.org/plugins/gitiles/coreboot/+archive/main.tar.gz', @gerrit.download_url(repository)
end
end