require 'rugged' module Ginatra class Repo attr_reader :name, :param, :description # Create a new repository, and sort out clever stuff including assigning # the param, the name and the description. # # @param [String] path a path to the repository you want created # @return [Ginatra::Repo] a repository instance def initialize(path) @repo = Rugged::Repository.new(path) @param = File.split(path).last @name = @param @description = '' if File.exists?("#{@repo.path}description") @description = File.read("#{@repo.path}description").strip @description = '' if @description.match(/\AUnnamed repository;/) end end # Return a commit corresponding to sha in the repo. # # @param [String] sha the commit id or tag name # @return [Rugged::Commit] the commit object def commit(sha) @repo.lookup(sha) end # Return a commit corresponding to tag in the repo. def commit_by_tag(name) target = @repo.ref("refs/tags/#{name}").target if target.is_a? Rugged::Tag::Annotation target = target.target end target end # Return a list of commits in a certain branch, including pagination options and all the refs. # # @param [String] start the branch to look for commits in # @param [Integer] max_count the maximum count of commits # @param [Integer] skip the number of commits in the branch to skip before taking the count. # # @return [Array] the array of commits. def commits(branch='master', max_count=10, skip=0) raise Ginatra::InvalidRef unless branch_exists?(branch) walker = Rugged::Walker.new(@repo) walker.sorting(Rugged::SORT_TOPO) walker.push(@repo.ref("refs/heads/#{branch}").target) commits = walker.collect {|commit| commit } commits[skip, max_count] end # Returns list of branches sorted by name alphabetically def branches @repo.branches.each(:local).sort_by {|b| b.name } end # Returns list of branches containing the commit def branches_with(commit) b = [] branches.each do |branch| walker = Rugged::Walker.new(@repo) walker.sorting(Rugged::SORT_TOPO) walker.push(@repo.ref("refs/heads/#{branch.name}").target) walker.collect { |c| b << branch if c.oid == commit } end b end # Checks existence of branch by name def branch_exists?(branch_name) @repo.branches.exists?(branch_name) end # Find blob by oid def find_blob(oid) Rugged::Blob.new @repo, oid end # Find tree by tree oid or branch name def find_tree(oid) if branch_exists?(oid) last_commit_sha = @repo.ref("refs/heads/#{oid}").target.oid lookup(last_commit_sha).tree else lookup(oid) end end # Returns Rugged::Repository instance def to_rugged @repo end # Catch all # # @todo update respond_to? method def method_missing(sym, *args, &block) if @repo.respond_to?(sym) @repo.send(sym, *args, &block) else super end end # to correspond to the #method_missing definition def respond_to?(sym) @repo.respond_to?(sym) || super end end end