Class: Pro::Commands

Inherits:
Object
  • Object
show all
Defined in:
lib/pro/commands.rb

Constant Summary collapse

EMPTY_MESSAGE =
'empty'.green
UNCOMMITTED_MESSAGE =
'uncommitted'.red
UNTRACKED_MESSAGE =
'untracked'.magenta
UNPUSHED_MESSAGE =
'unpushed'.blue
JOIN_STRING =
' + '

Instance Method Summary collapse

Constructor Details

#initialize(index) ⇒ Commands

Returns a new instance of Commands.



38
39
40
# File 'lib/pro/commands.rb', line 38

def initialize(index)
  @index = index
end

Instance Method Details

#commit_pending?(path) ⇒ Boolean

Checks if there are pending commits / edited files

Returns:

  • (Boolean)


117
118
119
120
121
122
123
# File 'lib/pro/commands.rb', line 117

def commit_pending?(path)
  status = ""
  Dir.chdir(path) do
    status = `git status 2>/dev/null`
  end
  return status.include?("Changes to be committed") || status.include?("Changes not staged for commit")
end

#find_repo(name) ⇒ Object

Fuzzy search for a git repository by name Returns the full path to the repository.

If name is nil return the pro base.



46
47
48
49
50
# File 'lib/pro/commands.rb', line 46

def find_repo(name)
  return @index.base_dirs.first unless name
  match = FuzzyMatch.new(@index.to_a, :read => :name).find(name)
  match[1] unless match.nil?
end

#install_cdObject

Adds a shell function to the shell config files that allows easy directory changing.



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/pro/commands.rb', line 147

def install_cd
  puts CD_INFO
  print "Continue with installation (yN)? "
  return unless gets.chomp.downcase == "y"
  # get name
  print "Name of pro cd command (default 'pd'): "
  name = gets.strip
  name = 'pd' if name.empty?
  # sub into function
  func = SHELL_FUNCTION.sub("{{name}}",name)
  did_any = false
  ['~/.profile', '~/.bashrc','~/.zshrc','~/.bash_profile'].each do |rel_path|
    # check if file exists
    path = File.expand_path(rel_path)
    next unless File.exists?(path)
    # ask the user if they want to add it
    print "Install #{name} function to #{rel_path} [yN]: "
    next unless gets.chomp.downcase == "y"
    # add it on to the end of the file
    File.open(path,'a') do |file|
      file.puts func
    end
    did_any = true
  end
  if did_any
    puts "Done! #{name} will be available in new shells."
  else
    STDERR.puts "WARNING: Did not install in any shell dotfiles.".red
    STDERR.puts "Maybe you should create the shell config file you want.".red
  end
end

#list_basesObject

prints out all the base directories



79
80
81
82
83
# File 'lib/pro/commands.rb', line 79

def list_bases
  @index.base_dirs.each do |b|
    puts b
  end
end

#list_reposObject

Prints out the paths to all repositories in all bases



72
73
74
75
76
# File 'lib/pro/commands.rb', line 72

def list_repos()
  @index.each do |r|
    puts r.path
  end
end

#repo_empty?(path) ⇒ Boolean

Checks if there are nothing in the repo

Returns:

  • (Boolean)


108
109
110
111
112
113
114
# File 'lib/pro/commands.rb', line 108

def repo_empty?(path)
  status = ""
  Dir.chdir(path) do
    status = `git status 2>/dev/null`
  end
  return status.include?("Initial commit")
end

#repo_status(path) ⇒ Object

returns a short status message for the repo



98
99
100
101
102
103
104
105
# File 'lib/pro/commands.rb', line 98

def repo_status(path)
  messages = []
  messages << EMPTY_MESSAGE if repo_empty?(path)
  messages << UNCOMMITTED_MESSAGE if commit_pending?(path)
  messages << UNTRACKED_MESSAGE if untracked_files?(path)
  messages << UNPUSHED_MESSAGE if repo_unpushed?(path)
  messages.join(JOIN_STRING)
end

#repo_unpushed?(path) ⇒ Boolean

Finds if there are any commits which have not been pushed to origin

Returns:

  • (Boolean)


135
136
137
138
139
140
141
142
143
# File 'lib/pro/commands.rb', line 135

def repo_unpushed?(path)
  unpushed = ""
  Dir.chdir(path) do
    branch_ref = `/usr/bin/git symbolic-ref HEAD 2>/dev/null`
    branch = branch_ref.chomp.split('/').last
    unpushed = `git cherry -v origin/#{branch} 2>/dev/null`
  end
  return !(unpushed.empty?)
end

#run_command(command, confirm = true) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/pro/commands.rb', line 52

def run_command(command, confirm = true)
  if confirm
    print "Do you really want to run '#{command.bold}' on all repos [Yn]? "
    ans = STDIN.gets.chomp.downcase
    return unless ans == 'y' || ans.empty?
  end
  @index.each do |r|
    Dir.chdir(r.path)
    stdin, result, wait_thr = Open3.popen2e(command)
    if wait_thr.value == 0
      puts "#{r.name}:".bold.green
    else
      puts "#{r.name}:".bold.red
    end
    puts result.read
    [stdin, result].map &:close
  end
end

#statusObject

prints a status list showing repos with unpushed commits or uncommitted changes



87
88
89
90
91
92
93
94
95
# File 'lib/pro/commands.rb', line 87

def status()
  max_name = @index.map {|repo| repo.name.length}.max + 1
  @index.each do |r|
    status = repo_status(r.path)
    next if status.empty?
    name = format("%-#{max_name}s",r.name).bold
    puts "#{name} > #{status}"
  end
end

#untracked_files?(path) ⇒ Boolean

Checks if there are untracked files in the repo

Returns:

  • (Boolean)


126
127
128
129
130
131
132
# File 'lib/pro/commands.rb', line 126

def untracked_files?(path)
  status = ""
  Dir.chdir(path) do
    status = `git status 2>/dev/null`
  end
  return status.include?("Untracked files")
end