Class: Ninny::Git

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/ninny/git.rb

Constant Summary collapse

NO_BRANCH =
"(no branch)"
DEFAULT_DIRTY_MESSAGE =
"Your Git index is not clean. Commit, stash, or otherwise clean up the index before continuing."
DIRTY_CONFIRM_MESSAGE =
"Your Git index is not clean. Do you want to continue?"
DEPLOYABLE_PREFIX =

branch prefixes

"deployable"
STAGING_PREFIX =
"staging"
QAREADY_PREFIX =
"qaready"
CheckoutFailed =

Exceptions

Class.new(StandardError)
NotOnBranch =
Class.new(StandardError)
NoBranchOfType =
Class.new(StandardError)
DirtyIndex =
Class.new(StandardError)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeGit

Returns a new instance of Git.



19
20
21
# File 'lib/ninny/git.rb', line 19

def initialize
  @git = ::Git.open(Dir.pwd)
end

Instance Attribute Details

#gitObject (readonly)

Returns the value of attribute git.



17
18
19
# File 'lib/ninny/git.rb', line 17

def git
  @git
end

Instance Method Details

#alert_dirty_index(message) ⇒ Object

Public: Display the message and show the git status

Raises:



144
145
146
147
148
149
150
# File 'lib/ninny/git.rb', line 144

def alert_dirty_index(message)
  prompt.say " "
  prompt.say message
  prompt.say " "
  prompt.say command('status')
  raise DirtyIndex
end

#branches_for(prefix) ⇒ Object

Public: List of branches starting with the given string

prefix - String to match branch names against

Returns an Array of Branches containing the branch name



110
111
112
113
114
# File 'lib/ninny/git.rb', line 110

def branches_for(prefix)
  remote_branches.select do |branch|
    branch.name =~ /^#{prefix}/
  end
end

#check_out(branch, do_after_pull = true) ⇒ Object

Public: Check out the given branch name

branch_name - The name of the branch to check out do_after_pull - Should a pull be done after checkout?



67
68
69
70
71
72
73
74
# File 'lib/ninny/git.rb', line 67

def check_out(branch, do_after_pull=true)
  git.fetch
  branch.checkout
  pull if do_after_pull
  unless current_branch.name == branch.name
    raise CheckoutFailed, "Failed to check out '#{branch}'"
  end
end

#clean?Boolean

Public: Whether the Git index is clean (has no uncommited changes)

Returns a Boolean

Returns:

  • (Boolean)


129
130
131
# File 'lib/ninny/git.rb', line 129

def clean?
  command('status', '--short').empty?
end

#command(*args) ⇒ Object



23
24
25
# File 'lib/ninny/git.rb', line 23

def command(*args)
  git.lib.send(:command, *args)
end

#current_branchObject



27
28
29
# File 'lib/ninny/git.rb', line 27

def current_branch
  git.branch(current_branch_name)
end

#current_branch_nameObject



31
32
33
34
35
36
37
38
# File 'lib/ninny/git.rb', line 31

def current_branch_name
  name = git.current_branch
  if name == NO_BRANCH
    raise NotOnBranch, "Not currently checked out to a particular branch"
  else
    name
  end
end

#delete_branch(branch_name) ⇒ Object

Public: Delete the given branch

branch_name - The name of the branch to delete



91
92
93
94
95
# File 'lib/ninny/git.rb', line 91

def delete_branch(branch_name)
  branch = branch_name.is_a?(::Git::Branch) ? branch_name : git.branch(branch_name)
  git.push('origin', ":#{branch}")
  branch.delete
end

#if_clean(message = DEFAULT_DIRTY_MESSAGE) ⇒ Object

Public: Perform the block if the Git index is clean



134
135
136
137
138
139
140
141
# File 'lib/ninny/git.rb', line 134

def if_clean(message=DEFAULT_DIRTY_MESSAGE)
  if clean? || prompt.yes?(DIRTY_CONFIRM_MESSAGE)
    yield
  else
    alert_dirty_index message
    exit 1
  end
end

#latest_branch_for(prefix) ⇒ Object

Public: Most recent branch starting with the given string

prefix - String to match branch names against

Returns an Array of Branches containing the branch name



121
122
123
# File 'lib/ninny/git.rb', line 121

def latest_branch_for(prefix)
  branches_for(prefix).last || raise(NoBranchOfType, "No #{prefix} branch")
end

#merge(branch_name) ⇒ Object



40
41
42
43
44
45
46
47
# File 'lib/ninny/git.rb', line 40

def merge(branch_name)
  if_clean do
    git.fetch
    command 'merge', ['--no-ff', "origin/#{branch_name}"]
    raise MergeFailed unless clean?
    push
  end
end

#new_branch(new_branch_name, source_branch_name) ⇒ Object

Public: Create a new branch from the given source

new_branch_name - The name of the branch to create source_branch_name - The name of the branch to branch from



80
81
82
83
84
85
86
# File 'lib/ninny/git.rb', line 80

def new_branch(new_branch_name, source_branch_name)
  git.fetch
  command('branch', ['--no-track', new_branch_name, "origin/#{source_branch_name}"])
  new_branch = branch(new_branch_name)
  new_branch.checkout
  command('push', ['-u', 'origin', new_branch_name])
end

#prompt(**options) ⇒ Object



152
153
154
155
# File 'lib/ninny/git.rb', line 152

def prompt(**options)
  require 'tty-prompt'
  TTY::Prompt.new(options)
end

#pullObject

Public: Pull the latest changes for the checked-out branch



57
58
59
60
61
# File 'lib/ninny/git.rb', line 57

def pull
  if_clean do
    command('pull')
  end
end

#pushObject

Public: Push the current branch to GitHub



50
51
52
53
54
# File 'lib/ninny/git.rb', line 50

def push
  if_clean do
    git.push('origin', current_branch_name)
  end
end

#remote_branchesObject

Public: The list of branches on GitHub

Returns an Array of Strings containing the branch names



100
101
102
103
# File 'lib/ninny/git.rb', line 100

def remote_branches
  git.fetch
  git.branches.remote.map{ |branch| git.branch(branch.name) }.sort_by(&:name)
end