svn-command 0.0.3 → 0.0.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.
data/Readme CHANGED
@@ -1,14 +1,14 @@
1
1
  = <i>Enhanced Subversion command</i> -- an +svn+ command wrapper
2
2
 
3
3
  [*Environment*:] Command line
4
+ [<b>Home page</b>:] http://svncommand.rubyforge.org/
4
5
  [<b>Project site</b>:] http://rubyforge.org/projects/svncommand
5
- [<b>Documentation</b>:] http://svncommand.rubyforge.org/
6
6
  [<b>Wiki</b>:] http://wiki.qualitysmith.com/svn-command
7
7
  [<b>Author</b>:] Tyler Rick
8
8
 
9
9
  == Introduction
10
10
 
11
- This is a replacement <tt>svn</tt> <b>command-line client</b> meant to be used instead of the standard +svn+ command.
11
+ This is a replacement <tt>svn</tt> <b>command-line client</b> meant to be used instead of the standard +svn+ command. Actually, it's a /wrapper/, not a replacement, because it still uses <tt>/usr/bin/svn</tt> to do all the dirty work.
12
12
 
13
13
  == Installation
14
14
 
@@ -18,25 +18,29 @@ Currently a _patched_ version of Console::Command is required. The patched vesio
18
18
 
19
19
  /usr/lib/ruby/gems/1.8/gems/facets-1.8.51/lib/facets/more/command.rb
20
20
 
21
- (These changes will hopefully be absorbed into the next release.)
21
+ (These changes will hopefully be absorbed into the next release of facets. I apologize for the inconvenience.)
22
22
 
23
23
  === Installation: Per system
24
24
 
25
25
  sudo gem install svn-command
26
26
 
27
- You also need to make those files executable (once per _system_):
27
+ You also need to make those files *executable* (once per _system_):
28
28
 
