svn-command 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/Readme CHANGED
@@ -36,7 +36,7 @@ And for some reason I seem to have to restart my terminal after doing the chmod
36
36
 
37
37
  *Important*: You need the gem's +bin+ directory to be added to the <b><i>front</i></b> of your path. This requires adding/editing a <tt>PATH=</tt> command in your <tt>~/.bash_profile</tt> (or equivalent). For example:
38
38
 
39
- export PATH=`ls -d /usr/lib/ruby/gems/1.8/gems/svn-command* | tail -n1`/bin:$PATH
39
+ export PATH=`ls -d /usr/lib/ruby/gems/1.8/gems/svn-command* --color=never | tail -n1`/bin:$PATH
40
40
 
41
41
  Or hard-code the path, if you _really_ want to:
42
42
 
@@ -246,6 +246,9 @@ only this format:
246
246
  --diff-cmd colordiff
247
247
  This is a limitation of Console::Command.
248
248
 
249
+ Fix: Show the whole thing, including this line:
250
+ Fetching external item into 'glass/rails_backend/vendor/plugins/our_extensions'
251
+
249
252
  === Slowness
250
253
 
251
254
  Is it slower than just running /usr/bin/svn directly? You betcha it is!
@@ -267,4 +270,27 @@ Take the best ideas from these and incorporate:
267
270
 
268
271
  Possibly switch to LazySvn.
269
272
 
