Changeset 6299

Show
Ignore:
Timestamp:
02/06/08 22:22:00 (5 years ago)
Author:
yhara
Message:

lang/ruby/reposh: new: custom command (ver 0.1.4)

Location:
lang/ruby/reposh/trunk
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • lang/ruby/reposh/trunk/reposh.rb

    r6276 r6299  
    2222 
    2323class Reposh 
    24   VERSION = "0.1.3" 
     24  VERSION = "0.1.4" 
    2525  CONF_DEFAULT = {  
    2626    "global" => { 
    2727      "editing_mode" => nil, 
     28      "custom_commands" => [], 
    2829    }, 
    2930    "system" => { 
     
    3940  } 
    4041 
    41   def initialize 
    42   end 
    43  
    4442  def run 
    4543    parse_option(ARGV) 
     
    4947    @conf = load_config(@conf_path) 
    5048    @editing_mode = @conf["global"]["editing_mode"] 
    51     @binpath     = get_conf(@system_name, "binpath") || @system_name 
    5249    @prompt      = get_conf(@system_name, "prompt") 
    53     @default_cmd = get_conf(@system_name, "default_cmd") 
     50    binpath      = get_conf(@system_name, "binpath") || @system_name 
     51    default_cmd  = get_conf(@system_name, "default_cmd") 
     52 
     53    @commands = Commands.new(binpath, default_cmd) 
     54    @commands.register_custom_commands(@conf["global"]["custom_commands"]) 
     55 
    5456    run_loop 
    5557  end 
     
    102104   
    103105  def get_conf(system, prop) 
    104     if @conf["system"][system]  
    105       @conf["system"][system][prop] 
    106     else 
    107       @conf["system"]["default"][prop]  
    108     end 
     106    (@conf["system"][system] and @conf["system"][system][prop]) or @conf["system"]["default"][prop]  
    109107  end 
    110108 
     
    117115    loop do 
    118116      cmd = Readline.readline(@prompt, true) 
    119       cmd = @default_cmd if cmd == "" 
    120  
    121       case cmd 
    122       when "%reload" 
    123         load __FILE__ 
    124       when "%env" 
     117      @commands.dispatch(cmd, @system_name) 
     118    end 
     119  end 
     120 
     121  class Commands 
     122    def initialize(binpath, default_cmd) 
     123      @binpath, @default_cmd = binpath, default_cmd 
     124      @commands = [] 
     125      register_builtin_commands 
     126    end 
     127 
     128    def register_builtin_commands 
     129      # default command 
     130      register(/.*/){|match| 
     131        cmd = (match[0] == "") ? @default_cmd : match[0] 
     132        execute "#{@binpath} #{cmd}" 
     133      } 
     134 
     135      # system commands 
     136      register("%reload"){  
     137        load __FILE__  
     138      } 
     139      register("%env"){ 
    125140        require 'pp' 
    126141        pp ENV 
    127       when "%version" 
    128         puts VERSION 
    129       when nil, "exit", "quit" 
     142      } 
     143      register("%version"){ 
     144        puts VERSION  
     145      } 
     146      register(/\A%ruby (.*)/){|match| 
     147        puts "reposh: result is " + eval(match[1]).inspect 
     148      } 
     149      @trace_mode = false 
     150      register("%trace"){ 
     151        @trace_mode = (not @trace_mode) 
     152        puts "set trace_mode to #{@trace_mode}" 
     153      } 
     154 
     155      # exit commands 
     156      exit_task = lambda{ 
    130157        puts "" 
    131158        exit 
    132       when /^:(.*)/ 
    133         puts $1 
    134         execute $1 
     159      } 
     160      register(nil,    &exit_task) 
     161      register("exit", &exit_task) 
     162      register("quit", &exit_task) 
     163 
     164      # shell execution command 
     165      register(/^:(.*)/){|match| 
     166        execute match[1] 
     167      } 
     168    end 
     169 
     170    def register_custom_commands(commands) 
     171      commands.each do |hash| 
     172        if hash["for"]  
     173          systems = hash["for"].split(/,/).map{|s| s.strip} 
     174        else 
     175          systems = nil 
     176        end 
     177        register(Regexp.new(hash["pattern"]), systems){|match| 
     178          cmd = hash["rule"]. 
     179                  gsub(/\{system\}/, @binpath). 
     180                  gsub(/\{\$(\d+)\}/){ match[$1.to_i] } 
     181          puts cmd 
     182          execute cmd 
     183        } 
     184      end 
     185    end 
     186 
     187    def register(pattern, systems = nil, &task) 
     188      @commands.unshift [pattern, systems, task] 
     189    end 
     190 
     191    def dispatch(cmd, sys) 
     192      @commands.each do |pattern, systems, task| 
     193        next if systems && !systems.include?(sys) 
     194 
     195        if (match = match?(pattern, cmd)) 
     196          return task.call(match) 
     197        end 
     198      end 
     199      raise "must not happen" 
     200    end 
     201 
     202    def match?(pat, value) 
     203      case pat 
     204      when Regexp 
     205        pat.match(value) 
     206      when nil 
     207        value == nil 
    135208      else 
    136         execute "#{@binpath} #{cmd}" 
    137       end 
    138     end 
    139   end 
    140  
    141   def execute(cmd) 
    142     result = system(cmd) 
    143     if (not result) and ($?.nil? or $?.exitstatus == 127) 
    144       puts "error: failed to exec '#{cmd}'" 
    145     end 
    146   end 
     209        pat.strip == value 
     210      end 
     211    end 
     212 
     213    def execute(cmd) 
     214      puts cmd if @trace_mode 
     215      result = system(cmd) 
     216      if result == false  
     217        case 
     218        when $?.nil?  
     219          puts "reposh: unknown error ($? is nil)" 
     220        when [0, 127].include?($?.exitstatus) 
     221          puts "reposh: failed to exec '#{cmd}': status #{$?.exitstatus}" 
     222        end 
     223      end 
     224    end 
     225 
     226  end 
     227 
    147228end 
    148229 
  • lang/ruby/reposh/trunk/sample.reposh.yaml

    r6276 r6299  
    1 # vcs independent settings 
    21global: 
    32  editing_mode: vi  # default is: emacs 
     3  custom_commands: 
     4    # > ignore_of lib  =>  svn propedit svn:ignore lib 
     5    - pattern: \Aignore_of (.*) 
     6      rule: "{system} propedit svn:ignore {$1}" 
     7      for: svn, svk 
     8    # > ignore lib/*.o  =>  svn propset svn:ignore *.o lib 
     9    - pattern: \Aignore (.*)[\\/]([^\\/]+) 
     10      rule: "{system} propset svn:ignore {$2} {$1}" 
     11      for: svn, svk 
    412 
    513# settings for each vcs 
  • lang/ruby/reposh/trunk/spec_reposh.rb

    r6276 r6299  
     1require 'rubygems' 
     2require 'kagemusha' 
    13require 'reposh' 
    24 
    35describe "Hash#recursive_merge" do 
    4   before(:all) do 
     6  before :all do 
    57    @reposh = Reposh.new 
    68  end 
     
    3335  end 
    3436end 
     37 
     38describe "Reposh::Commands" do 
     39  before :each do 
     40    @commands = Reposh::Commands.new("svn") 
     41  end 
     42 
     43  it "should judge whether a command matches a pattern" do 
     44    @commands.match?("exit", "exit").should == true 
     45    match = @commands.match?(/:(.*)/, ":rake aaa") 
     46    match.should be_an_instance_of(MatchData) 
     47    match[1].should == "rake aaa" 
     48  end 
     49 
     50  it "should register a command and dispatch" do 
     51    @commands.register(/foo (.*) (\d+)/){|match| 
     52      match[1].should == "bar" 
     53      match[2].should == "1192" 
     54    } 
     55    @commands.dispatch("foo bar 1192", "svk") 
     56  end 
     57 
     58  it "should dispatch only for wanted systems" do 
     59    @commands.register("foo"){ :no_match } 
     60    @commands.register("foo", ["svn", "svk"]){ :match } 
     61 
     62    @commands.dispatch("foo", "svn").should == :match 
     63    @commands.dispatch("foo", "svk").should == :match 
     64    @commands.dispatch("foo", "hg").should == :no_match 
     65  end 
     66 
     67  it "should register custom commands" do  
     68    my_execute = Kagemusha.new(Reposh::Commands).def(:execute){|x| x} 
     69 
     70    @commands.register_custom_commands([ 
     71      { "pattern" => "ignore (\\S+)", 
     72        "rule"    => "{system} propset svn:ignore . {$1}", 
     73        "for"     => "svn, svk" } 
     74    ]) 
     75    my_execute.swap{ 
     76      result = @commands.dispatch("ignore *.swp", "svn") 
     77      result.should == "svn propset svn:ignore . *.swp" 
     78    } 
     79  end 
     80 
     81end