29
29
  sudo chmod a+x /usr/lib/ruby/gems/1.8/gems/svn-command-0.0.3/bin/*
30
30
 
31
- (We can't just set <tt>executables = "svn"</tt> because that would cause it to wipe out the existing executable at <tt>/usr/bin/svn</tt>! If you know of a better, more automatic solution to this, please let the developers know!)
31
+ (We can't just set <tt>executables = "svn"</tt> and have it automatically install it to /usr/bin because that would cause it to <b>wipe out</b> the existing executable at <tt>/usr/bin/svn</tt>! If you know of a better, more automatic solution to this, please let the developers know!)
32
32
 
33
33
  And for some reason I seem to have to restart my terminal after doing the chmod step for bash to detect the svn command in that new location.
34
34
 
35
35
  === Installation: Per user
36
36
 
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>. For example:
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=/usr/lib/ruby/gems/1.8/gems/svn-command-0.0.3/bin:$PATH
39
+ export PATH=`ls -d /usr/lib/ruby/gems/1.8/gems/svn-command* | tail -n1`/bin:$PATH
40
+
41
+ Or hard-code the path, if you really want to:
42
+
43
+ export PATH=/usr/lib/ruby/gems/1.8/gems/svn-command-0.0.4/bin:$PATH
40
44
 
41
45
  (I'm not sure if this is possible to automate with the <tt>gem install</tt> process or not. But in the meantime you need to do it manually.)
42
46
 
@@ -48,18 +52,22 @@ You'll know it's working by way of two signs:
48
52
  == Features
49
53
 
50
54
  Changes to existing subcommands:
51
- * <tt>svn diff</tt> output is in _color_ (requires +colordiff+, see below)
55
+ * <tt>svn diff</tt> output is in _color_* (requires +colordiff+, see below)
52
56
  * <tt>svn diff</tt> includes the differences from your *externals* too (consistent with how <tt>svn status</tt> includes them) so that you don't forget to commit those changes too!
53
- * <tt>svn status</tt> output filters out distracting, useless output about externals (if you want a list of externals, use <tt>svn externals</tt>
57
+ * <tt>svn status</tt>
58
+ ** filters out distracting, useless output about externals (don't worry -- it still shows which files were _modified_)
59
+ ** the flags (?, M, C, etc.) are in *color*!
60
+
61
+ (* You can pass --no-color to disable colors for a single command...useful if you want to pipe the output to another command or something. Eventually maybe we could make this a per-user option via .svn-command?)
54
62
 
55
63
  New subcommands:
56
- * <tt>svn each_unadded</tt> (+eu+) -- goes through each unadded (<tt>?</tt>) file reported by <tt>svn status</tt> and asks you what to do with them (add, delete, ignore).
57
- * <tt>svn externals</tt>
64
+ * <tt>svn each_unadded</tt> (+eu+, +unadded+) -- goes through each unadded (<tt>?</tt>) file reported by <tt>svn status</tt> and asks you what to do with them (add, delete, ignore).
65
+ * <tt>svn externals</tt> -- lists all externals
58
66
  * <tt>svn edit_externals</tt> (+ee+)
59
67
  * <tt>svn externalize</tt>
60
- * <tt>svn set_message</tt> / <tt>svn get_message</tt> / <tt>svn edit_message</tt>
61
- * <tt>svn ignore</tt>
62
- * <tt>svn view_commits</tt> (gives you output from both svn log and from svn diff for the given changesets)
68
+ * <tt>svn set_message</tt> / <tt>svn get_message</tt> / <tt>svn edit_message</tt> -- shortcuts for accessing <tt>--revprop svn:log</tt>
69
+ * <tt>svn ignore</tt> -- shortcut for accessing <tt>svn:ignore</tt> property
70
+ * <tt>svn view_commits</tt> -- gives you output from both <tt>svn log</tt> and from <tt>svn diff</tt> for the given changesets (useful for code reviews)
63
71
 
64
72
  (RDoc question: how do I make the identifiers like Subversion::SvnCommand#externalize into links??)
65
73
 
@@ -129,7 +137,7 @@ It simply goes through each "unadded" file (each file reporting a status of <tt>
129
137
  Are you pretty much *SURE* you want to 'rm -rf applications/underlord/vendor/plugins/exception_notification'? (y)es, (n)o > y
130
138
  Deleting...
131
139
 
132
- For *files*, it will show a preview of the _contents_ of that file (limited to the first 3000 characters); for *directories*, it will show a _directory_ _listing_. By looking at the preview, you should hopefully be able to decide whether you want to keep the file or junk it.
140
+ For *files*, it will show a preview of the _contents_ of that file (limited to the first 3000 characters); for *directories*, it will show a _directory_ _listing_. By looking at the preview, you should hopefully be able to decide whether you want to _keep_ the file or _junk_ it.
133
141
 
134
142
  ===externalize / externals / edit_externals
135
143
 
@@ -194,6 +202,7 @@ You can, of course, get a lits of the custom commands that have been added by us
194
202
 
195
203
  * --no-color (since color is on by default)
196
204
  * --dry-run (see what /usr/bin/svn command it _would_ have executed if you weren't just doing a dry run -- useful for debugging if nothing else)
205
+ * --show-commands (prints out the /usr/bin/svn commands before executing them)
197
206
  * --debug (sets $debug = true)
198
207
 
199
208
  ==colordiff
@@ -295,9 +295,29 @@ protected
295
295
  #Kernel.exec *args
296
296
  Kernel.exec command
297
297
  when :popen
298
- # To do: rather than `...`, which waits until command is finished before you get any output, maybe do popen and output the output in realtime!
298
+ # This is just an idea of how maybe we could speed up the performance a bit. Rather than waiting until the command completes
299
+ # (which can take quite a while for svn status sometimes since it has to walk the entire directory tree), why not process
300
+ # the output from /usr/bin/svn *in real-time*??
301
+ #
302
+ # Unfortunately, it looks like /usr/bin/svn itself might make that impossible. It seems that if it detects that its output is
303
+ # being redirected to a pipe, it will not yield any output until the command is finished!
304
+ #
305
+ # So even though this command gives you output in real-time:
306
+ # find / | grep .
307
+ # as does this:
308
+ # IO.popen('find /', 'r') {|p| line = ""; ( puts line; $stdout.flush ) until !(line = p.gets) }
309
+ # as does this:
310
+ # /usr/bin/svn st
311
+ #
312
+ # ... as soon as you redirect svn to a *pipe*, it seems to automatically (annoyingly) buffer its output until it's finished:
313
+ # /usr/bin/svn st | grep .
314
+ # So when I tried this:
315
+ # IO.popen('/usr/bin/svn st', 'r') {|p| line = ""; ( puts line; $stdout.flush ) until !(line = p.gets) }
316
+ # it didn't seem any more responsive than a plain puts `/usr/bin/svn st` ! Frustrating!
317
+ #
299
318
  IO.popen(command, 'r') do |pipe|
300
- pipe.read
319
+ line = ""
320
+ ( puts line; $stdout.flush ) until !(line = pipe.gets)
301
321
  end
302
322
  else
303
323
  raise ArgumentError.new(":method option must be one of #{valid_options.inspect}")
@@ -1,11 +1,30 @@
1
1
  # Tested by: ../test/subversion_extensions_test.rb
2
2
 
3
+ require_gem 'colored'
4
+ require 'colored'
5
+
3
6
  class Array
4
7
  def to_regexp_char_class
5
8
  "[#{join('')}]"
6
9
  end
7
10
  end
8
11
 
12
+ class String
13
+ def colorize_svn_status_lines
14
+ if Subversion.color
15
+ self.gsub(/^ *\?/) { $&.yellow.bold}.
16
+ gsub(/^ *A/) { $&.green.bold}.
17
+ gsub(/^ *M/) { $&.green.bold}.
18
+ gsub(/^ *C/) { $&.red.bold}.
19
+ gsub(/^ *~/) { $&.red.bold}.
20
+ gsub(/^ *!/) { $&.red.bold}
21
+ else
22
+ self
23
+ end
24
+ end
25
+ end
26
+
27
+
9
28
  # These are methods used by the SvnCommand for filtering and whatever else it needs...
10
29
  # 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.
11
30
  # Rename to Subversion::Filters ? Then would each_unadded fit?
@@ -16,13 +35,28 @@ module Subversion
16
35
  Status_flags = Interesting_status_flags | Uninteresting_status_flags
17
36
 
18
37
  def self.status_lines_filter(input)
19
- (input || "").reject { |line|
38
+ input = (input || "").reject { |line|
20
39
  line =~ /^$/ # Blank lines
21
- }.reject { |line|
22
- line =~ /^Performing status on external item at/
23
40
  }.reject { |line|
24
41
  line =~ /^#{Uninteresting_status_flags.to_regexp_char_class}/
25
42
  }.join
43
+
44
+ before_externals, *externals = input.split(/^Performing status on external item at.*$/)
45
+
46
+ before_externals ||= ''
47
+ before_externals = before_externals.strip.colorize_svn_status_lines + "\n" if before_externals != ""
48
+
49
+ externals = externals.join
50
+ externals =
51
+ '_'*40 + ' externals '.underline + '_'*40 + "\n" +
52
+ externals.reject { |line|
53
+ line =~ /^Performing status on external item at/
54
+ }.reject { |line|
55
+ line =~ /^$/ # Blank lines
56
+ }.join.strip.colorize_svn_status_lines + "\n" if externals != ""
57
+
58
+ before_externals +
59
+ externals
26
60
  end
27
61
 
28
62
  def self.update_lines_filter(input)
@@ -15,6 +15,10 @@ require 'extensions/symbol' # to_proc
15
15
  require 'pp'
16
16
  require 'termios'
17
17
  require 'stringio'
18
+ require_gem 'colored'
19
+ require 'colored'
20
+ # Lets us do "(a)".white.bold instead of "(\033[1ma\033[0m)"
21
+ #- Warning: Make sure you have the *right* color gem! gem install color --source require.errtheblog.com
18
22
  require_local '../lib/subversion'
19
23
  require_local '../lib/subversion_extensions'
20
24
 
@@ -76,7 +80,7 @@ module Subversion
76
80
  def __dry_run
77
81
  Subversion::dry_run = true
78
82
  end
79
- def __print
83
+ def __show_commands
80
84
  Subversion::print_commands = true
81
85
  end
82
86
 
@@ -95,6 +99,10 @@ module Subversion
95
99
  #puts "method_missing(#{subcommand}, #{args.inspect})"
96
100
  svn :exec, subcommand, *args
97
101
  end
102
+ # This is here solely to allow subcommandless commands like `svn --version`
103
+ def default()
104
+ svn :exec
105
+ end
98
106
 
99
107
  def option_missing(option_name, args)
100
108
  #puts "#{@subcommand} defined? #{@subcommand_is_defined}"
@@ -183,14 +191,14 @@ module Subversion
183
191
  )
184
192
  end
185
193
 
186
- #def diff(*args)
187
- def diff(directory = "./")
188
- print Subversion.diff(*([directory] + @passthrough_options))
194
+ def diff(*directories)
195
+ directories = ["./"] if directories.empty?
196
+ print Subversion.diff(*(directories + @passthrough_options))
189
197
 
190
198
  # Show diff for externals (if there are any)
191
199
  output = StringIO.new
192
200
  #paths = args.reject{|arg| arg =~ /^-/} || ['./']
193
- [directory].each do |path|
201
+ directories.each do |path|
194
202
  (Subversion.externals_containers(path) || []).each do |external|
195
203
  #puts external.to_s
196
204
  external.entries.each do |entry|
@@ -391,8 +399,8 @@ End
391
399
  begin
392
400
  response = ""
393
401
  loop do
394
- puts '-'*100
395
- puts "What do you want to do with '#{file}'?"
402
+ puts( ('-'*100).green )
403
+ puts "What do you want to do with '#{file.white.underline}'?".white.bold
396
404
  begin
397
405
  if File.file?(file)
398
406
  # Only show the first x bytes so that we don't accidentally dump the contens of some 20 GB log file to screen...
@@ -406,9 +414,15 @@ End
406
414
  raise "#{file} is not a file or directory -- what *is* it??"
407
415
  end
408
416
  end
409
- print "(a)dd, (d)elete, add to svn:(i)ignore property, or [Enter] to do nothing > "
417
+ print(
418
+ "" + "A".green.bold.underline + "dd, ".green +
419
+ "".red + "D".red.bold.underline + "elete".red + ", " +
420
+ "add to " + "svn:".yellow + "I".yellow.bold.underline + "gnore".yellow + " property, " +
421
+ "or [" + "Enter".white.bold + "] to do nothing > "
422
+ )
410
423
  response = ""
411
424
  response = $stdin.getc.chr while !['a', 'd', 'i', "\n"].include?(begin response.downcase!; response end)
425
+
412
426
  break
413
427
  end
414
428
 
@@ -445,6 +459,7 @@ End
445
459
  end # catch :exit
446
460
  end
447
461
  alias_subcommand :eu => :each_unadded
462
+ alias_subcommand :unadded => :each_unadded
448
463
 
449
464
 
450
465
 
@@ -611,7 +626,11 @@ End
611
626
  private
612
627
  def svn(method, *args)
613
628
  subcommand = args[0]
614
- args = ([subcommand] + prepare_args(args[1..-1]) + [:method => method])
629
+ args = (
630
+ [subcommand] +
631
+ prepare_args(args[1..-1] || []) +
632
+ [:method => method]
633
+ )
615
634
  # puts "in svn(): about to call Subversion#execute(#{args.inspect})"
616
635
  Subversion.send :execute, *args
617
636
  end
@@ -1,5 +1,7 @@
1
1
  require 'rubygems'
2
- require 'color' # Warning: Make sure you have the *right* color gem! gem install color --source require.errtheblog.com
2
+ require_gem 'colored'
3
+ require 'colored'
4
+
3
5
  module Test::Unit
4
6
 
5
7
  class Error
@@ -1,12 +1,17 @@
1
1
  require File.dirname(__FILE__) + '/test_helper'
2
2
  require 'subversion_extensions'
3
3
 
4
+ Subversion.color = false # Makes testing simpler. We can just test that the *colorization* features are working via *manual* tests.
4
5
 
5
6
  class SubversionExtensionsTest < Test::Unit::TestCase
6
7
  def setup
7
8
  end
8
9
 
9
10
  def test_status_lines_filter
11
+
12
+ #String.any_instance.stubs(:underline).returns(lambda {|a| a}) # Doesn't work! Lame! So we can't make the return value depend on the input?
13
+ String.any_instance.stubs(:underline).returns(lambda {' externals '})
14
+
10
15
  input = <<End
11
16
  M gemables/calculator/test/calculator_test.rb
12
17
  X gemables/calculator/tasks/shared
@@ -24,6 +29,7 @@ End
24
29
  expected = <<End
25
30
  M gemables/calculator/test/calculator_test.rb
26
31
  ? gemables/calculator/lib/calculator_extensions.rb
32
+ ________________________________________ externals ________________________________________
27
33
  M applications/underlord/vendor/plugins/nifty/tasks/shared/base.rake
28
34
  End
29
35
 
@@ -4,7 +4,7 @@ require_local '../lib/svn_command.rb'
4
4
  require 'facets/core/string/to_re'
5
5
  require 'yaml'
6
6
 
7
-
7
+ Subversion.color = false # Makes testing simpler. We can just test that the *colorization* features are working via *manual* tests.
8
8
 
9
9
  module Subversion
10
10
  class BaseSvnCommandTest < Test::Unit::TestCase
@@ -104,7 +104,7 @@ class SvnDiffTest < BaseSvnCommandTest
104
104
  def test_1
105
105
  SvnCommand.execute("diff -r 123:125")
106
106
  assert_equal [
107
- "svn diff --diff-cmd colordiff ./ -r 123:125",
107
+ "svn diff ./ -r 123:125",
108
108
  "svn status ./"
109
109
  ], Subversion.executed
110
110
  end
@@ -112,8 +112,8 @@ class SvnDiffTest < BaseSvnCommandTest
112
112
  #:fixme:
113
113
  #capture_output { SvnCommand.execute("diff -r { 2006-07-01 }") }
114
114
  #p Subversion.executed
115
- # Currently does this, since it thinks the arity is 1: --diff-cmd colordiff 2006-07-01 } -r '{'
116
- #assert_equal "svn diff --diff-cmd colordiff -r { 2006-07-01 }", Subversion.executed.join
115
+ # Currently does this, since it thinks the arity is 1: 2006-07-01 } -r '{'
116
+ #assert_equal "svn diff -r { 2006-07-01 }", Subversion.executed.join
117
117
  end
118
118
  end
119
119
 
@@ -150,10 +150,12 @@ X applications/underlord/vendor/plugins/nifty/doc_include/template
150
150
  Performing status on external item at 'applications/underlord/vendor/plugins/nifty/tasks/shared'
151
151
  M applications/underlord/vendor/plugins/nifty/tasks/shared/base.rake
152
152
  ")
153
+ String.any_instance.stubs(:underline).returns(lambda {' externals '})
153
154
 
154
155
  expected = <<End
155
156
  M gemables/calculator/test/calculator_test.rb
156
157
  ? gemables/calculator/lib/calculator_extensions.rb
158
+ ________________________________________ externals ________________________________________
157
159
  M applications/underlord/vendor/plugins/nifty/tasks/shared/base.rake
158
160
  End
159
161
 
metadata CHANGED
@@ -3,7 +3,7 @@ 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.3
6
+ version: 0.0.4
7
7
  date: 2007-03-15 00:00:00 -07:00
8
8
  summary: A nifty wrapper command for Subversion's command-line svn client
9
9
  require_paths:
@@ -73,3 +73,12 @@ dependencies:
73
73
  - !ruby/object:Gem::Version
74
74
  version: 0.0.0
75
75
  version:
76
+ - !ruby/object:Gem::Dependency
77
+ name: colored
78
+ version_requirement:
79
+ version_requirements: !ruby/object:Gem::Version::Requirement
80
+ requirements:
81
+ - - ">"
82
+ - !ruby/object:Gem::Version
83
+ version: 0.0.0
84
+ version: