Created
November 25, 2008 09:38
-
-
Save mkhl/28864 to your computer and use it in GitHub Desktop.
An old version of gx, plus a few macros I used to use.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# evanphx's old version of the gx git macro facility, slightly modified. | |
# I guess this is completely superseded by git aliases by now, but I like | |
# having it around somewhere... | |
class GitProxy | |
def initialize(prog="git") | |
@prog = prog | |
@record = false | |
@recording = [] | |
@verbose = false | |
end | |
def method_missing(cmd, *args) | |
str = "#{@prog} #{cmd}" | |
str << (" " + args.join(' ')) unless args.empty? | |
puts "GX: Running '#{str}'" if @verbose | |
if !@record and !block_given? | |
system str | |
else | |
ran = [:git, cmd, args.dup] | |
args.delete_if { |i| i =~ /%./ } | |
IO.popen(str, "r") do |io| | |
io.each_line do |line| | |
puts line | |
ran << line | |
yield line if block_given? | |
end | |
end | |
@recording << ran if @record | |
end | |
end | |
alias :run :method_missing | |
def record! | |
@record = true | |
end | |
attr_accessor :recording, :verbose | |
end | |
class GX | |
def initialize | |
@gx_dir = File.join ENV['HOME'], ".gx" | |
@recording_flag = File.join(@gx_dir, "recording") | |
@macros_path = File.join(@gx_dir, "macros") | |
@full_flag = File.join(@gx_dir, "fullpass") | |
Dir.mkdir @gx_dir unless File.exists?(@gx_dir) | |
Dir.mkdir @macros_path unless File.exists?(@macros_path) | |
@git = GitProxy.new(ENV['GIT_PATH'] || 'git') | |
if recording? | |
@git.record! | |
cur = Marshal.load File.read(@recording_flag) rescue nil | |
@git.recording = cur if cur | |
end | |
@fullpass = File.exists?(@full_flag) | |
setup_commands | |
scan_macros | |
end | |
def verbose=(value) | |
@git.verbose = value | |
end | |
def setup_commands | |
@commands = { | |
:record => method(:record), | |
:save => method(:save), | |
:macros => method(:macros) | |
} | |
end | |
def scan_macros | |
@macros = {} | |
Dir[@macros_path+"/*.rb"].each do |macro| | |
@macros[File.basename(macro, ".rb").to_sym] = macro | |
end | |
end | |
def recording? | |
File.exists? @recording_flag | |
end | |
def git(command, *args, &block) | |
@git.run command, *args, &block | |
end | |
def convert_to_options(args) | |
opts = {} | |
i = 0 | |
while i < args.size | |
if /^-(\w+)/.match(args[i]) | |
opt = $1 | |
if /^-/.match(args[i + 1]) | |
opts[opt] = true | |
else | |
opts[opt] = args[i += 1] | |
end | |
elsif /^--(.+)(?:=(.+))?/.match(args[i]) | |
opts[$1.to_sym] = ($2 or true) | |
else | |
break | |
end | |
i += 1 | |
end | |
args.slice!(0, i) if i > 0 | |
args << opts | |
end | |
def run(command, *args) | |
@command = command.to_sym | |
if handler = @commands[@command] | |
convert_to_options(args) | |
out = handler.call(*args) | |
elsif (!recording? or @fullpass) and macro = @macros[@command] | |
out = run_macro macro, *args | |
else | |
out = @git.run command, *args | |
end | |
if recording? | |
File.open(@recording_flag, "w") do |f| | |
f << Marshal.dump(@git.recording) | |
end | |
end | |
out | |
end | |
def run_macro(macro, *args) | |
old = @args | |
@args = args | |
out = instance_eval File.read(macro) | |
@args = old | |
out | |
end | |
def error(str) | |
puts "GX Error: #{str}" | |
exit 1 | |
end | |
def record(opts) | |
puts "Recording of commands has begun..." | |
File.open(@recording_flag, "w") { } | |
if opts[:full] or opts[:f] | |
File.open(@full_flag, "w") { } | |
end | |
end | |
def save(name, opts) | |
puts "Saving macro as '#{name}'" | |
File.open(File.join(@macros_path, "#{name}.rb"), "w") do |f| | |
@git.recording.each do |command| | |
if command[0] == :git | |
f.puts compose_command(command[1], command[2]) | |
else | |
f.puts "perform '#{command[1]}'" | |
end | |
end | |
end | |
File.unlink @recording_flag | |
File.unlink @full_flag if @fullpass | |
end | |
def compose_command(command, args) | |
if args.empty? | |
"git :#{command}, *@args" | |
else | |
if args.last == "%-" | |
arg.pop | |
no_extra = true | |
else | |
no_extra = false | |
end | |
skip = false | |
sargs = args.map do |i| | |
if skip | |
skip = false | |
nil | |
elsif i == "%%" | |
skip = true | |
"@args.shift" | |
else | |
i.dump | |
end | |
end.compact.join(", ") | |
sargs << ", *@args" unless no_extra | |
"git :#{command}, #{sargs}" | |
end | |
end | |
def macros(opts) | |
puts "Available macros:" | |
@macros.each do |name, macro| | |
puts " #{name}" | |
end | |
end | |
end | |
gx = GX.new | |
command = ARGV.shift | |
unless command | |
puts "Usage: gx <command> <args>" | |
puts " Commands which gx does not recognized are passed through to git." | |
exit 1 | |
end | |
gx.verbose = ENV['GX_VERBOSE'] | |
gx.run command, *ARGV |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
branch = run :'test-branch', 'master' | |
git :stash | |
git :checkout, "master" | |
git :merge, branch | |
git :checkout, branch | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
branch = run :'test-branch', 'master' | |
git :stash, "save" | |
git :checkout, "master" | |
git :pull, *@args | |
git :checkout, branch | |
git :rebase, "master" | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
branch = run :'test-branch', 'master' | |
git :stash | |
git :checkout, "master" | |
git :push | |
git :checkout, branch | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
branch = nil | |
git :branch do |line| | |
branch = line[2..-1].chomp if /\*/ === line | |
end | |
error "Couldn't figure out which branch you're on!" if branch.nil? | |
error "Already on branch \"#{branch}\"" if @args.include? branch | |
branch | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment