vcs 0.4.1 → 0.5.2.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  # Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
2
2
  # Copyright:: Copyright (c) 2005 LRDE. All rights reserved.
3
3
  # License:: GNU General Public License (GPL).
4
- # Revision:: $Id: script.rb 261 2005-10-03 00:45:53Z pouill_n $
4
+ # Revision:: $Id: /lrde/tools/trunk/vcs/lib/vcs/script.rb 9102 2005-10-03T00:45:53.019651Z pouill_n $
5
5
 
6
6
  require 'vcs/vcs'
7
7
 
@@ -5,7 +5,7 @@
5
5
 
6
6
  require 'vcs/svn'
7
7
 
8
- class Svn
8
+ class Vcs
9
9
 
10
10
  class StatusEntry
11
11
  attr_accessor :line, :file_st, :prop_st, :cpy, :file, :category, :comment
@@ -51,24 +51,11 @@ class Svn
51
51
  ?R => [:MAGENTA],
52
52
  ?~ => [:RED],
53
53
  ?! => [:RED],
54
- ?? => [:BLINK, :RED],
55
- ?C => [:BLINK, :RED],
54
+ ?? => [:BOLD, :RED],
55
+ ?C => [:BOLD, :RED],
56
56
  }
57
57
  end # class StatusEntry
58
58
 
59
- def status ( *args, &block )
60
- return status_(*args) if block.nil?
61
- result = PathList.new
62
- status_(*args).each_line do |line|
63
- next unless line =~ /^.{5} /
64
- status_entry = StatusEntry.new(@h, line)
65
- next if status_entry.category == :exclude
66
- result << status_entry
67
- end
68
- result.sort_with_regex_list! Vcs.regex_list
69
- result.each(&block)
70
- end
71
-
72
59
  def color_status! ( *args )
73
60
  status(*args) do |status_entry|
74
61
  status_entry.colorize!
@@ -86,4 +73,41 @@ class Svn
86
73
  end
87
74
  end
88
75
 
76
+ def spawn_status_entries ( status_data, &block )
77
+ result = PathList.new
78
+ status_data.each_line do |line|
79
+ next unless line =~ /^.{5} /
80
+ status_entry = StatusEntry.new(@h, line)
81
+ next if status_entry.category == :exclude
82
+ result << status_entry
83
+ end
84
+ result.sort_with_regex_list! Vcs.regex_list
85
+ result.each(&block)
86
+ end
87
+
88
+ end # class Vcs
89
+
90
+
91
+ class Svn
92
+
93
+ def status ( *args, &block )
94
+ return status_(*args) if block.nil?
95
+ spawn_status_entries(status_(*args), &block)
96
+ end
97
+
89
98
  end # class Svn
99
+
100
+
101
+
102
+ class Cvs
103
+
104
+ def status ( files=[], options={}, &block )
105
+ return status_(*args) if block.nil?
106
+ opts = options.merge :q => true, :n => true
107
+ output = update_(files, opts).output.read
108
+ output.gsub!(/^(\w) (\w)/, '\1 \2')
109
+ spawn_status_entries(output, &block)
110
+ end
111
+
112
+ end # class Cvs
113
+
@@ -66,4 +66,12 @@ class Svn < Vcs
66
66
  --xml
67
67
  "
68
68
 
69
+ @@standard_options ||=
70
+ %w[ non_recursive username password no_auth_cache
71
+ non_interactive config_dir ].map { |x| x.to_sym }
72
+
73
+ def standard_option? ( option_name )
74
+ @@standard_options.include? option_name.to_sym
75
+ end
76
+
69
77
  end # class Svn
@@ -1,7 +1,7 @@
1
1
  # Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
2
2
  # Copyright:: Copyright (c) 2004 LRDE. All rights reserved.
3
3
  # License:: GNU General Public License (GPL).
