svn-command 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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: