svn-command 0.0.6 → 0.0.7

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.
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: