vcs 0.4.1 → 0.5.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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