Created
December 3, 2014 22:59
-
-
Save dergachev/d024800b4514de64fcb3 to your computer and use it in GitHub Desktop.
Initial draft for redmine_git_remote, deprecated; see https://github.com/dergachev/redmine_git_remote
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# initial draft for redmine_git_remote, deprecated | |
module RepositoryFetch | |
def self.logger | |
::Rails.logger | |
end | |
PATTERNS = [ | |
{ :pattern => "/redmine_git_fetch/github.com/", | |
:uri_prefix => "[email protected]:", | |
:host => "github.com", | |
:key => "/home/redmine/data/keys/id_rsa" | |
}, | |
{ :pattern => "/redmine_git_fetch/gitlab.com/", | |
:uri_prefix => "[email protected]:", | |
:host => "gitlab.com", | |
:key => "/home/redmine/data/keys/id_rsa" | |
}, | |
{ :pattern => "/redmine_git_fetch/git.ewdev.ca/", | |
:uri_prefix => "[email protected]:", | |
:host => "git.ewdev.ca", | |
:key => "/home/redmine/data/keys/id_rsa" | |
} | |
] | |
def self.clone_or_fetch(repository) | |
return unless repository.scm_name == "Git" | |
path = repository.url | |
p = PATTERNS.find { |p| path.starts_with? p[:pattern] } | |
unless p | |
# TODO: figure out how to handle non-matching repos. | |
# eg. skip them, try fetching them, throw warning or not? | |
proj = repository.project.identifier | |
logger.warn "repository_fetch: no match for '#{path}' in project '#{proj}'" | |
return | |
end | |
RepositoryFetch::add_known_host(p[:host]) | |
# If dir exists and non-empty, should be safe to 'git fetch' | |
if Dir.exists?(path) && Dir.entries(path) != [".", ".."] | |
puts "Running git fetch on #{path}" | |
puts exec_with_key "git -C #{path} fetch --all", p[:key] | |
else | |
# try cloning the repo | |
url = path.sub( p[:pattern], p[:uri_prefix]) | |
puts "Matched new URL, trying to clone: " + url | |
puts exec_with_key "git clone --mirror #{url} #{path}", p[:key] | |
end | |
end | |
def self.clone_empty(repository) | |
clone_path = repository.clone_path | |
clone_url = repository.clone_url | |
clone_host = repository.clone_host | |
RepositoryFetch::add_known_host(clone_host) | |
if Dir.exists? clone_path | |
raise "Clone path already exits: #{clone_path}" | |
end | |
unless system "git ls-remote -h #{clone_url}" | |
# TODO: put in validation error | |
raise "Invalid remote; unable to clone #{clone_url}" | |
end | |
unless system "git init --bare #{clone_path}" | |
#TODO validation error | |
raise "Unable to run git init at #{clone_path}" | |
end | |
unless system "git -C #{clone_path} remote add --tags --mirror=fetch origin #{clone_url}" | |
#TODO validation error | |
raise "Unable to run: git -C #{clone_path} remote add #{clone_url}" | |
end | |
end | |
def self.exec_with_key(cmd, keyfile) | |
return `ssh-agent bash -c 'ssh-add #{keyfile}; #{cmd}'` | |
end | |
def self.fetch | |
Project.active.has_module(:repository).all.each do |project| | |
project.repositories.each do |repository| | |
clone_or_fetch(repository) | |
end | |
end | |
end | |
# Checks if host is in ~/.ssh/known_hosts, adds it if not present | |
def self.add_known_host(host) | |
# if not found... | |
if `ssh-keygen -F #{host} | grep 'found'` == "" | |
# hack to work with 'docker exec' where HOME isn't set (or set to /) | |
ssh_known_hosts = (ENV['HOME'] == "/" or ENV['HOME'] == nil ? "/root" : ENV['HOME']) + "/.ssh/known_hosts" | |
puts "Authorizing #{host}" | |
puts `ssh-keyscan #{host} >> #{ssh_known_hosts}` | |
end | |
end | |
class Fetch | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment