lib/r10k/git/repository.rb in r10k-1.1.4 vs lib/r10k/git/repository.rb in r10k-1.2.0rc1

- old
+ new

@@ -1,74 +1,103 @@ -require 'r10k/execution' -require 'r10k/git/errors' +require 'r10k/git' +require 'r10k/util/subprocess' -module R10K -module Git -class Repository - # Define an abstract base class for git repositories. +# Define an abstract base class for git repositories. +class R10K::Git::Repository - include R10K::Execution - # @!attribute [r] remote # @return [String] The URL to the git repository attr_reader :remote # @!attribute [r] basedir - # @return [String] The basedir for the working directory + # @return [String] The directory containing the repository attr_reader :basedir # @!attribute [r] dirname - # @return [String] The name for the directory + # @return [String] The name of the directory attr_reader :dirname - # Resolve a ref to a commit hash + # @!attribute [r] git_dir + # Set the path to the git directory. For git repositories with working copies + # this will be `$working_dir/.git`; for bare repositories this will be + # `bare-repo.git` + # @return [String] The path to the git directory + attr_reader :git_dir + + # Resolve a ref to a git commit. The given pattern can be a commit, tag, + # or a local or remote branch # - # @param [String] ref + # @param [String] pattern # - # @return [String] The dereferenced hash of `ref` - def rev_parse(ref) - commit = git "rev-parse #{ref}^{commit}", :git_dir => git_dir - commit.chomp - rescue R10K::ExecutionFailure - raise R10K::Git::NonexistentHashError.new(ref, git_dir) + # @return [String] The dereferenced hash of `pattern` + def resolve_ref(pattern) + commit = nil + begin + all_commits = git ['show-ref', '-s', pattern], :git_dir => git_dir + commit = all_commits.lines.first + rescue R10K::Util::Subprocess::SubprocessError + end + + if commit.nil? + begin + commit = git ['rev-parse', "#{ref}^{commit}"], :git_dir => git_dir + rescue R10K::Util::Subprocess::SubprocessError + end + end + + if commit + commit.chomp + else + raise R10K::Git::UnresolvableRefError.new(:ref => pattern, :git_dir => git_dir) + end end + alias rev_parse resolve_ref + private + + # Fetch objects and refs from the given git remote + # + # @param remote [#to_s] The remote name to fetch from + def fetch(remote = 'origin') + git ['fetch', '--prune', remote], :git_dir => @git_dir + end + # Wrap git commands # - # @param [String] command_line_args The arguments for the git prompt - # @param [Hash] opts + # @param cmd [Array<String>] cmd The arguments for the git prompt + # @param opts [Hash] opts # + # @option opts [String] :path # @option opts [String] :git_dir # @option opts [String] :work_tree - # @option opts [String] :work_tree # # @raise [R10K::ExecutionFailure] If the executed command exited with a # nonzero exit code. # # @return [String] The git command output - def git(command_line_args, opts = {}) - args = %w{git} + def git(cmd, opts = {}) + argv = %w{git} - log_event = "git #{command_line_args}" - log_event << ", args: #{opts.inspect}" unless opts.empty? - - if opts[:path] - args << "--git-dir #{opts[:path]}/.git" - args << "--work-tree #{opts[:path]}" + argv << "--git-dir" << File.join(opts[:path], '.git') + argv << "--work-tree" << opts[:path] else if opts[:git_dir] - args << "--git-dir #{opts[:git_dir]}" + argv << "--git-dir" << opts[:git_dir] end if opts[:work_tree] - args << "--work-tree #{opts[:work_tree]}" + argv << "--work-tree" << opts[:work_tree] end end - args << command_line_args - cmd = args.join(' ') + argv.concat(cmd) - execute(cmd, :event => log_event) + subproc = R10K::Util::Subprocess.new(argv) + subproc.raise_on_fail = true + subproc.logger = self.logger + + result = subproc.execute + + # todo ensure that logging always occurs even if the command fails to run + result.stdout end -end -end end