blob: 92fb6a914249abc9d6224f46708d22e61656a257 [file] [log] [blame]
require 'open3'
require 'net/http'
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'
# get a file live from github, e.g. '/apache/petri/master/info.yaml'
# returns body, status
def self.github(file, _etag = nil)
http = Net::HTTP.new(GITHUB_HOST, 443)
http.use_ssl = true
req = http.request(Net::HTTP::Get.new(file))
return req.code, req.body
end
# path to <tt>repository.yml</tt> in the source.
REPOSITORY = File.expand_path('../../../repository.yml', __dir__)
@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))
# 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)
repo_override = ASF::Config.get(:repository)
if repo_override
git_over = repo_override[:git]
if git_over
require 'wunderbar'
Wunderbar.warn("Found override for repository.yml[:git]")
@@repository_entries[:git].merge!(git_over)
end
end
@repos = Hash[Dir[*git].map { |name|
if Dir.exist? name
out, _, status =
Open3.capture3('git', 'config', '--get', 'remote.origin.url', {chdir: name})
if status.success?
[File.basename(out.chomp, '.git'), name]
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) or raise ArgumentError, "Unable to find git clone for #{name}"
result
end
end
end
if $0 == __FILE__
require 'net/http'
c, b = ASF::Git.github('/apache/petri/master/info.yaml')
p c
puts b[0..60]
c, b = ASF::Git.github('/apache/petri/master/missing.invalid')
p c
puts b
end