4
- # Revision:: $Id: url.rb 236 2005-09-26 13:08:22Z pouill_n $
4
+ # Revision:: $Id: /lrde/tools/trunk/vcs/lib/vcs/url.rb 9077 2005-09-26T13:08:22.140977Z pouill_n $
5
5
 
6
6
  class Vcs
7
7
 
@@ -27,7 +27,7 @@ require 'logger'
27
27
  require 'optparse'
28
28
  require 'etc'
29
29
  require 'ostruct'
30
- ENV['LC_ALL'] = 'C'
30
+ ENV['LC_ALL'] = 'en_US'
31
31
 
32
32
  unless defined? Vcs
33
33
 
@@ -44,7 +44,7 @@ unless defined? Vcs
44
44
  # checkout_!
45
45
  #
46
46
  class Vcs
47
- @@version ||= '0.4.0'
47
+ require 'vcs/version'
48
48
  @@user_conf ||= OpenStruct.new(
49
49
  :exclude => [/^-/],
50
50
  :unmask => [/^\\/],
@@ -52,7 +52,10 @@ class Vcs
52
52
  :precious => [/^(\+|\.vcs)/],
53
53
  :color => :auto,
54
54
  :sorting => [],
55
- :sign => true
55
+ :sign => true,
56
+ :log_mode => :change_log,
57
+ :interactive => true,
58
+ :new_user => true
56
59
  )
57
60
  @@output_io_methods ||= %w[ print puts putc ] # FIXME and so ...
58
61
  @@specific_options ||= Set.new
@@ -76,7 +79,6 @@ class Vcs
76
79
  @@categories ||= @@user_defined_categories + @@symbol_category.values
77
80
 
78
81
 
79
- cattr_accessor :version
80
82
  cattr_accessor :default
81
83
  cattr_accessor :user_conf
82
84
  cattr_accessor :output_io_methods
@@ -85,12 +87,13 @@ class Vcs
85
87
  cattr_accessor :user_defined_categories
86
88
  cattr_accessor :symbol_category
87
89
  cattr_accessor :categories
90
+ cattr_accessor :log_mode
88
91
  class_inheritable_accessor :option_controller
89
92
 
90
93
 
91
94
  class Logger < ::Logger
92
95
 
93
- attr_accessor :color
96
+ attr_reader :color
94
97
 
95
98
  def initialize ( *a, &b )
96
99
  super
@@ -98,9 +101,14 @@ class Vcs
98
101
  @color = false
99
102
  end
100
103
 
104
+ def color= ( aColor )
105
+ @color = aColor
106
+ @@headers.clear
107
+ end
108
+
101
109
  def header ( progname, severity )
102
110
  @@headers[[progname, severity]] ||= [
103
- '[', 'vcs', ']', ' ', progname, severity, ':', ' '
111
+ 'vcs', ': ', progname, severity, ': '
104
112
  ].compact.map { |x| stylize x }.join
105
113
  end
106
114
 
@@ -122,20 +130,20 @@ class Vcs
122
130
  end
123
131
 
124
132
  @@headers ||= {}
125
-
126
- @@style =
133
+ @@style ||=
127
134
  {
128
- :vcs => [:cyan],
129
- :debug => [:magenta],
130
- :info => [:green],
131
135
  :warn => [:yellow],
132
- :error => [:red],
133
- :fatal => [:red, :blink],
134
- :'[' => [:blue],
135
- :']' => [:blue],
136
- :':' => [:red],
136
+ :error => [:red, :bold],
137
+ :fatal => [:red, :underline, :bold],
137
138
  }
138
139
 
140
+ def self.enable_xmas_tree_colors
141
+ @@style.merge! :vcs => [:cyan],
142
+ :debug => [:magenta],
143
+ :info => [:green],
144
+ :': ' => [:blue]
145
+ end
146
+
139
147
  def stylize ( aString )
140
148
  aString = aString.downcase
141
149
  if @color
