Module: GitFlow
Defined Under Namespace
Modules: Mixin Classes: HelpCommand, NoSuchCommand
Constant Summary collapse
- HELP =
<<-HELP GitFlow is a tool to create custom git commands implemented in ruby. It is generic enougth to be used on any git based project besides Apache Buildr. OVERVIEW: gitflow is intended to help developers with their daily git workflow, performing repetitive git commands for them. It is implemented in ruby so you can do anything, from invoking rake tasks to telling people on twitter you are having trouble with their code :P. To get help for a specific command use: gitflow.rb help command gitflow.rb command --help For convenience you can create an alias to be execute using git. The following example registers buildr-git.rb, which provides apache svn and git synchronization commands: git config alias.apache '!'"ruby $PWD/doc/scripts/buildr-git.rb" After that you can use git apache command --help EXTENDING YOUR WORKFLOW: You can create your own gitflow commands, to adapt your development workflow. Simply create a ruby script somewhere say ~/.buildr/gitflow.rb And alias it in your local repo: git config alias.flow '!'"ruby ~/.buildr/gitflow.rb" git config alias.work '!'"ruby ~/.buildr/gitflow.rb my-flow sub-work" A sample command would look like this.. (you may want to look at buildr-git.rb) #!/usr/bin/env ruby require /path/to/gitflow.rb class MyCommand < GitFlow/'my-flow' @help = "Summary to be displayed when listing commands" @documentation = "Very long help that will be paged if necessary. (for --help)" # takes an openstruct to place default values and option values. # returns an array of arguments given to optparse.on def options(opts) opts.something = 'default' [ ['--name NAME', lambda { |n| opts.name = n }], ['--yes', lambda { |n| opts.yes = true }] ] end # takes the opts openstruct after options have been parsed and # an argv array with non-option arguments. def execute(opts, argv) # you can run another command using run('other-command', '--using-this', 'arg') some = git('config', '--get', 'some.property').chomp rescue nil page { puts "This will be paged on terminal if needed" } end class SubCommand < MyCommand/'sub-work' ... # implement a subcommand end end You would then get help for your command with git flow my-flow --help git work --help Using gitflow you can customize per-project git interface. HELP
Instance Attribute Summary collapse
-
#program ⇒ Object
Returns the value of attribute program.
-
#should_run ⇒ Object
Returns the value of attribute should_run.
-
#trace ⇒ Object
Returns the value of attribute trace.
Instance Method Summary collapse
-
#/(command_name) ⇒ Object
Return a class to be extended in order to register a GitFlow command if command name is nil, it will be registered as the top level command.
- #command(argv) ⇒ Object
- #commands ⇒ Object
- #optparse ⇒ Object
- #pager ⇒ Object
- #run(*argv) ⇒ Object
Instance Attribute Details
#program ⇒ Object
Returns the value of attribute program.
24 25 26 |
# File 'lib/git_bpf/lib/gitflow.rb', line 24 def program @program end |
#should_run ⇒ Object
Returns the value of attribute should_run.
24 25 26 |
# File 'lib/git_bpf/lib/gitflow.rb', line 24 def should_run @should_run end |
#trace ⇒ Object
Returns the value of attribute trace.
24 25 26 |
# File 'lib/git_bpf/lib/gitflow.rb', line 24 def trace @trace end |
Instance Method Details
#/(command_name) ⇒ Object
Return a class to be extended in order to register a GitFlow command if command name is nil, it will be registered as the top level command. Classes implementing commands also provide this method, allowing for sub-command creation.
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/git_bpf/lib/gitflow.rb', line 140 def /(command_name) command_name = command_name.to_s unless command_name.nil? cls = Class.new { include GitFlow::Mixin } (class << cls; self; end).module_eval do attr_accessor :help, :documentation, :command define_method(:/) do |subcommand| raise "Subcommand cannot be nil" unless subcommand GitFlow/([command_name, subcommand].compact.join(' ')) end define_method(:inherited) do |subclass| subclass.command = command_name GitFlow.commands[command_name] = subclass end end cls end |
#command(argv) ⇒ Object
173 174 175 176 177 178 179 180 |
# File 'lib/git_bpf/lib/gitflow.rb', line 173 def command(argv) cmds = [] argv.each_with_index do |arg, i| arg = argv[0..i].join(' ') cmds << commands[arg] if commands.key?(arg) end cmds.last || commands[nil] end |
#commands ⇒ Object
157 158 159 |
# File 'lib/git_bpf/lib/gitflow.rb', line 157 def commands @commands ||= Hash.new end |
#optparse ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/git_bpf/lib/gitflow.rb', line 161 def optparse optparse = opt = OptionParser.new opt.separator ' ' opt.separator 'OPTIONS' opt.separator ' ' opt.on('-h', '--help', 'Display this help') do GitFlow.pager; puts opt; throw :exit end opt.on('--trace', 'Display traces') { GitFlow.trace = true } optparse end |
#pager ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/git_bpf/lib/gitflow.rb', line 110 def pager return if RUBY_PLATFORM =~ /win32/ return unless STDOUT.tty? read, write = IO.pipe unless Kernel.fork # Child process STDOUT.reopen(write) STDERR.reopen(write) if STDERR.tty? read.close write.close return end # Parent process, become pager STDIN.reopen(read) read.close write.close ENV['LESS'] = 'FSRX' # Don't page if the input is short enough Kernel.select [STDIN] # Wait until we have input before we start the pager pager = ENV['PAGER'] || 'less' exec pager rescue exec '/bin/sh', '-c', pager end |
#run(*argv) ⇒ Object
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/git_bpf/lib/gitflow.rb', line 182 def run(*argv) catch :exit do command = self.command(argv).new argv = argv[command.class.command.split.length..-1] if command.class.command parser = optparse parser. = "Usage: #{GitFlow.program} #{command.class.command} [options]" = OpenStruct.new if command.respond_to?(:options) command.().each { |args| parser.on(*args) } end if command.class.documentation && command.class.documentation != '' parser.separator ' ' parser.separator command.class.documentation.split(/\n/) end parser.parse!(argv) command.execute(, argv) end end |