blob: 0f2b48e0520f680885a7b14de47eaa41b1ec0ccd [file] [log] [blame]
require 'thread'
require 'open3'
module ASF
#
# Provide access to files stored in Git, generally to local clones that
# are updated via cronjobs.
#
class Git
# host which can be used to get raw content from git repositories hosted
# at GitHub.
GITHUB_HOST = 'raw.githubusercontent.com'
# path to the deployment branch on GitHub.
INFRA_PUPPET = '/apache/infrastructure-puppet/deployment/'
# get a file live from infrastructure puppet (e.g. 'data/common.yaml')
# issues a HTTP GET request, so may be slow and may fail. For applications
# that require faster and more dependable access,
# <tt>ASF::Git.find('infrastructure-puppet')</tt> may be used to get
# access to a clone that is updated every 10 minutes.
def self.infra_puppet(file)
file = INFRA_PUPPET + file
http = Net::HTTP.new(GITHUB_HOST, 443)
http.use_ssl = true
http.request(Net::HTTP::Get.new(file)).body
end
# path to <tt>repository.yml</tt> in the source.
REPOSITORY = File.expand_path('../../../../repository.yml', __FILE__).
untaint
@semaphore = Mutex.new
@@repository_mtime = nil
@@repository_entries = nil
#
# Scan a list of git directories, looking for local clones.
#
def self.repos
@semaphore.synchronize do
git = Array(ASF::Config.get(:git)).map {|dir| dir.untaint}
# reload if repository changes
if File.exist?(REPOSITORY) && @@repository_mtime!=File.mtime(REPOSITORY)
@repos = nil
end
unless @repos
@@repository_mtime = File.exist?(REPOSITORY) && File.mtime(REPOSITORY)
@@repository_entries = YAML.load_file(REPOSITORY)
@repos = Hash[Dir[*git].map { |name|
next unless Dir.exist? name.untaint
Dir.chdir name.untaint do
out, _, status =
Open3.capture3(*%(git config --get remote.origin.url))
if status.success?
[File.basename(out.chomp, '.git'), Dir.pwd.untaint]
end
end
}.compact]
end
@repos
end
end
# Get all the Git repo entries
def self.repo_entries
self.repos # refresh @@repository_entries
@@repository_entries[:git]
end
#
# Find a local git clone. Raises an exception if not found.
#
def self.[](name)
self.find!(name)
end
#
# Find a local git clone. Returns <tt>nil</tt> if not found.
#
def self.find(name)
repos[name]
end
#
# Find a local git clone. Raises an exception if not found.
#
def self.find!(name)
result = self.find(name)
if not result
raise Exception.new("Unable to find git clone for #{name}")
end
result
end
end
end