class Geordi::Gitpt

Attributes

client[RW]
highline[RW]
settings[RW]

Public Class Methods

new() click to toggle source
# File lib/geordi/gitpt.rb, line 12
def initialize
  self.highline = HighLine.new
  self.settings = Settings.new
  self.client = build_client
end

Public Instance Methods

run_branch(from_master: false) click to toggle source
# File lib/geordi/gitpt.rb, line 29
def run_branch(from_master: false)
  story = choose_story || Interaction.fail('No story selected.')

  normalized_story_name = normalize_string(story.name)

  branch_list_string = if Util.testing?
    ENV['GEORDI_TESTING_GIT_BRANCHES'] || ''
  else
    `git branch --format="%(refname:short)"`
  end

  if branch_list_string.nil? || branch_list_string.strip.empty?
    Interaction.fail 'Could not determine local git branches.'
  end

  new_branch_name = "#{git_user_initials}/#{normalized_story_name}-#{story.id}"

  local_branches = branch_list_string.split("\n")
  branch_name = local_branches.find { |branch_name| branch_name == new_branch_name }
  branch_name ||= local_branches.find { |branch_name| branch_name.include? story.id.to_s }

  if branch_name.present?
    checkout_branch branch_name, new_branch: false
  else
    checkout_branch new_branch_name, new_branch: true, from_master: from_master
  end
end
run_commit(git_args) click to toggle source
# File lib/geordi/gitpt.rb, line 18
    def run_commit(git_args)
      Interaction.warn <<~WARNING unless Util.staged_changes?
        No staged changes. Will create an empty commit.
      WARNING

      story = choose_story
      if story
        create_commit "[##{story.id}] #{story.name}", *git_args
      end
    end

Private Instance Methods

applicable_stories() click to toggle source
# File lib/geordi/gitpt.rb, line 77
def applicable_stories
  if Util.testing?
    return ENV['GEORDI_TESTING_NO_PT_STORIES'] == 'true' ? [] : [OpenStruct.new(id: 12, name: 'Test Story')]
  end

  projects = load_projects
  projects.collect do |project|
    project.stories(filter: 'state:started,finished,rejected', fields: ':default,owners(id,name)')
  end.flatten
end
bold(string) click to toggle source
# File lib/geordi/gitpt.rb, line 138
def bold(string)
  HighLine::BOLD + string + HighLine::RESET
end
build_client() click to toggle source
# File lib/geordi/gitpt.rb, line 61
def build_client
  TrackerApi::Client.new(token: settings.pivotal_tracker_api_key)
end
checkout_branch(name, new_branch: false, from_master: false) click to toggle source
# File lib/geordi/gitpt.rb, line 142
def checkout_branch(name, new_branch: false, from_master: false)
  if new_branch
    Util.run! ['git', 'checkout', 'master'] if from_master
    Util.run! ['git', 'checkout', '-b', name]
  else
    Util.run! ['git', 'checkout', name]
  end
end
choose_story() click to toggle source
# File lib/geordi/gitpt.rb, line 88
def choose_story
  loading_message = 'Connecting to Pivotal Tracker ...'
  print(loading_message)
  stories = applicable_stories
  reset_loading_message = "\r#{' ' * (loading_message.length + stories.length)}\r"

  Geordi::Interaction.fail('No stories to offer.') if stories.empty?

  if Util.testing?
    return stories[0]
  end

  my_id = client.me.id

  highline.choose do |menu|
    menu.header = 'Choose a story'

    stories.each do |story|
      state = story.current_state
      owners = story.owners
      owner_is_me = owners.collect(&:id).include?(my_id)

      if state == 'started'
        state = HighLine::GREEN + state + HighLine::RESET
      elsif state != 'finished'
        state = HighLine::RED + state + HighLine::RESET
      end

      state += HighLine::BOLD if owner_is_me

      label = "(#{owners.collect(&:name).join(', ')}, #{state}) #{story.name}"
      label = bold(label) if owner_is_me

      menu.choice(label) { return story }
    end

    menu.hidden ''
    print reset_loading_message # Once menu is build
  end

  nil # Return nothing
end
create_commit(message, *git_args) click to toggle source
# File lib/geordi/gitpt.rb, line 131
def create_commit(message, *git_args)
  extra = highline.ask("\nAdd an optional message").strip
  message << ' - ' << extra if extra != ''

  Util.run!(['git', 'commit', '--allow-empty', '-m', message, *git_args])
end
git_user_initials() click to toggle source
# File lib/geordi/gitpt.rb, line 163
def git_user_initials
  stdout_str = if Util.testing?
    ENV['GEORDI_TESTING_GIT_USERNAME']
  else
    `git config user.name`
  end

  git_user_initials = unless stdout_str.nil?
    stdout_str.strip.split(' ').map(&:chars).map(&:first).join.downcase
  end

  git_user_initials = Interaction.prompt 'Enter your initials:', git_user_initials

  if git_user_initials.nil?
    Interaction.fail('Could not determine the git user\'s initials.')
  else
    git_user_initials
  end
end
load_projects() click to toggle source
# File lib/geordi/gitpt.rb, line 65
def load_projects
  project_ids = settings.pivotal_tracker_project_ids
  project_ids.collect do |project_id|
    begin
      client.project(project_id)
    rescue TrackerApi::Errors::ClientError
      puts # Start a new line
      Geordi::Interaction.warn "Could not access project #{project_id}. Skipping."
    end
  end.compact
end
normalize_string(name) click to toggle source
# File lib/geordi/gitpt.rb, line 151
def normalize_string(name)
  name.gsub!('ä', 'ae')
  name.gsub!('ö', 'oe')
  name.gsub!('ü', 'ue')
  name.gsub!('ß', 'ss')
  name.tr!('^A-Za-z0-9_ ', '')
  name.squeeze! ' '
  name.gsub!(' ', '-')
  name.downcase!
  name
end