270
- http://wiki.qualitysmith.com/svn-command
273
+ After you save/edit/set an svn:externals, it should try to automatically pretty up the margins/alignment for you.
274
+
275
+ Color menu_item for do you want to edit this external yes/no
276
+
277
+ ====================================================================================================
278
+ Diff of externals (**don't forget to commit these too!**):
279
+ ----------------------------------------------------------------------------------------------------
280
+ to use ANSI underlines/colors
281
+
282
+ Done, I think:
283
+ Make sure to show errors!
284
+ ~/svn st * wasn't showing an error it should have been
285
+ > /usr/bin/svn status change_all_externals.rb change_all_externals.sh devscripts frontend glass glass.net potluck shared
286
+ svn: 'change_all_externals.rb' is not a working copy
287
+
288
+ If wrapped svn ever exits with an error code (such as 1), we ought to throw a fit as well
289
+
290
+ If there is an error during an update, such as this one:
291
+ Fetching external item into 'glass/rails_backend/vendor/plugins/our_extensions'
292
+ svn: REPORT request failed on '/!svn/vcc/default'
293
+ svn: Cannot replace a directory from within
294
+ it will not be displayed on screen. At least if it's an external that had the error.
295
+
296
+ More at: http://wiki.qualitysmith.com/svn-command
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby
2
+ require 'find'
3
+
4
+ Find.find(ARGV[0]) do |path|
5
+ if FileTest.directory?(path)
6
+ if File.basename(path)[0] == ?. # Don't look in directories beginning with .
7
+ Find.prune # Don't look any further into this directory.
8
+ else
9
+ ext = `svn pg svn:externals #{path} 2>&1`.strip
10
+ next if ext =~ /not under version control/
11
+ next if ext =~ /not a working copy/
12
+ next if path =~ /plugins\//
13
+ if ext.size > 0 and ext =~ /_tasks/
14
+ puts "-"*80
15
+ puts path
16
+ puts ext
17
+
18
+ # puts "svn up #{path}"
19
+ # puts `svn up #{path}`
20
+ # puts "svn pe svn:externals #{path}"
21
+ # exec "svn pe svn:externals #{path}" if fork.nil?
22
+ # Process.wait
23
+ # puts `svn up #{path}`
24
+ # puts "svn ci #{path} -m \"Fixing svn:externals\""
25
+ # puts `svn ci #{path} -m \"Fixing svn:externals\"`
26
+ end
27
+
28
+ next
29
+ end
30
+ end
31
+ end
32
+
@@ -0,0 +1,13 @@
1
+ svn pe svn:externals svn/code/gemables/dev_scripts/tasks
2
+ svn ci svn/code/gemables/dev_scripts/tasks -m 'Fixed svn:externals'
3
+ svn pe svn:externals svn/code/gemables/our_extensions/tasks
4
+ svn ci svn/code/gemables/our_extensions/tasks -m 'Fixed svn:externals'
5
+ svn pe svn:externals svn/code/applications/underlord/vendor/plugins
6
+ svn ci svn/code/applications/underlord/vendor/plugins -m 'Fixed svn:externals'
7
+ svn pe svn:externals svn/glass/rails_backend/vendor/plugins
8
+ svn ci svn/glass/rails_backend/vendor/plugins -m 'Fixed svn:externals'
9
+ svn pe svn:externals svn/glass.net/backend/vendor/plugins
10
+ svn ci svn/glass.net/backend/vendor/plugins -m 'Fixed svn:externals'
11
+ svn pe svn:externals svn/glass.net/shops/vendor/plugins
12
+ svn ci svn/glass.net/shops/vendor/plugins -m 'Fixed svn:externals'
13
+
data/lib/subversion.rb CHANGED
@@ -142,10 +142,11 @@ module Subversion
142
142
  status.sub!(/(Performing status.*)/m, '')
143
143
  end
144
144
 
145
- # Returns an array of external *items*
145
+ # Returns an array of externals *items*. These are the actual externals listed in an svn:externals property.
146
146
  # Example:
147
- # gemables/extensions/tasks/shared
148
- # gemables/extensions/doc_include/template
147
+ # vendor/a
148
+ # vendor/b
149
+ # Where 'vendor' is an ExternalsContainer containing external items 'a' and 'b'.
149
150
  def self.externals_items(path = './')
150
151
  status = status_the_section_before_externals(path)
151
152
  return [] if status.nil?
@@ -288,14 +289,12 @@ protected
288
289
  valid_options = [:capture, :exec, :popen]
289
290
  case method
290
291
  when :capture
291
- silence_stream($stderr) {
292
- `#{command}`
293
- }
292
+ `#{command} 2>&1`
294
293
  when :exec
295
294
  #Kernel.exec *args
296
295
  Kernel.exec command
297
296
  when :popen
298
- # This is just an idea of how maybe we could speed up the performance a bit. Rather than waiting until the command completes
297
+ # This is just an idea of how maybe we could improve the LATENCY. Rather than waiting until the command completes
299
298
  # (which can take quite a while for svn status sometimes since it has to walk the entire directory tree), why not process
300
299
  # the output from /usr/bin/svn *in real-time*??
301
300
  #
@@ -339,8 +338,12 @@ module Subversion
339
338
  #p @entries
340
339
  end
341
340
 
341
+ def has_entries?
342
+ @entries.size > 0
343
+ end
344
+
342
345
  def to_s
343
- "#{container_dir}\n" +
346
+ "#{container_dir.bold}\n" +
344
347
  entries.chomp.map { |line|
345
348
  " * " + line
346
349
  }.join
@@ -13,12 +13,31 @@ class String
13
13
  def colorize_svn_status_lines
14
14
  if Subversion.color
15
15
  self.gsub(/^ *\?/) { $&.yellow.bold}.
16
- gsub(/^ *A/) { $&.green.bold}.
17
- gsub(/^ *M/) { $&.green.bold}.
18
- gsub(/^ *D/) { $&.magenta.bold}.
19
- gsub(/^ *C/) { $&.red.bold}.
20
- gsub(/^ *~/) { $&.red.bold}.
21
- gsub(/^ *!/) { $&.red.bold}
16
+ gsub(/^ *A/) { $&.green.bold}.
17
+ gsub(/^ *M/) { $&.green.bold}.
18
+ gsub(/^ *D/) { $&.magenta.bold}.
19
+ gsub(/^ *C/) { $&.red.bold}.
20
+ gsub(/^ *~/) { $&.red.bold}.
21
+ gsub(/^ *!/) { $&.red.bold}
22
+ else
23
+ self
24
+ end
25
+ end
26
+ def colorize_svn_update_lines
27
+ if Subversion.color
28
+ self.gsub(/^ *U\s/) { $&.yellow.bold}.
29
+ gsub(/^ *A\s/) { $&.green.bold}.
30
+ gsub(/^ *M\s/) { $&.green.bold}.
31
+ gsub(/^ *D\s/) { $&.magenta.bold}.
32
+ gsub(/^ *C\s/) { $&.red.bold}
33
+ else
34
+ self
35
+ end
36
+ end
37
+ def colorize_svn_diff
38
+ if Subversion.color
39
+ self.gsub(/^(Index: )(.*)$/) { $2.underline}.
40
+ gsub(/^=+\n/, '')
22
41
  else
23
42
  self
24
43
  end
@@ -28,7 +47,7 @@ end
28
47
 
29
48
  # These are methods used by the SvnCommand for filtering and whatever else it needs...
30
49
  # It could probably be moved into SvnCommand, but I thought it might be good to at least make it *possible* to use them apart from SvnCommand.
31
- # Rename to Subversion::Filters ? Then would each_unadded fit?
50
+ # Rename to Subversion::Filters ? Then each_unadded would be an odd man out.
32
51
  module Subversion
33
52
  module Extensions
34
53
  Interesting_status_flags = ["M", "A", "D", "?"]
@@ -68,7 +87,7 @@ module Subversion
68
87
  # Eventually we may want it to include this whole block, but only iff there is something updated for this external.
69
88
  }.reject { |line|
70
89
  line =~ /^External at revision/
71
- }.join
90
+ }.join.colorize_svn_update_lines
72
91
  # Also get rid of all but one "At revision _."?
