diff --git a/README.md b/README.md index eb62f22..5b17714 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## What is it? -In the git game, you guess who made a commit to your team's repo based on their commit message: +In the git game, you guess who made a commit to your team's repo based on their commit message: ![](https://cloud.githubusercontent.com/assets/21294/6428030/ba13a98c-bf60-11e4-92fa-ae25302e9a84.png) @@ -13,7 +13,7 @@ The goal is to get the longest streak! (It's harder than you think...) - [Download the `git-game` executable](https://github.com/jsomers/git-game/releases/tag/1.2) - Put it somewhere on your PATH (like /usr/local/bin) - Then, in any git repository, run `git game` -- (If you'd like, you can select a subset of commits, for example, `git game --after={2014-08-08}`. For more options, see [http://gitref.org/inspect/](http://gitref.org/inspect/).) +- (If you'd like, you can select a subset of commits, for example, `git game --after={2014-08-08}`. For more options, see [Git - git-log documentation](https://git-scm.com/docs/git-log).) ## Requirements diff --git a/git-game b/git-game index 503eb61..00251d7 100755 --- a/git-game +++ b/git-game @@ -1,68 +1,93 @@ #!/usr/bin/ruby +# frozen_string_literal: true + +require 'English' longest_streak = streak = 0 +difficulty = :normal # -- Exit gracefully -- -Signal.trap("INT") { +Signal.trap('INT') do puts "\nLongest streak: #{longest_streak}" exit 0 -} +end def print_header - puts "----------------------------------------------------------" - puts " THE GIT GAME " - puts "----------------------------------------------------------" - puts "Welcome! The goal of the git game is to guess committers" - puts "based on their commit messages.\n\n" + puts <<~TXT + ---------------------------------------------------------- + THE GIT GAME + ---------------------------------------------------------- + Welcome! The goal of the git game is to guess committers + based on their commit messages. + + TXT end def print_help - puts "----------------------------------------------------------" - puts " USAGE " - puts "----------------------------------------------------------" - puts "git game [extra git log options]" - puts "EX: git game --after={2014-08-08}" - puts "(This script already uses --no-merges and --pretty." - puts "For more valid options see: http://gitref.org/inspect/)" + puts <<~TXT + ---------------------------------------------------------- + USAGE + ---------------------------------------------------------- + git game [options] + + Flags: + -h Show this help message + --hard Opt into a challenge (git game classic) + + Extra options can be passed directly to git log: + + EX: git game --after={2014-08-08} + (This script already uses --no-merges and --pretty. + For more valid options see: https://git-scm.com/docs/git-log) + TXT +end + +def print_commit_preview(sha, difficulty) + details_args = { + normal: "--pretty='(%ar)%n%B' --shortstat", + hard: "--pretty='(%ar)%n%B' --no-patch" + }[difficulty] + + puts `git show #{sha} #{details_args}` + puts "\n\n" end -# -- Usage Text -- -if ARGV.count > 0 && (input = ARGV.shift) == 'help' +# -- Command line options -- +used_args = [] +if ARGV.include?('help') || + ARGV.include?('--help') || + ARGV.include?('-h') print_header print_help exit 0 +elsif ARGV.include?('--hard') + used_args << '--hard' + difficulty = :hard end - -# -- Parse commits -- -COMMIT_DELIMITER = "XXXCOMMITXXX" -FIELD_DELIMITER = "|||" - -commit_format = ["%an", "%ar", "%B"].join(FIELD_DELIMITER) - -raw_commits = `git log --no-merges --pretty="#{COMMIT_DELIMITER}#{commit_format}" #{input if input}`.split("#{COMMIT_DELIMITER}") -commits = [] -raw_commits.each do |c| - next if c.strip.empty? - - fields = c.split(FIELD_DELIMITER) - commits << {:author => fields[0], :date => fields[1], :message => fields[2]} -end - -committers = commits.map { |c| c[:author] }.compact.uniq +input = ARGV.reject { |arg| used_args.include?(arg) }.join(' ') +ARGV.clear + +# -- Fetch Repository Info -- +commit_shas = `git log --no-merges --pretty=%H -z #{input}` + .split("\0") + .shuffle +exit $CHILD_STATUS.exitstatus unless $CHILD_STATUS.success? +committers = `git log --no-merges --pretty=%aN | sort -u` + .split("\n") + .map(&:strip) # -- Show welcome message -- system('clear') print_header -puts "You're playing in a repo with #{commits.size} commits and #{committers.size}" +puts "You're playing in a repo with #{commit_shas.size} commits and #{committers.size}" puts "distinct committers.\n\n" committers.each do |committer| puts committer end -puts "Ready? PRESS ENTER TO START PLAYING (Ctrl-C to quit)" - +puts 'Ready? PRESS ENTER TO START PLAYING (Ctrl-C to quit)' gets system('clear') @@ -70,40 +95,29 @@ system('clear') # -- Game loop -- NUM_CHOICE = 4 -loop do - commit = commits.shuffle.pop - message = commit[:message] - author = commit[:author] - - next if message.nil? || message.empty? || author.nil? || author.empty? +commit_shas.each do |sha| + print_commit_preview(sha, difficulty) - puts "(#{commit[:date]})\n" - puts "#{message.strip}\n\n" - puts - - choices = committers.sample(NUM_CHOICE) - if !choices.include?(author) - choices.pop - choices.push author - end + author = `git show #{sha} --pretty=%aN --no-patch`.strip + choices = [author] + choices += committers.reject do |name| + name == author + end.sample(NUM_CHOICE - 1) choices.shuffle! choices.each_with_index do |name, index| puts "[#{index + 1}] #{name}" end - print "Who wrote it (current streak: #{streak})? " - - guess = gets.strip - - while guess.empty? || !guess.to_i.between?(1, NUM_CHOICE) + guess = nil + until guess.to_i.between?(1, NUM_CHOICE) print "Who wrote it (current streak: #{streak})? " guess = gets.strip end if choices[guess.to_i - 1] == author streak += 1 - puts "Got it!" + puts 'Got it!' else streak = 0 puts "Actually, it was #{author}." @@ -111,6 +125,14 @@ loop do longest_streak = [longest_streak, streak].max - sleep 1 + puts "\nEnter to go to next question" + gets system('clear') end + +puts <<~TXT + Congratulations! There are no more commits in this repo! + + Longest streak: #{longest_streak} +TXT +exit 0