@@ -192,44 +200,56 @@ class Vcs
192
200
 
193
201
 
194
202
  class Switch
195
- cattr_reader :shortcuts
196
- attr_reader :name, :shortcuts, :argument
203
+ cattr_reader :aliases
204
+ attr_reader :main, :aliases, :argument, :comment
197
205
 
206
+ switch = '[\w?-]+'
198
207
  @@re ||=
199
208
  /^
200
209
  \s*
201
- --([\w-]+) # The option (--foo)
210
+ ((?:\*PRE\*)?) # Is the switch must be before
211
+ # the sub command
212
+ \s*
213
+ (#{switch}) # The option (--foo)
202
214
  \s*
203
215
  (?: \(
204
- (-\w) # A shortcut (-f)
205
- (?:\sor\s(-(?:\?|\w)))? # Another one (-f or -o)
216
+ (#{switch}) # An alias (-f)
217
+ (?:\sor\s(#{switch}))? # Another one (-f or -o)
206
218
  \)
207
219
  )?
208
220
  \s*
209
221
  (.*?) # An argument (--foo NUM)
210
222
  \s*
211
223
  (?:\{(.*)\})? # A type (--foo NUM {Integer})
224
+ \s*
225
+ (?:\(\(.*\)\))? # A comment (--foo ((Usage...)))
212
226
  $/x
213
227
 
214
228
  def initialize ( aString )
215
229
  match = @@re.match(aString)
216
230
  raise "Cannot parse switch: `#{aString}'" if match.nil?
217
- @name, @argument, @type = match[1], match[4], match[5]
231
+ @pre = match[1] == '*PRE*'
232
+ @main = match[2]
233
+ @argument, @type, @comment = match[5..7]
218
234
  @type = eval(@type) unless @type.nil?
219
- @shortcuts = match[2..3].compact
235
+ @aliases = match[3..4].compact
220
236
  end
221
237
 
222
238
  def to_s
223
- '--' + @name
239
+ @main
224
240
  end
225
241
 
226
242
  def to_a_for_option_parser
227
243
  argument = (@argument.nil? || @argument.empty?)? '' : ' ' + @argument
228
- @shortcuts + ["--#@name#{argument}", @type].compact
244
+ @aliases + ["#@main#{argument}", @type].compact
229
245
  end
230
246
 
231
247
  def to_sym
232
- @name.gsub('-', '_').to_sym
248
+ @main.gsub(/^-+/, '').gsub('-', '_').sub(/^no_/, '').to_sym
249
+ end
250
+
251
+ def pre?
252
+ @pre
233
253
  end
234
254
 
235
255
  end # class Switch
@@ -238,19 +258,22 @@ class Vcs
238
258
 
239
259
  class OptionController
240
260
 
241
- attr_reader :switches, :shortcuts, :vcs_name, :option_parser, :options
261
+ attr_reader :switches, :vcs_name, :option_parser, :options
242
262
  protected :options
263
+ cattr_accessor :logger
264
+ self.logger = Vcs.logger
243
265
 
244
266
  def initialize ( aVcsClass, aString )
245
267
  Vcs.logger.debug { "Creating an option_controller for #{aVcsClass}..." }
246
268
  @switches = []
247
- @shortcuts = {}
269
+ @switches_finder = {}
248
270
  aString.each_line do |line|
249
271
  next if line.blank?
250
272
  switch = Switch.new(line)
251
273
  @switches << switch
252
- switch.shortcuts.each do |shortcut|
253
- @shortcuts[shortcut] = switch.name
274
+ @switches_finder[switch.main] = switch
275
+ switch.aliases.each do |al|
276
+ @switches_finder[al] = switch
254
277
  end
255
278
  end
256
279
  @option_parser = OptionParser.new do |o|
@@ -271,18 +294,22 @@ class Vcs
271
294
  [@options, @option_parser.parse(argv)]
272
295
  end
273
296
 
274
- def short_to_long ( short_option )
275
- @shortcuts[short_option]
297
+ def find ( anObject )
298
+ @switches_finder[anObject.to_s]
276
299
  end
277
300
 
278
301
  def to_strings ( options )
279
- result = []
302
+ pre, post = [], []
280
303
  options.each do |k, v|
281
- raise if v == false
282
- result << '--' + k.to_s.gsub('_', '-')
283
- result << v.to_s if v != true
304
+ sw = (k.to_s.size == 1)? "-#{k}" : ('--' + k.to_s.gsub('_', '-'))
305
+ sw.gsub!(/^--/, '--no-') if v == false
306
+ switch = find sw
307
+ logger.warn { "Unknown switch: #{sw}" } if switch.nil?
308
+ result = (switch and switch.pre?)? pre : post
309
+ result << (switch || sw).to_s
310
+ result << v.to_s if (v != true) and (v != false)
284
311
  end
285
- result
312
+ [pre, post]
286
313
  end
287
314
 
288
315
  end # class OptionController
@@ -294,12 +321,25 @@ class Vcs
294
321
  @h = HighLine.new
295
322
  self.cmd_data_factory = VcsCmdDataFactory.new(:output => STDOUT, :error => STDERR)
296
323
 
297
- @runner.subscribe_hook(:failure) do |data|
298
- if data.output == STDOUT
299
- logger.debug { raise data.to_yaml }
300
- exit((data.status)? data.status.exitstatus : 1)
301
- else
302
- raise data.to_yaml
324
+ unless is_a? Cvs
325
+ @runner.subscribe_hook(:failure) do |command, data|
326
+ data = command if data.nil? # Backward compatiblity
327
+ logger.error { 'command: ' + command.to_s.gsub('"', '') }
328
+ logger.error { "exit: #{data.status.exitstatus}" }
329
+ suppress(IOError) do
330
+ o = data.output.read
331
+ logger.error { o.gsub!(/^/, 'stdout: ') ; o } unless o.empty?
332
+ end
333
+ suppress(IOError) do
334
+ o = data.error.read
335
+ logger.error { o.gsub!(/^/, 'stderr: ') ; o } unless o.empty?
336
+ end
337
+ # logger.error { 'data: ' + data.to_yaml }
338
+ if data.output == STDOUT
339
+ exit((data.status)? data.status.exitstatus : 1)
340
+ else
341
+ raise 'command failed'
342
+ end
303
343
  end
304
344
  end
305
345
  @runner.subscribe_hook(:display_command) do |cmd|
@@ -378,12 +418,12 @@ class Vcs
378
418
 
379
419
  def run! ( command, files=[], options={} )
380
420
  flush
381
- cmd_options = option_controller.to_strings(options)
382
- (@cmd + command + cmd_options + '--' + files).run(@runner)
421
+ pre_cmd_options, cmd_options = option_controller.to_strings(options)
422
+ (@cmd + pre_cmd_options + command + cmd_options + '--' + files).run(@runner)
383
423
  end
384
424
 
385
- def sub_vcs ( out, err, &block )
386
- copy = self.class.new(@cmd)
425
+ def sub_vcs ( out, err, vcs_class=nil, &block )
426
+ copy = (vcs_class || self.class).new(@cmd)
387
427
  copy.cmd_data_factory = VcsCmdDataFactory.new(:output => out, :error => err)
388
428
  if block.nil?
389
429
  copy
@@ -392,13 +432,14 @@ class Vcs
392
432
  end
393
433
  end
394
434
 
395
- def sub_vcs_with_name ( name, &block )
396
- sub_vcs(TempPath.new("#{name}-out"), TempPath.new("#{name}-err"), &block)
435
+ def sub_vcs_with_name ( name, vcs_class=nil, &block )
436
+ sub_vcs(TempPath.new("#{name}-out"), TempPath.new("#{name}-err"),
437
+ vcs_class, &block)
397
438
  end
398
439
 
399
- def with ( io, &block )
440
+ def with ( io, vcs_class=nil, &block )
400
441
  io.flush if io.respond_to? :flush
401
- sub_vcs(io, io, &block)
442
+ sub_vcs(io, io, vcs_class, &block)
402
443
  end
403
444
 
404
445
  def output
@@ -416,8 +457,10 @@ class Vcs
416
457
  def run_missing! ( name, orig, *args )
417
458
  if name =~ /^(.*)_$/
418
459
  run!($1, *args)
460
+ elsif name =~ /^--/
461
+ run!(name, *args)
419
462
  else
420
- logger.warn { "unknown method #{orig}" }
463
+ logger.warn { "Unknown command: '#{orig.gsub('!', '')}'" }
421
464
  run!(name, *args)
422
465
  end
423
466
  end
@@ -425,9 +468,17 @@ class Vcs
425
468
 
426
469
  def run_argv ( argv )
427
470
  options, files = option_controller.parse(argv)
428
- if files.empty?
429
- options.delete(:help)
471
+ if options[:help]
430
472
  meth = :help!
473
+ options.delete(:help)
474
+ elsif files.empty?
475
+ if options[:version]
476
+ meth = '--version'
477
+ options.delete(:version)
478
+ else
479
+ options.delete(:help)
480
+ meth = :help!
481
+ end
431
482
  else
432
483
  meth = files.shift.dup
433
484
  meth.sub!(/([^!])$/, '\1!') if meth != 'script'
@@ -478,10 +529,10 @@ class Vcs
478
529
  return path.read
479
530
  end
480
531
  begin
481
- logger.info "Creating a new `#{path}' file ..."
532
+ logger.info "Creating a new `#{path}' file..."
482
533
  path.open('w') { |f| result = with(f, &block) }
483
534
  rescue Exception => ex
484
- logger.error "Removing `#{path}' ..."
535
+ logger.error "Removing `#{path}'..."
485
536
  path.unlink
486
537
  raise ex
487
538
  end
@@ -536,6 +587,18 @@ class Vcs
536
587
  end
537
588
  end
538
589
 
590
+ def standard_option? ( option_name )
591
+ false
592
+ end
593
+
594
+ def just_standard_options ( options )
595
+ result = {}
596
+ options.each do |k, v|
597
+ result[k] = v if standard_option? k
598
+ end
599
+ result
600
+ end
601
+
539
602
  CL = Pathname.new('ChangeLog') unless defined? CL
540
603
  TMP_CL = Pathname.new(',,ChangeLog') unless defined? TMP_CL
541
604
 
@@ -598,7 +661,7 @@ class Vcs
598
661
  class << self
599
662
 
600
663
  def add_conf_checker ( meth=nil, &block )
601
- @@checkers << (block.nil?)? meth : block
664
+ @@checkers << ((block.nil?)? meth : block)
602
665
  end
603
666
 
604
667
  def user_conf_match ( sym, file )
@@ -624,12 +687,21 @@ class Vcs
624
687
  def color? ( &auto_block )
625
688
  case color = Vcs.user_conf.color
626
689
  when :never then return false
627
- when :auto then return (auto_block.nil?)? false : auto_block[]
690
+ when :auto, :xmas_tree
691
+ return (auto_block.nil?)? false : auto_block[]
628
692
  when :always then return true
629
693
  else raise ArgumentError, "Bad value for `color' (#{color})"
630
694
  end
631
695
  end
632
696
 
697
+ def interactive?
698
+ user_conf.interactive
699
+ end
700
+
701
+ def xmas_tree_colors?
702
+ Vcs.user_conf.color == :xmas_tree
703
+ end
704
+
633
705
  def regex_list
634
706
  @@regex_list ||= RegexList.new(user_conf.sorting)
635
707
  end