diff options
author | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-12-15 04:36:19 -0500 |
---|---|---|
committer | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-12-15 04:36:19 -0500 |
commit | 381a9b85d4ea82c5792fcc75383b2d0d98b72100 (patch) | |
tree | 182f7421375f771c210405e8586674b2a9f31c06 /git-mirror-gitlab-ce | |
parent | 445d6d320e75917eb6678648b1571be97cf3dcd9 (diff) |
more
Diffstat (limited to 'git-mirror-gitlab-ce')
-rwxr-xr-x | git-mirror-gitlab-ce | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/git-mirror-gitlab-ce b/git-mirror-gitlab-ce new file mode 100755 index 0000000..a8d885e --- /dev/null +++ b/git-mirror-gitlab-ce @@ -0,0 +1,202 @@ +#!/usr/bin/env ruby +# coding: utf-8 + +load 'git-mirror-backend.rb' +require 'net/http' +require 'uri' +require 'cgi' +require 'json' + +class GitLabCE < GitMirrorBackend + class Error < RuntimeError + def initialize(obj) + @obj = obj + end + def obj + return @obj + end + end + + def initialize() + @connections = {} + @projects = {} + @config = {} + end + + def connection(uri) + key=URI(uri.scheme+":") + key.host = uri.host + key.port = uri.port + + @connections[key] ||= Net::HTTP::start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') + return @connections[key] + end + + def finish + @connections.each do |k,v| + v.finish() + end + @connections = {} + super + end + + def config + return @config + end + + # Project + def project(project_id) + unless @projects.has_key?(project_id) + @projects[project_id] = Project.new(self, project_id) + end + return @projects[project_id] + end + class Project + def initialize(gl, project_id) + @gl = gl + @project_id = project_id + @cache = {} + end + + def info + unless @cache.has_key?(:info) + req = Net::HTTP::Get.new(@gl.config['apiurl'] + "projects/" + CGI::escape(@project_id)) + req.add_field("PRIVATE-TOKEN", @gl.config['apikey']) + res = @gl.connection(req.uri).request(req) + case res.code + when "200" + @cache[:info] = JSON::parse(res.body) + when "404" + @cache[:info] = nil + else + raise Error.new(res) + end + end + return @cache[:info] + end + + def info=(i) + @cache[:info] = i + end + + def get_meta + return self.info.select{|k,v| @vars.include?(k.to_sym)} + end + + def set_meta(map) + mirror = map["mirror"] + map.delete("mirror") + + illegal = map.select{|k,v| not @vars.include?(k.to_sym)} + if illegal.count > 0 + raise Error.new(illegal) + end + + if info == nil + # create + req = Net::HTTP::Put.new(@gl.config['apiurl'] + "projects") + req.add_field("PRIVATE-TOKEN", @gl.config['apikey']) + req.add_field("Content-Type", "application/json") + map["path"] = @project_id + if not mirror.nil? + map["import_url"] = mirror + end + req.body = JSON::dump(map) + res = @gl.connection(req.uri).request(req) + if res.code != "201" + raise Error.new(res) + end + info = JSON::parse(res.body) + else + # update + req = Net::HTTP::Put.new(@gl.config['apiurl'] + "projects/" + CGI::escape(info["id"].to_s)) + req.add_field("PRIVATE-TOKEN", @gl.config['apikey']) + req.add_field("Content-Type", "application/json") + req.body = JSON::dump(map) + res = @gl.connection(req.uri).request(req) + if res.code != "200" + raise Error.new(res) + end + info = JSON::parse(res.body) + end + return self.get_meta + end + + def repo_mode + return "passive" + end + end + + # commands + def cmd_config(*args) + args.each do |arg| + key, val = arg.split('=', 2) + case key + when "apiurl" + val = URI(val) + unless val.path.end_with?("/") + val.path += "/" + end + end + @config[key] = val + end + end + + def cmd_get_meta(project_id) + return self.project(project_id).get_meta() + end + + def cmd_set_meta(project_id, *pairs) + map = {} + pairs.each do |pair| + key, val = arg.split('=', 2) + map[key] = val + end + return self.project(project_id).set_meta(map) + end + + def cmd_push_url(project_id) + return self.project(project_id).info["ssh_url_to_repo"] + end + + def cmd_pull_url(project_id) + return self.project(project_id).info["http_url_to_repo"] + end + + def cmd_repo_mode(project_id) + return self.project(projecT_id).repo_mode() + end + + def vars + # API docs suck, look at `lib/api/projects.rb` instead. + return [ + :builds_enabled, # create | create-user | edit + :container_registry_enabled, # XXX # create | | edit + :default_branch, # | create-user | edit + :description, # create | create-user | edit + #:import_url, # XXX # create | create-user | + :issues_enabled, # create | create-user | edit + :lfs_enabled, # create | create-user | edit + :merge_requests_enabled, # create | create-user | edit + :name, # create | create-user | edit + #:namespace_id, # create | | + :only_allow_merge_if_build_succeeds, # create | create-user | edit + #:path, # create | | edit + :public, # create | create-user | edit + :public_builds, # create | create-user | edit + :request_access_enabled, # create | create-user | edit + :shared_runners_enabled, # create | create-user | edit + :snippets_enabled, # create | create-user | edit + :visibility_level, # create | create-user | edit + :wiki_enabled, # create | create-user | edit + :only_allow_merge_if_all_discussions_are_resolved # create | create-user | edit + ] + end +end + +if __FILE__ == $0 + if ARGV.length != 1 + raise "Usage: $0 ACCOUNT_NAME" + end + GitLabCE.new().repl(ARGV[1]) +end |