From 9c196504a85193797cb0a01c8a1fb866a9d07c77 Mon Sep 17 00:00:00 2001 From: Steven Harman Date: Fri, 30 Oct 2020 16:45:41 -0400 Subject: [PATCH] Differentiate between options and arguments i.e., we now use `--help` rather than a `help` sub-command. --- lib/git_tracker/runner.rb | 76 +++++++++++++++++++++++++-------- spec/git_tracker/runner_spec.rb | 47 +++++++++++--------- 2 files changed, 86 insertions(+), 37 deletions(-) diff --git a/lib/git_tracker/runner.rb b/lib/git_tracker/runner.rb index 22a12e1..3da0887 100644 --- a/lib/git_tracker/runner.rb +++ b/lib/git_tracker/runner.rb @@ -1,41 +1,81 @@ +require "optparse" require "git_tracker/prepare_commit_message" require "git_tracker/hook" require "git_tracker/repository" require "git_tracker/version" module GitTracker - module Runner - def self.call(cmd_arg = "help", *args) - command = cmd_arg.tr("-", "_") + class Runner + def self.call(*args, io: $stdout) + args << "--help" if args.empty? + options = {} - abort("[git_tracker] command: '#{cmd_arg}' does not exist.") unless respond_to?(command) + OptionParser.new { |optparse| + optparse.banner = <<~BANNER + git-tracker is a Git hook used during the normal lifecycle of committing, + rebasing, merging, etc… This hook must be initialized into each repository + in which you wish to use it. - send(command, *args) + usage: git-tracker init + BANNER + + optparse.on("-h", "--help", "Prints this help") do + io.puts(optparse) + options[:exit] = true + end + + optparse.on("-v", "--version", "Prints the git-tracker version number") do + io.puts("git-tracker #{VERSION}") + options[:exit] = true + end + }.parse!(args) + + return if options.fetch(:exit, false) + + command, *others = args + + new(command: command, arguments: others, options: options).call + end + + def initialize(command:, arguments:, options:) + @command = command + @arguments = arguments + @options = options end - def self.prepare_commit_msg(*args) - PrepareCommitMessage.call(*args) + def call + abort("[git_tracker] command: '#{command}' does not exist.") unless sub_command + + send(sub_command) end - def self.init + private + + SUB_COMMANDS = { + init: :init, + install: :install, + "prepare-commit-msg": :prepare_commit_msg + }.freeze + private_constant :SUB_COMMANDS + + attr_reader :arguments, :command, :options + + def init Hook.init(at: Repository.root) end - def self.install - warn("`git-tracker install` is deprecated. Please use `git-tracker init`", uplevel: 1) + def install + warn("`git-tracker install` is deprecated. Please use `git-tracker init`.") init end - def self.help - puts <<~HELP - git-tracker #{VERSION} is installed. + def prepare_commit_msg + PrepareCommitMessage.call(*arguments) + end - Remember, git-tracker is a hook which Git interacts with during its normal - lifecycle of committing, rebasing, merging, etc. You need to initialize this - hook by running `git-tracker init` from each repository in which you wish to - use it. Cheers! - HELP + def sub_command + @sub_command ||= SUB_COMMANDS.fetch(command.intern, false) end end end diff --git a/spec/git_tracker/runner_spec.rb b/spec/git_tracker/runner_spec.rb index 809c57a..43357a6 100644 --- a/spec/git_tracker/runner_spec.rb +++ b/spec/git_tracker/runner_spec.rb @@ -2,17 +2,14 @@ RSpec.describe GitTracker::Runner do subject(:runner) { described_class } - let(:args) { ["a_file", "the_source", "sha1234"] } describe "::call" do include OutputHelper - - before do - allow(runner).to receive(:prepare_commit_msg) { true } - end + let(:args) { ["a_file", "the_source", "sha1234"] } + let(:io) { StringIO.new } it "runs the hook, passing the args" do - expect(runner).to receive(:prepare_commit_msg).with(*args) + expect(GitTracker::PrepareCommitMessage).to receive(:call).with(*args) runner.call("prepare-commit-msg", *args) end @@ -22,27 +19,39 @@ } expect(errors.chomp).to eq("[git_tracker] command: 'non-existent-hook' does not exist.") end - end - describe ".prepare_commit_msg" do - it "runs the hook, passing the args" do - expect(GitTracker::PrepareCommitMessage).to receive(:call).with(*args) - runner.prepare_commit_msg(*args) + it "shows the help/banner for the --help option" do + runner.call("--help", io: io) + + expect(io.string).to match(/git-tracker is a Git hook used/) end - end - describe ".init" do - let(:repo_root) { "/path/to/git/repo/root" } + it "shows the version for the --version option" do + runner.call("--version", io: io) + + expect(io.string).to match(/git-tracker #{GitTracker::VERSION}/) + end it "tells the hook to initialize itself" do + repo_root = "/path/to/git/repo/root" allow(GitTracker::Repository).to receive(:root) { repo_root } + expect(GitTracker::Hook).to receive(:init).with(at: repo_root) - runner.init + + runner.call("init") end - end - it ".help reports that it was run" do - expect(runner).to receive(:puts).with(/git-tracker #{GitTracker::VERSION} is installed\./) - runner.call("help") + it "warns of deprecated install command" do + allow(GitTracker::Hook).to receive(:init) + + warnings = capture_stderr { + runner.call("install") + } + + aggregate_failures do + expect(warnings.chomp).to match(/git-tracker install.*deprecated.*git-tracker init/) + expect(GitTracker::Hook).to have_received(:init) + end + end end end