Reposh 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README +49 -0
  2. data/bin/reposh.rb +238 -0
  3. data/sample.reposh.yaml +25 -0
  4. metadata +55 -0
data/README ADDED
@@ -0,0 +1,49 @@
1
+ == Reposh - what's this?
2
+
3
+ Without reposh, you type like this:
4
+ $ svk di
5
+ $ svk ci
6
+ $ svk st
7
+ $ ls
8
+ but this is not DRY :)
9
+
10
+ With reposh, you can omit typing all 'svk's:
11
+ $ reposh
12
+ Welcome to reposh x.y.z (mode: svk)
13
+ > di
14
+ > ci
15
+ > # just push [Enter] for 'svk status'
16
+ > :ls # start with ':' to run shell commands
17
+
18
+ == How to use
19
+
20
+ (1) write /home/(your name)/.reposh.yaml
21
+ (2) cd to your working directory
22
+ (3) reposh.rb [Enter]
23
+
24
+ == Options
25
+
26
+ see reposh.rb --help
27
+
28
+ == Commands
29
+
30
+ * exit, quit, ^D(^Z)
31
+ * Quit reposh
32
+ * :ls ~/
33
+ * Run "ls ~/" by shell
34
+ * [Enter]
35
+ * Equals to "status" (you can change this by .reposh.yaml)
36
+ * %reload
37
+ * Reload reposh.rb (for reposh developper)
38
+ * Some more commands starts with % are supported: see source
39
+
40
+ All other commands are passed to vcs system.
41
+
42
+ == Configuration
43
+
44
+ see sample.reposh.yaml
45
+
46
+ == Contact
47
+
48
+ http://mono.kmc.gr.jp/~yhara/w?Reposh
49
+
@@ -0,0 +1,238 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # reposh.rb - Reposh - Simple VCS Manager Shell
4
+ #
5
+ require 'readline'
6
+ require 'yaml'
7
+ require 'optparse'
8
+
9
+ class Hash
10
+ def recursive_merge(other)
11
+ self.merge(other) do |key, my_val, other_val|
12
+ # for values of a same key
13
+ if my_val.is_a? Hash and other_val.is_a? Hash
14
+ my_val.recursive_merge(other_val) # XXX: hang-ups for cyclic hash?
15
+ else
16
+ other_val
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ class Reposh
23
+ VERSION = "0.1.5"
24
+ CONF_DEFAULT = {
25
+ "global" => {
26
+ "editing_mode" => nil,
27
+ "custom_commands" => [],
28
+ "pathext" => [],
29
+ },
30
+ "system" => {
31
+ "default" => {
32
+ "binpath" => nil,
33
+ "prompt" => "> ",
34
+ "default_cmd" => "status",
35
+ },
36
+ "darcs" => {
37
+ "default_cmd" => "whatsnew --summary",
38
+ }
39
+ }
40
+ }
41
+
42
+ def run
43
+ parse_option(ARGV)
44
+ @conf_path ||= File.join(ENV["HOME"], ".reposh.yaml")
45
+ @system_name ||= guess_system
46
+
47
+ @conf = load_config(@conf_path)
48
+ @editing_mode = @conf["global"]["editing_mode"]
49
+ pathext = @conf["global"]["pathext"]
50
+ @prompt = get_conf(@system_name, "prompt")
51
+ binpath = get_conf(@system_name, "binpath") || @system_name
52
+ default_cmd = get_conf(@system_name, "default_cmd")
53
+
54
+ @commands = Commands.new(binpath, default_cmd, pathext)
55
+ @commands.register_custom_commands(@conf["global"]["custom_commands"])
56
+
57
+ run_loop
58
+ end
59
+
60
+ def parse_option(args)
61
+ o = OptionParser.new{|opt|
62
+ opt.on("-c confpath",
63
+ "path to .reposh.yaml"){|path|
64
+ @confpath = path
65
+ }
66
+ opt.on("-s system",
67
+ "vcs command name (eg. svn, svk, hg)"){|sys|
68
+ @system_name = sys
69
+ }
70
+ opt.on("-h", "--help",
71
+ "show this message"){
72
+ puts opt
73
+ exit
74
+ }
75
+ opt.on("-v", "--version",
76
+ "show version information"){
77
+ puts VERSION
78
+ exit
79
+ }
80
+ }
81
+ o.parse(args)
82
+ end
83
+
84
+ def load_config(path)
85
+ if File.exist?(path)
86
+ config_hash = YAML.load(File.read(path))
87
+ CONF_DEFAULT.recursive_merge(config_hash)
88
+ else
89
+ CONF_DEFAULT
90
+ end
91
+ end
92
+
93
+ def guess_system
94
+ case
95
+ when File.directory?(".hg")
96
+ "hg"
97
+ when File.directory?("_darcs")
98
+ "darcs"
99
+ when File.directory?(".svn")
100
+ "svn"
101
+ else
102
+ "svk"
103
+ end
104
+ end
105
+
106
+ def get_conf(system, prop)
107
+ (@conf["system"][system] and @conf["system"][system][prop]) or @conf["system"]["default"][prop]
108
+ end
109
+
110
+ def run_loop
111
+ if @editing_mode == "vi"
112
+ Readline.vi_editing_mode
113
+ end
114
+
115
+ puts "Welcome to reposh #{VERSION} (mode: #{@system_name})"
116
+ loop do
117
+ cmd = Readline.readline(@prompt, true)
118
+ @commands.dispatch(cmd, @system_name)
119
+ end
120
+ end
121
+
122
+ class Commands
123
+ def initialize(binpath, default_cmd, pathext)
124
+ @binpath, @default_cmd, @pathext = binpath, default_cmd, pathext
125
+ @commands = []
126
+ register_builtin_commands
127
+ end
128
+
129
+ def register_builtin_commands
130
+ # default command
131
+ register(/.*/){|match|
132
+ cmd = (match[0] == "") ? @default_cmd : match[0]
133
+ execute "#{@binpath} #{cmd}"
134
+ }
135
+
136
+ # system commands
137
+ register("%reload"){
138
+ load __FILE__
139
+ }
140
+ register("%env"){
141
+ require 'pp'
142
+ pp ENV
143
+ }
144
+ register("%version"){
145
+ puts VERSION
146
+ }
147
+ register(/\A%ruby (.*)/){|match|
148
+ puts "reposh: result is " + eval(match[1]).inspect
149
+ }
150
+ @trace_mode = false
151
+ register("%trace"){
152
+ @trace_mode = (not @trace_mode)
153
+ puts "set trace_mode to #{@trace_mode}"
154
+ }
155
+
156
+ # exit commands
157
+ exit_task = lambda{
158
+ puts ""
159
+ exit
160
+ }
161
+ register(nil, &exit_task)
162
+ register("exit", &exit_task)
163
+ register("quit", &exit_task)
164
+
165
+ # shell execution command
166
+ register(/^:(.*)/){|match|
167
+ execute match[1]
168
+ }
169
+ end
170
+
171
+ def register_custom_commands(commands)
172
+ commands.each do |hash|
173
+ if hash["for"]
174
+ systems = hash["for"].split(/,/).map{|s| s.strip}
175
+ else
176
+ systems = nil
177
+ end
178
+ register(Regexp.new(hash["pattern"]), systems){|match|
179
+ cmd = hash["rule"].
180
+ gsub(/\{system\}/, @binpath).
181
+ gsub(/\{\$(\d+)\}/){ match[$1.to_i] }
182
+ puts cmd
183
+ execute cmd
184
+ }
185
+ end
186
+ end
187
+
188
+ def register(pattern, systems = nil, &task)
189
+ @commands.unshift [pattern, systems, task]
190
+ end
191
+
192
+ def dispatch(cmd, sys)
193
+ @commands.each do |pattern, systems, task|
194
+ next if systems && !systems.include?(sys)
195
+
196
+ if (match = match?(pattern, cmd))
197
+ return task.call(match)
198
+ end
199
+ end
200
+ raise "must not happen"
201
+ end
202
+
203
+ def match?(pat, value)
204
+ case pat
205
+ when Regexp
206
+ pat.match(value)
207
+ when nil
208
+ value == nil
209
+ else
210
+ pat.strip == value
211
+ end
212
+ end
213
+
214
+ def execute(cmd)
215
+ stat = false
216
+ ([""] + @pathext).each do |ext|
217
+ command = add_ext(cmd, ext)
218
+ puts command if @trace_mode
219
+ result = system(command)
220
+ return if result
221
+ stat = $?
222
+ end
223
+ puts "reposh: failed to exec '#{cmd}': status #{stat.exitstatus}"
224
+ end
225
+
226
+ def add_ext(cmd, ext)
227
+ exe, *args = cmd.split(' ')
228
+ "#{exe}#{ext} #{args.join ' '}"
229
+ end
230
+
231
+ end
232
+
233
+ end
234
+
235
+ if $0==__FILE__
236
+ Reposh.new.run
237
+ end
238
+
@@ -0,0 +1,25 @@
1
+ global:
2
+ editing_mode: vi # default is: emacs
3
+ # pathext: [".bat", ".cmd"] # for windows users
4
+ custom_commands:
5
+ # > ignore_of lib => svn propedit svn:ignore lib
6
+ - pattern: \Aignore_of (.*)
7
+ rule: "{system} propedit svn:ignore {$1}"
8
+ for: svn, svk
9
+ # > ignore lib/*.o => svn propset svn:ignore *.o lib
10
+ - pattern: \Aignore (.*)[\\/]([^\\/]+)
11
+ rule: "{system} propset svn:ignore {$2} {$1}"
12
+ for: svn, svk
13
+
14
+ # settings for each vcs
15
+ system:
16
+ default: # for all vcs
17
+ prompt: "> "
18
+ svn:
19
+ binpath: svn
20
+ svk:
21
+ binpath: c:/prog/svk/bin/svk.bat # path to svk
22
+ prompt: "svk > " # prompt
23
+ default_cmd: "status" # used when you just type [Enter]
24
+ hg:
25
+ binpath: hg
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: Reposh
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.5
5
+ platform: ruby
6
+ authors:
7
+ - yhara (Yutaka HARA)
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-06-21 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: yhara,at,kmc,gr,jp
18
+ executables:
19
+ - reposh.rb
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - README
26
+ - sample.reposh.yaml
27
+ - bin/reposh.rb
28
+ has_rdoc: false
29
+ homepage: http://mono.kmc.gr.jp/~yhara/
30
+ post_install_message:
31
+ rdoc_options: []
32
+
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: "0"
40
+ version:
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ requirements: []
48
+
49
+ rubyforge_project: reposh
50
+ rubygems_version: 1.1.1
51
+ signing_key:
52
+ specification_version: 2
53
+ summary: Simple VCS Shell
54
+ test_files: []
55
+