Class: Hipe::GitHelper

Inherits:
Object
  • Object
show all
Defined in:
lib/hipe-githelper.rb

Defined Under Namespace

Classes: BufferString, Command, GitHelperException

Constant Summary collapse

VERSION =
'0.0.1beta'
REGGIE =
%r< 
(?:^\#\sOn\sbranch.*$\n)
(?:^\#\sYour\sbranch\sis\sahead[^\n]+\n\#\n)?
(?:^\#\s^\#\sInitial\sCommit\n\#\s)?
(?:
  (?:^\#\sChanges\sto\sbe\scommitted:$\n)
  (?:^\#\s+[[:print:]]+$\n)+
  (?:^\#$\n)
  ((?:^\#\s+(?:new\sfile|modified|deleted|renamed|copied|[a-z ]+):\s+.+$\n)+)
  (?:^\#$\n)                       
)?
(?:
  (?:^\#\sChanged\sbut\snot\supdated:$\n)
  (?:^\#\s+[[:print:]]+$\n)+
  (?:^\#$\n)
  ((?:^\#\s+(?:modified|deleted):\s+.+$\n)+)
  (?:^\#$\n)                       
)?  
(?:
  (?:^\#\sUntracked\sfiles:$\n)
  (?:^\#\s+[[:print:]]+$\n)+
  (?:^\#$\n)
  ((?:^\#\s+.+$\n)+)
)?        
>ix

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ GitHelper

Returns a new instance of GitHelper.



125
126
127
128
# File 'lib/hipe-githelper.rb', line 125

def initialize(opts={})
  opts = {:output_buffer => $stdout }.merge opts
  @out = opts[:output_buffer]
end

Class Attribute Details

.commandsObject

Returns the value of attribute commands.



117
118
119
# File 'lib/hipe-githelper.rb', line 117

def commands
  @commands
end

.grammarObject

Returns the value of attribute grammar.



117
118
119
# File 'lib/hipe-githelper.rb', line 117

def grammar
  @grammar
end

.screenObject

Returns the value of attribute screen.



117
118
119
# File 'lib/hipe-githelper.rb', line 117

def screen
  @screen
end

Class Method Details

.command(name, *other, &block) ⇒ Object



121
122
123
# File 'lib/hipe-githelper.rb', line 121

def self.command name, *other, &block
  @commands << Command.new(name, other[0], @grammar[(name.to_s+'_command'.to_s).to_sym])
end

Instance Method Details

#<<(argv) ⇒ Object



136
137
138
139
140
# File 'lib/hipe-githelper.rb', line 136

def << (argv)
  tree = parse_command argv
  execute_command tree
  @out
end

#_to_hash(mixed) ⇒ Object



255
256
257
258
259
260
261
# File 'lib/hipe-githelper.rb', line 255

def _to_hash(mixed)
  mixed ||= ''
  hash = Hash.new{|x,y|x[y] = []}
  x = mixed.scan(/^\#\t([^:]+): +(.*)$\n/)
  x.each{|pair| hash[pair[0]] << pair[1] }
  hash
end

#add(tree) ⇒ Object



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/hipe-githelper.rb', line 193

def add tree
  is_dry = tree[1].size > 0 && tree[1][0].name == :dry
  do_untracked = ['both','untracked'].include? tree[0][1][0]
  do_modified  = ['both','modified'].include? tree[0][1][0]
  tree = git_status_parse_tree
  raise GitHelperException("failed to parse command") unless do_untracked || do_modified
  list = {}
  list[:modified] = do_modified ? tree[:changed]['modified'] : [] # names are strings!
  list[:untracked] = do_untracked ? tree[:untracked] : []
  [:modified,:untracked].each do |which|
    count = ( list[which] && list[which].size ) ? list[which].size : 0
    @out << %{# adding #{count} #{which.to_s} file(s)#{(is_dry&&count>0)? ' (dry run -- not actually doing it)' : '' }\n}
    next if count == 0
    list[which].each do |filename| 
      cmd = %{git add #{filename}}
      @out.puts cmd
      unless is_dry
        if (res = shell!(cmd)).length > 0
          raise GitHelperException.new(%{I wasn't expecting any response from this.  Got: "#{res}"})
        end
      end
    end
  end
  @out.puts '# done.'
end

#execute_command(tree) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/hipe-githelper.rb', line 154

def execute_command tree
  if tree.is_error?
    @out.puts tree.message 
    @out.puts "Please try 'help' for syntax and usage."
  else
    commands = tree.recurse {|x| (x.name.to_s =~ /_command$/) ? [x] : [] }
    dry      = tree.recurse {|x| (x.name.to_s =~ /dry/) ? [x] : [] }
    commands.each do |x| 
      send(x.name.to_s.match(/^(.+)_command$/).captures[0],[x,dry]) 
    end
  end
  @out      
end

#git_status_parse_treeObject



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/hipe-githelper.rb', line 239

def git_status_parse_tree
  str = self.git_status_string
  unless (matches = REGGIE.match str)
    response = try_to_write_git_status_to_file(str)
    raise GitHelperException.new(%{Sorry, failed to parse the git status string.  Please make a note }+
    %{of the git status for a bug report. #{response}})        
  end
  caps = matches.captures
  ret = {
    :pending   =>  _to_hash(caps[0]),
    :changed   =>  _to_hash(caps[1]),
    :untracked =>  caps[2] ? caps[2].scan(/^\#\t(.*)$\n/).flatten : []
  }
  ret
end

#git_status_stringObject



223
224
225
# File 'lib/hipe-githelper.rb', line 223

def git_status_string
  shell! 'git status'
end

#help(args) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/hipe-githelper.rb', line 169

def help args
  argv = self.class.grammar[:argv].fork_for_parse # make a deep copy,
  dry = argv.instance_variable_get('@group').pop.dereference # explain dry separately
  argv_syntax = %{#{argv.syntax} #{dry.syntax}}
  @out << <<-END.gsub(/^ {6}/, '')
  Helpful little shortcuts for git.
  usage: #{program_name} #{argv_syntax}
  
  available commands:
  END
  @out << self.class.commands.map{ |x| x.help_short(self.class.screen) }.join("\n")
  @out << "\n\n"
  @out << "available options:\n"+Command.new(:dry,
  "Don't actually do anything, just show a preview of what you would do (where applicable.)", dry).
  help_short(self.class.screen)
  @out << "\n"
end

#info(args) ⇒ Object

This is a port of Duane Johnson’s shell script (duane D0T johnson AT gmail D0T com, License: MIT): blog.inquirylabs.com/2008/06/12/git-info-kinda-like-svn-info/ Based on discussion at kerneltrap.org/mailarchive/git/2007/11/12/406496



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/hipe-githelper.rb', line 267

def info args
  # Find base of git directory
  until Dir.glob('.git').length > 0 do
    if '/'==Dir.pwd   
      @out.puts "can't find .git directory this or any parent folder!"
      return
    end
    Dir.chdir('..')
  end

  @out.puts "(in "+Dir.pwd+')'

  # Show various information about this git directory
  @out.puts "== Remote URL: "
  @out.puts `git remote -v`

  @out.puts "== Remote Branches: "
  @out.puts `git branch -r`

  @out.puts "== Local Branches:"
  @out.puts `git branch`
  @out.puts "\n"

  @out.puts "== Configuration (.git/config)"
  File.open('.git/config'){|fh| @out.puts fh.read }
  @out.puts "\n"

  @out.puts "== Most Recent Commit"
  @out.puts `git log --max-count=1`
  @out.puts "\n"

  @out.puts "Type 'git log' for more commits, or 'git show' for full commit details."
  
end

#parse_command(argv) ⇒ Object



146
147
148
149
150
151
152
# File 'lib/hipe-githelper.rb', line 146

def parse_command argv
  if (0==argv.size || ['--help','-h'].include?(argv[0])) then argv[0] = 'help'
  elsif (['-v','--version'].include?(argv[0])) then argv[0] = 'version'
  end
  tree = self.class.grammar.parse argv
  tree
end

#program_nameObject



130
# File 'lib/hipe-githelper.rb', line 130

def program_name;  File.basename($PROGRAM_NAME) end

#readObject



142
143
144
# File 'lib/hipe-githelper.rb', line 142

def read
  @out.read # will fail unless the user passed in something that responds to this.
end

#runObject



132
133
134
# File 'lib/hipe-githelper.rb', line 132

def run 
  self << ARGV
end

#shell!(cmd) ⇒ Object



219
220
221
# File 'lib/hipe-githelper.rb', line 219

def shell! cmd
  %x{#{cmd}}      
end

#try_to_write_git_status_to_file(str) ⇒ Object



227
228
229
230
231
232
233
234
235
236
237
# File 'lib/hipe-githelper.rb', line 227

def try_to_write_git_status_to_file(str)
  i = 0
  head = File.expand_path(FileUtils.pwd)+'/example'
  tail = '.git.status'
  begin
    filename = %{#{head}#{i+=1}#{tail}} 
  end while File.exist?(filename)
  e = nil
  File.open(filename, 'w'){|fh| fh.write(str)} rescue e
  e ? e.message : %{Wrote git status to "#{filename}".}
end

#version(args) ⇒ Object



188
189
190
# File 'lib/hipe-githelper.rb', line 188

def version args
  @out.puts %{#{program_name} version #{VERSION}}
end