73
92
  end
74
93
 
@@ -91,5 +110,10 @@ module Subversion
91
110
  }
92
111
  end
93
112
 
113
+ # This is just a wrapper for Subversion.diff that adds some color
114
+ def self.diff(*args)
115
+ output = Subversion.diff(*args).colorize_svn_diff.add_exit_code_error
116
+ end
117
+
94
118
  end
95
119
  end
data/lib/svn_command.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'rubygems'
2
2
 
3
3
  require_gem 'facets', '>=1.8.51'
4
- require 'facets/more/command'
4
+ #require 'facets/more/command' # Not until they include my changes
5
5
  require 'facets/core/string/margin'
6
6
  require 'facets/core/kernel/require_local'
7
7
  require 'facets/core/array/select' # select!
@@ -11,15 +11,15 @@ require 'qualitysmith_extensions/enumerable/enum'
11
11
  require 'qualitysmith_extensions/array/expand_ranges'
12
12
  require 'qualitysmith_extensions/array/shell_escape'
13
13
  require 'qualitysmith_extensions/file_test/binary_file'
14
+ require 'qualitysmith_extensions/console/command'
14
15
 
15
16
  require 'extensions/symbol' # to_proc
17
+ require 'English'
16
18
  require 'pp'
17
19
  require 'termios'
18
20
  require 'stringio'
19
21
  require_gem 'colored'
20
- require 'colored'
21
- # Lets us do "(a)".white.bold instead of "(\033[1ma\033[0m)"
22
- #- Warning: Make sure you have the *right* color gem! gem install color --source require.errtheblog.com
22
+ require 'colored' # Lets us do "(a)".white.bold instead of "(\033[1ma\033[0m)"
23
23
  require_local '../lib/subversion'
24
24
  require_local '../lib/subversion_extensions'
25
25
 
@@ -43,6 +43,10 @@ class String
43
43
  def menu_item(color = :white)
44
44
  self[0..0].send(color).bold.underline + self[1..-1].send(color)
45
45
  end
46
+ def add_exit_code_error
47
+ self << "Exited with error!".bold.red if !$?.success?
48
+ self
49
+ end
46
50
  end
47
51
 
48
52
  Subversion.extend(Subversion::Extensions)
@@ -201,30 +205,26 @@ module Subversion
201
205
 
202
206
  def diff(*directories)
203
207
  directories = ["./"] if directories.empty?
204
- print Subversion.diff(*(directories + @passthrough_options))
208
+ puts Extensions.diff(*(directories + @passthrough_options))
205
209
 
206
210
  # Show diff for externals (if there are any)
207
211
  output = StringIO.new
208
212
  #paths = args.reject{|arg| arg =~ /^-/} || ['./']
209
213
  directories.each do |path|
210
- (Subversion.externals_containers(path) || []).each do |external|
211
- #puts external.to_s
212
- external.entries.each do |entry|
213
- dir = entry[/^[^ ]+/]
214
- #puts "#{external.container_dir} + #{dir}"
215
- path = File.join(external.container_dir, dir)
216
- diff_output = Subversion.diff(path).strip
214
+ (Subversion.externals_items(path) || []).each do |item|
215
+ diff_output = Extensions.diff(item).strip
217
216
  unless diff_output == ""
218
- output.puts '-'*100
219
- output.puts path
217
+ #output.puts '-'*100
218
+ #output.puts item.ljust(100, ' ').black_on_white.bold.underline
219
+ output.puts item.black_on_white.bold
220
220
  output.puts diff_output
221
221
  end
222
- end
223
222
  end
224
223
  end
225
224
  unless output.string == ""
226
- puts '='*100
227
- puts "Diff of externals (**don't forget to commit these too!**):"
225
+ #puts '='*100
226
+ puts (' '*100).yellow.underline
227
+ puts " Diff of externals (**don't forget to commit these too!**):".ljust(100, ' ').yellow_on_red.bold.underline
228
228
  puts output.string
