diff --git a/Library/Homebrew/cmd/log.rb b/Library/Homebrew/cmd/log.rb index 06223b4b47..d783af51b5 100644 --- a/Library/Homebrew/cmd/log.rb +++ b/Library/Homebrew/cmd/log.rb @@ -1,83 +1,88 @@ # typed: true # frozen_string_literal: true -require "cli/parser" +require "abstract_command" +require "fileutils" module Homebrew - sig { returns(CLI::Parser) } - def self.log_args - Homebrew::CLI::Parser.new do - description <<~EOS - Show the `git log` for or , or show the log for the Homebrew repository - if no formula or cask is provided. - EOS - switch "-p", "-u", "--patch", - description: "Also print patch from commit." - switch "--stat", - description: "Also print diffstat from commit." - switch "--oneline", - description: "Print only one line per commit." - switch "-1", - description: "Print only one commit." - flag "-n", "--max-count=", - description: "Print only a specified number of commits." - switch "--formula", "--formulae", - description: "Treat all named arguments as formulae." - switch "--cask", "--casks", - description: "Treat all named arguments as casks." + module Cmd + class Log < AbstractCommand + include FileUtils - conflicts "-1", "--max-count" - conflicts "--formula", "--cask" - - named_args [:formula, :cask], max: 1, without_api: true - end - end - - def self.log - args = log_args.parse - - # As this command is simplifying user-run commands then let's just use a - # user path, too. - ENV["PATH"] = PATH.new(ORIGINAL_PATHS).to_s - - if args.no_named? - git_log(HOMEBREW_REPOSITORY, args:) - else - path = args.named.to_paths.first - tap = Tap.from_path(path) - git_log path.dirname, path, tap, args: - end - end - - def self.git_log(cd_dir, path = nil, tap = nil, args:) - cd cd_dir do - repo = Utils.popen_read("git", "rev-parse", "--show-toplevel").chomp - if tap - name = tap.to_s - git_cd = "$(brew --repo #{tap})" - elsif cd_dir == HOMEBREW_REPOSITORY - name = "Homebrew/brew" - git_cd = "$(brew --repo)" - else - name, git_cd = cd_dir - end - - if File.exist? "#{repo}/.git/shallow" - opoo <<~EOS - #{name} is a shallow clone so only partial output will be shown. - To get a full clone, run: - git -C "#{git_cd}" fetch --unshallow + cmd_args do + description <<~EOS + Show the `git log` for or , or show the log for the Homebrew repository + if no formula or cask is provided. EOS + switch "-p", "-u", "--patch", + description: "Also print patch from commit." + switch "--stat", + description: "Also print diffstat from commit." + switch "--oneline", + description: "Print only one line per commit." + switch "-1", + description: "Print only one commit." + flag "-n", "--max-count=", + description: "Print only a specified number of commits." + switch "--formula", "--formulae", + description: "Treat all named arguments as formulae." + switch "--cask", "--casks", + description: "Treat all named arguments as casks." + + conflicts "-1", "--max-count" + conflicts "--formula", "--cask" + + named_args [:formula, :cask], max: 1, without_api: true end - git_args = [] - git_args << "--patch" if args.patch? - git_args << "--stat" if args.stat? - git_args << "--oneline" if args.oneline? - git_args << "-1" if args.public_send(:"1?") - git_args << "--max-count" << args.max_count if args.max_count - git_args += ["--follow", "--", path] if path.present? - system "git", "log", *git_args + sig { override.void } + def run + # As this command is simplifying user-run commands then let's just use a + # user path, too. + ENV["PATH"] = PATH.new(ORIGINAL_PATHS).to_s + + if args.no_named? + git_log(HOMEBREW_REPOSITORY, args:) + else + path = args.named.to_paths.first + tap = Tap.from_path(path) + git_log T.must(path).dirname, path, tap + end + end + + private + + def git_log(cd_dir, path = nil, tap = nil) + cd cd_dir do + repo = Utils.popen_read("git", "rev-parse", "--show-toplevel").chomp + if tap + name = tap.to_s + git_cd = "$(brew --repo #{tap})" + elsif cd_dir == HOMEBREW_REPOSITORY + name = "Homebrew/brew" + git_cd = "$(brew --repo)" + else + name, git_cd = cd_dir + end + + if File.exist? "#{repo}/.git/shallow" + opoo <<~EOS + #{name} is a shallow clone so only partial output will be shown. + To get a full clone, run: + git -C "#{git_cd}" fetch --unshallow + EOS + end + + git_args = [] + git_args << "--patch" if args.patch? + git_args << "--stat" if args.stat? + git_args << "--oneline" if args.oneline? + git_args << "-1" if args.public_send(:"1?") + git_args << "--max-count" << args.max_count if args.max_count + git_args += ["--follow", "--", path] if path.present? + system "git", "log", *git_args + end + end end end end diff --git a/Library/Homebrew/test/cmd/log_spec.rb b/Library/Homebrew/test/cmd/log_spec.rb index c89c86d0d0..4f91f9aeb2 100644 --- a/Library/Homebrew/test/cmd/log_spec.rb +++ b/Library/Homebrew/test/cmd/log_spec.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true +require "cmd/log" require "cmd/shared_examples/args_parse" -RSpec.describe "brew log" do +RSpec.describe Homebrew::Cmd::Log do it_behaves_like "parseable arguments" it "shows the Git log for a given Formula", :integration_test do