# frozen_string_literal: true module Groundskeeper # Wraps git executable and adds a few convenience methods on top. class Git COMMAND = "git" # git arguments STATUS = "status" FETCH_WITH_TAGS = "fetch --tags" VERSION = "--version" TAGS_ASC = "tag -l --sort=v:refname" TAGS_DESC = "tag -l --sort=-v:refname" LATEST_TAG_COMMIT = "#{COMMAND} rev-list --tags --max-count=1" LATEST_TAG_NAME = format("describe --tags $(%s)", commit: LATEST_TAG_COMMIT) LATEST_TAG_BRANCHES = format("branch --contains $(%s)", commit: LATEST_TAG_COMMIT) LATEST_CHANGES = "log %s..HEAD --oneline" CREATE_AND_CHECKOUT_BRANCH = "checkout -b %s" ADD_UPDATE = "add -u" ADD_ALL = "add ." COMMIT = "commit -m \"%s\"" ADD_TAG = "tag %s" PUSH_HEAD_WITH_TAGS = "push origin head --tags" PULL = "-C #{Dir.home}/%s pull" REMOTE_URL = "-C #{Dir.home}/%s config --get remote.origin.url" ORIGIN_URL = "config --get remote.origin.url" attr_reader :git def self.build new Executable.new(COMMAND) end def initialize(git) @git = git end def status git.execute(STATUS) end def fetch git.execute(FETCH_WITH_TAGS) end def version semantic_version = /\d+.\d+.\d+/ git.execute(VERSION).match(semantic_version)[0] end def list_tags git.execute(TAGS_ASC) end def fetch_and_list_tags git.execute(FETCH_WITH_TAGS) git.execute(TAGS_DESC).split("\n") end def latest_tag_name_across_branches git.execute(LATEST_TAG_NAME).chop end def branches_containing_latest_tag git.execute(LATEST_TAG_BRANCHES).split("\n").map(&:strip) end def raw_changes_since_latest_tag latest_changes = format(LATEST_CHANGES, latest_tag_name_across_branches) git.execute(latest_changes).split("\n") end def create_and_checkout_branch(name) git.execute(format(CREATE_AND_CHECKOUT_BRANCH, name)) end def add_update git.execute(ADD_UPDATE) end def add_all git.execute(ADD_ALL) end def commit(message) git.execute(format(COMMIT, message)) end def add_tag(name) git.execute(format(ADD_TAG, name)) end def push_with_tags git.execute(PUSH_HEAD_WITH_TAGS) end def pull(name) git.execute(format(PULL, name)) end def remote_url(name) git.execute(format(REMOTE_URL, name)) end def origin_url git.execute(ORIGIN_URL).strip end end end