| 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 |