From 1e3872c86617352122eeef2b6d50eb18825292f8 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 21 Apr 2021 11:49:32 -0400 Subject: [PATCH] Add gitea-import.rb --- gitea-import.rb | 137 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100755 gitea-import.rb diff --git a/gitea-import.rb b/gitea-import.rb new file mode 100755 index 0000000..f74502e --- /dev/null +++ b/gitea-import.rb @@ -0,0 +1,137 @@ +#!/usr/bin/env ruby + +require "set" +require "net/http" +require "json" + +SERVER_URL = "https://git.jholtrop.com" +MIGRATE_API = "/api/v1/repos/migrate" +# Go to https://git.jholtrop.com/user/settings/applications to add a token. +TOKEN = File.read("token").chomp +USERNAME = "josh" +EXCLUDE = Set[*%w[gitolite-admin]] +CLONE_URL_BASE = "git://holtrop.mooo.com" + +def read_gitolite_repos + gitolite_conf = File.read("../gitolite-admin/conf/gitolite.conf") + repo = nil + gitolite_conf.each_line.reduce([]) do |result, line| + if line =~ /^repo (\S+)/ + repo_name = $1 + if EXCLUDE.include?(repo_name) + repo = nil + else + repo = {} + repo[:oldname] = repo_name + repo[:name] = File.basename(repo_name) + result << repo + end + end + if line =~ /^\s*config gitweb\.description\s*=\s*(\S.+)$/ + description = $1 + if repo + repo[:description] = description + end + end + result + end +end + +def check_unique_names(gitolite_repos) + names = Set.new + gitolite_repos.each do |repo| + if names.include?(repo[:name]) + raise "duplicate repo name: #{repo[:name]}" + names << repo[:name] + end + end +end + +def migrate_repo(repo) + puts "Migrating #{repo[:name]}..." + clone_url = "#{CLONE_URL_BASE}/#{repo[:oldname]}.git" + uri = URI("#{SERVER_URL}/#{MIGRATE_API}") + Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http| + request = Net::HTTP::Post.new(uri) + request["Authorization"] = "token #{TOKEN}" + request.set_form_data( + "clone_addr" => clone_url, + "repo_name" => repo[:name], + "description" => repo[:description], + "repo_owner" => USERNAME, + "mirror" => "false", + "private" => "true", + ) + response = http.request(request) + case response + when Net::HTTPSuccess + else + puts response.body + response.value + end + end +end + +# Change from private to public to get git-daemon-export-ok to appear. +def make_public(repo) + uri = URI("#{SERVER_URL}/api/v1/repos/#{USERNAME}/#{repo[:name]}") + Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http| + request = Net::HTTP::Patch.new(uri) + request["Authorization"] = "token #{TOKEN}" + request.content_type = "application/json" + request.body = JSON.dump("private" => false) + response = http.request(request) + case response + when Net::HTTPSuccess + else + puts response.body + response.value + end + end +end + +def add_topic(repo, topic) + uri = URI("#{SERVER_URL}/api/v1/repos/#{USERNAME}/#{repo[:name]}/topics/#{topic}") + Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http| + request = Net::HTTP::Put.new(uri) + request["Authorization"] = "token #{TOKEN}" + response = http.request(request) + case response + when Net::HTTPSuccess + else + puts response.body + response.value + end + end +end + +def process_all(repos) + repos.each do |repo| + migrate_repo(repo) + make_public(repo) + if repo[:oldname] =~ %r{^(\S+)/} + topic = $1 + topic = { + "exp" => "experimental", + "ref" => "reference", + "util" => "utility", + }[topic] || topic + add_topic(repo, topic) + end + end +end + +gitolite_repos = read_gitolite_repos +check_unique_names(gitolite_repos) + +# Just test with one for now +#gitolite_repos.select! do |repo| +# %w[exp/jes].include?(repo[:oldname]) +#end +#gitolite_repos = [{ +# name: "rscons-test", +# description: "test rscons import", +# oldname: "rscons", +#}] + +process_all(gitolite_repos)