229
229
  end
230
230
  end
@@ -318,7 +318,7 @@ End
318
318
  sources = args
319
319
 
320
320
  sources.each do |source|
321
- puts svn(:capture, 'move', source, destination)
321
+ puts filtered_svn('move', source, destination)
322
322
  end
323
323
  else
324
324
  svn :exec, 'move', *args
@@ -343,6 +343,7 @@ End
343
343
  def status(*args)
344
344
  #puts "in status(#{args.inspect})"
345
345
  #puts "#{self}.@passthrough_options == #{@passthrough_options.inspect}"
346
+ #print Subversion::Extensions.status_lines_filter( Subversion.status(*(@passthrough_options + args)) )
346
347
  print Subversion::Extensions.status_lines_filter( Subversion.status(*(@passthrough_options + args)) )
347
348
  end
348
349
 
@@ -358,7 +359,7 @@ End
358
359
  )
359
360
  end
360
361
  def update(*args)
361
- print Subversion::Extensions.update_lines_filter( Subversion.update(*prepare_args(args)) )
362
+ puts Subversion::Extensions.update_lines_filter( Subversion.update(*prepare_args(args)) )
362
363
  end
363
364
 
364
365
 
@@ -452,10 +453,10 @@ End
452
453
  else
453
454
  puts "File contents:"
454
455
  # Only show the first x bytes so that we don't accidentally dump the contens of some 20 GB log file to screen...
455
- contents = File.read(file, 3000) || ''
456
+ contents = File.read(file, threshold = 2000) || ''
456
457
  print contents
457
458
  puts if contents[-1] && contents[-1].chr != "\n" # Make sure we end with a newline character
458
- puts "..." if contents.length >= 3000 # So they know that there may be *more* to the file than what's shown
459
+ puts "..." if contents.length >= threshold # So they know that there may be *more* to the file than what's shown
459
460
  end
460
461
  elsif File.directory?(file)
461
462
  puts "Directory contains:"
@@ -526,6 +527,17 @@ End
526
527
  #-----------------------------------------------------------------------------------------------------------------------------
527
528
  # Externals-related commands
528
529
 
530
+ # Prints out all the externals *items* for the given directory. These are the actual externals listed in an svn:externals property.
531
+ # Example:
532
+ # vendor/a
533
+ # vendor/b
534
+ # Where 'vendor' is an ExternalsContainer containing external items 'a' and 'b'.
535
+ def externals_items(directory = "./")
536
+ puts Subversion.externals_items(directory).map { |external|
537
+ external.to_s
538
+ }
539
+ end
540
+
529
541
  # For every directory that has the svn:externals property set, this lists the contents of the svn:externals property (dir, URL)
530
542
  def externals(directory = "./")
531
543
  puts Subversion.externals_containers(directory).map { |external|
@@ -533,6 +545,7 @@ End
533
545
  gsub(File.expand_path(Dir.pwd) + '/', '')
534
546
  }
535
547
  end
548
+ alias_subcommand :e => :externals
536
549
  alias_subcommand :ext => :externals
537
550
 
538
551
  # Lists *directories* that have the svn:externals property set.
@@ -543,15 +556,21 @@ End
543
556
  end
544
557
 
545
558
  def edit_externals(directory = nil)
546
- if directory.nil?
547
- puts "No directory specified. Editing externals for *all* externals dirs..."
548
- Subversion.externals_containers('.').each do |external|
559
+
560
+ if directory.nil? || !Subversion::ExternalsContainer.new(directory).has_entries?
561
+ if directory.nil?
562
+ puts "No directory specified. Editing externals for *all* externals dirs..."
563
+ directory = "./"
564
+ else
565
+ puts "Editing externals for *all* externals dirs..."
566
+ end
567
+ Subversion.externals_containers(directory).each do |external|
549
568
  puts external.to_s
550
569
  command = "#{Subversion.executable} propedit svn:externals #{external.container_dir}"
551
570
  #puts command
552
571
  begin
553
572
  #print "Press Ctrl-C to skip, any other key to continue. (This will start up your default editor.) "
554
- print "Do you want to edit svn:externals for this directory? y/N > "
573
+ print "Do you want to edit svn:externals for this directory?".black_on_white + ' ' + 'yes'.menu_item(:white) + '/' + 'No'.menu_item(:white) + " > "
555
574
  response = $stdin.getc.chr
556
575
  system command if response.downcase == 'y'
557
576
  rescue Interrupt
@@ -559,10 +578,10 @@ End
559
578
  puts
560
579
  end
561
580
  end
581
+ puts 'Done'
562
582
  else
563
583
  system "#{Subversion.executable} propedit svn:externals #{directory}"
564
584
  end
565
- puts 'Done'
566
585
  end
567
586
  alias_subcommand :edit_ext => :edit_externals
568
587
  alias_subcommand :ee => :edit_externals
@@ -609,7 +628,7 @@ End
609
628
  puts "Message for r#{Subversion.latest_revision} :" if revision == 'head'
610
629
 
611
630
  $ignore_dry_run_option = true
612
- puts svn(:capture, *args)
631
+ puts filtered_svn(*args)
613
632
  $ignore_dry_run_option = false
614
633
  end
615
634
 
@@ -693,6 +712,13 @@ End
693
712
  # puts "in svn(): about to call Subversion#execute(#{args.inspect})"
694
713
  Subversion.send :execute, *args
695
714
  end
715
+
716
+ # Works identically to svn() except that it filters the output and displays a big red error message if /usr/bin/svn exied with an error.
717
+ def filtered_svn(*args)
718
+ # We have to use the :capture method if we're going to filter the output.
719
+ svn(:capture, *args).add_exit_code_error
720
+ end
721
+
696
722
  def prepare_args(args)
697
723
  args.compact! # nil elements spell trouble
698
724
  @passthrough_options + args.shell_escape
@@ -9,12 +9,13 @@ class Test::Unit::TestCase
9
9
  })
10
10
  end
11
11
 
12
- def assert_contains(container, expected_contents, failure_message = nil)
12
+ def assert_includes(container, expected_contents, failure_message = nil)
13
13
  failure_message = build_message(failure_message, "Container <?> was expected to contain <?> but it didn't", container, expected_contents)
14
14
  assert_block(failure_message) do
15
15
  container.include?(expected_contents)
16
16
  end
17
17
  end
18
+ alias_method :assert_contains, :assert_includes
18
19
 
19
20
  # Asserts that the block that is passed in causes the value of the specified variable (+variable+) to change.
20
21
  # +variable+ should be a Proc that, when evaluated, returns the current value of the variable.
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require_gem 'colored'
3
+ require 'test/unit'
3
4
  require 'colored'
4
5
 
5
6
  module Test::Unit
@@ -4,7 +4,13 @@ require_local '../lib/svn_command.rb'
4
4
  require 'facets/core/string/to_re'
5
5
  require 'yaml'
6
6
 
7
- Subversion.color = false # Makes testing simpler. We can test that the *colorization* features are working via *manual* testing (they're not as critical).
7
+ Subversion.color = false
8
+ # Makes testing simpler. We can test all the *colorization* features via *manual* testing (since they're not as critical).
9
+ class String
10
+ def colorize(string, options = {})
11
+ string
12
+ end
13
+ end
8
14
 
9
15
  module Subversion
10
16
  class BaseSvnCommandTest < Test::Unit::TestCase
data/test/test_helper.rb CHANGED
@@ -8,9 +8,9 @@ $LOAD_PATH << File.dirname(__FILE__) + "/../lib"
8
8
  require_local "shared/test_helper"
9
9
 
10
10
  require_gem 'qualitysmith_extensions', '>=0.0.3'
11
- require 'test/assert_exception.rb'
12
- require 'capture_output.rb'
13
- require 'simulate_input.rb'
11
+ require 'qualitysmith_extensions/test/assert_exception.rb'
12
+ require 'qualitysmith_extensions/capture_output.rb'
13
+ require 'qualitysmith_extensions/simulate_input.rb'
14
14
 
15
15
  require 'subversion'
16
16
  if $mock_subversion
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: svn-command
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.6
7
- date: 2007-03-15 00:00:00 -07:00
6
+ version: 0.0.7
7
+ date: 2007-03-20 00:00:00 -07:00
8
8
  summary: A nifty wrapper command for Subversion's command-line svn client
9
9
  require_paths:
10
10
  - lib
@@ -40,7 +40,9 @@ files:
40
40
  - test/shared/test_helpers/assertions.rb
41
41
  - test/shared/test_helpers/test_colorizer.rb
42
42
  - bin/rscm_test
43
+ - bin/change_all_externals.sh
43
44
  - bin/command_completion_for_svn_command
45
+ - bin/change_all_externals.rb
44
46
  - bin/svn
45
47
  - Readme
46
48
  test_files: