pvn 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. data/README.markdown +38 -0
  2. data/bin/pvn +12 -0
  3. data/bin/pvndiff +10 -0
  4. data/lib/pvn/app.rb +144 -0
  5. data/lib/pvn/base/textlines.rb +35 -0
  6. data/lib/pvn/base/util.rb +14 -0
  7. data/lib/pvn/cmddoc.rb +77 -0
  8. data/lib/pvn/config.rb +65 -0
  9. data/lib/pvn/describe.rb +40 -0
  10. data/lib/pvn/diff/diffcmd.rb +49 -0
  11. data/lib/pvn/diff/differ.rb +67 -0
  12. data/lib/pvn/diff/diffopts.rb +58 -0
  13. data/lib/pvn/doc.rb +34 -0
  14. data/lib/pvn/io/element.rb +113 -0
  15. data/lib/pvn/io/fselement.rb +22 -0
  16. data/lib/pvn/log/formatter/color_formatter.rb +29 -0
  17. data/lib/pvn/log/formatter/entries_formatter.rb +33 -0
  18. data/lib/pvn/log/formatter/entry_formatter.rb +57 -0
  19. data/lib/pvn/log/formatter/log_formatter.rb +59 -0
  20. data/lib/pvn/log/formatter/message_formatter.rb +19 -0
  21. data/lib/pvn/log/formatter/path_formatter.rb +41 -0
  22. data/lib/pvn/log/formatter/summary_formatter.rb +49 -0
  23. data/lib/pvn/log/logcmd.rb +136 -0
  24. data/lib/pvn/log/logentry.rb +116 -0
  25. data/lib/pvn/log/logfactory.rb +101 -0
  26. data/lib/pvn/log/logoptions.rb +43 -0
  27. data/lib/pvn/pct/linecount.rb +33 -0
  28. data/lib/pvn/pct/pctcmd.rb +204 -0
  29. data/lib/pvn/pct/statcmd.rb +13 -0
  30. data/lib/pvn/revision/entry.rb +94 -0
  31. data/lib/pvn/revision.rb +119 -0
  32. data/lib/pvn/subcommands/base/clargs.rb +53 -0
  33. data/lib/pvn/subcommands/base/command.rb +60 -0
  34. data/lib/pvn/subcommands/base/doc.rb +94 -0
  35. data/lib/pvn/subcommands/base/options.rb +22 -0
  36. data/lib/pvn/subcommands/log/command.rb +70 -0
  37. data/lib/pvn/subcommands/log/options.rb +43 -0
  38. data/lib/pvn/subcommands/pct/clargs.rb +33 -0
  39. data/lib/pvn/subcommands/pct/command.rb +57 -0
  40. data/lib/pvn/subcommands/revision/multiple_revisions_option.rb +43 -0
  41. data/lib/pvn/subcommands/revision/revision_option.rb +74 -0
  42. data/lib/pvn/subcommands/revision/revision_regexp_option.rb +39 -0
  43. data/lib/pvn/svn/command/svncmd.rb +39 -0
  44. data/lib/pvn/svn/environment.rb +23 -0
  45. data/lib/pvn/svn/svnelement.rb +89 -0
  46. data/lib/pvn/svn/svninfo.rb +42 -0
  47. data/lib/pvn/svn/svnroot.rb +29 -0
  48. data/lib/pvn/upp/uppcmd.rb +112 -0
  49. data/lib/pvn/wherecmd.rb +55 -0
  50. data/lib/pvn.rb +8 -0
  51. data/lib/svnx/command.rb +60 -0
  52. data/lib/svnx/entry.rb +34 -0
  53. data/lib/svnx/info/command.rb +21 -0
  54. data/lib/svnx/info/entries.rb +27 -0
  55. data/lib/svnx/info/entry.rb +34 -0
  56. data/lib/svnx/log/command.rb +93 -0
  57. data/lib/svnx/log/entries.rb +57 -0
  58. data/lib/svnx/log/entry.rb +54 -0
  59. data/lib/svnx/status/command.rb +21 -0
  60. data/lib/svnx/status/entries.rb +22 -0
  61. data/lib/svnx/status/entry.rb +33 -0
  62. data/lib/synoption/base_option.rb +149 -0
  63. data/lib/synoption/boolean_option.rb +21 -0
  64. data/lib/synoption/doc.rb +81 -0
  65. data/lib/synoption/fixnum_option.rb +13 -0
  66. data/lib/synoption/match.rb +47 -0
  67. data/lib/synoption/option.rb +10 -0
  68. data/lib/synoption/optionable.rb +66 -0
  69. data/lib/synoption/set.rb +114 -0
  70. data/lib/system/cachecmd.rb +65 -0
  71. data/lib/system/cmdexec.rb +13 -0
  72. data/lib/system/cmdline.rb +70 -0
  73. data/lib/system/command/arg.rb +12 -0
  74. data/lib/system/command/cachefile.rb +39 -0
  75. data/lib/system/command/caching.rb +36 -0
  76. data/lib/system/command/line.rb +47 -0
  77. data/lib/system/command.rb +72 -0
  78. data/test/integration/svnx/log/test.rb +43 -0
  79. data/test/unit/pvn/app_test.rb +22 -0
  80. data/test/unit/pvn/io/element/log/log_test.rb +35 -0
  81. data/test/unit/pvn/log/formatter/entry_formatter_test.rb +90 -0
  82. data/test/unit/pvn/revision/entry_test.rb +123 -0
  83. data/test/unit/pvn/subcommands/log/command_test.rb +22 -0
  84. data/test/unit/pvn/subcommands/log/options_test.rb +85 -0
  85. data/test/unit/pvn/subcommands/revision/multiple_revisions_option_test.rb +67 -0
  86. data/test/unit/pvn/subcommands/revision/revision_option_test.rb +57 -0
  87. data/test/unit/pvn/subcommands/revision/revision_regexp_option_test.rb +69 -0
  88. data/test/unit/svnx/info/entry_test.rb +52 -0
  89. data/test/unit/svnx/log/cmargs_test.rb +22 -0
  90. data/test/unit/svnx/log/entries_test.rb +73 -0
  91. data/test/unit/svnx/log/entry_test.rb +21 -0
  92. data/test/unit/svnx/status/entry_test.rb +39 -0
  93. data/test/unit/synoption/base_option_test.rb +182 -0
  94. data/test/unit/synoption/match_test.rb +61 -0
  95. data/test/unit/synoption/option_test.rb +15 -0
  96. data/test/unit/synoption/set_test.rb +37 -0
  97. data/test/unit/system/command/caching_test.rb +97 -0
  98. data/test/unit/system/command/line_test.rb +33 -0
  99. metadata +199 -0
data/README.markdown ADDED
@@ -0,0 +1,38 @@
1
+ PVN
2
+ ===
3
+
4
+ Pvn adds functionality stolen and inspired by Perforce and Git, as well as just
5
+ things I conjured up.
6
+
7
+ What it isn't: a replace for svn (the command). The intent here is not to do
8
+ everything svn does, but better. Maybe some day that will happen.
9
+
10
+ SUMMARY
11
+ -------
12
+
13
+ svn [ options ] file ...
14
+
15
+ FEATURES
16
+ --------
17
+
18
+ **Relative revisions**: Pvn supports revisions being specified as being relative
19
+ to their "index" in the list of svn revision. "+n" means the nth revision in
20
+ the list for a given path, and "-n" is the nth from the last revision, where
21
+ -1 means the last revision.
22
+
23
+ Thus for the following list of revisions for a path:
24
+
25
+ r1947 | easter.bunny | 2011-11-14 07:24:45 -0500 (Mon, 14 Nov 2011) | 1 line
26
+ r1714 | santa.claus | 2011-09-22 16:38:30 -0400 (Thu, 22 Sep 2011) | 1 line
27
+ r1192 | santa.claus | 2011-09-05 03:51:04 -0400 (Mon, 05 Sep 2011) | 1 line
28
+ r1145 | tooth.fairy | 2011-08-02 04:57:23 -0400 (Tue, 02 Aug 2011) | 1 line
29
+ r1143 | santa.claus | 2011-07-29 07:51:49 -0400 (Fri, 29 Jul 2011) | 1 line
30
+ r1049 | santa.claus | 2011-06-22 07:17:43 -0400 (Wed, 22 Jun 2011) | 1 line
31
+
32
+ Relative revision +0 is r1049, -1 is r1947, +1 is r1143, and so on.
33
+
34
+ **Colorized logging**. The "log" subcommand works in pvn as it does with svn,
35
+ except that output is colorized, differing for the elements (file, directory) and
36
+ the status of the element (added, deleted, changed). The logging output also
37
+ shows the relative revision.
38
+
data/bin/pvn ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created on 2011-11-9.
4
+ # Copyright (c) 2011. All rights reserved.
5
+
6
+ require 'rubygems'
7
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/pvn")
8
+ require "pvn/app"
9
+
10
+ PVN::App::Runner.new STDOUT, ARGV
11
+
12
+ # PVN::App.execute(STDOUT, ARGV)
data/bin/pvndiff ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created on 2011-11-9.
4
+ # Copyright (c) 2011. All rights reserved.
5
+
6
+ require 'rubygems'
7
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/pvn")
8
+ require "pvn/diff/differ"
9
+
10
+ PVN::Differ.new ARGV
data/lib/pvn/app.rb ADDED
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'rubygems'
5
+ require 'riel'
6
+
7
+ require 'pvn/io/element'
8
+
9
+ require 'svnx/log/entries'
10
+
11
+ require 'pvn/subcommands/log/command'
12
+
13
+ # not yet supported:
14
+ # require 'pvn/subcommands/pct/command'
15
+
16
+ # the old ones:
17
+ require 'pvn/diff/diffcmd'
18
+ require 'pvn/pct/pctcmd'
19
+ require 'pvn/describe'
20
+ require 'pvn/upp/uppcmd'
21
+ require 'pvn/wherecmd'
22
+
23
+ module PVN; module App; end; end
24
+
25
+ module PVN::App
26
+ class Runner
27
+ include Loggable
28
+
29
+ def initialize io, args
30
+ RIEL::Log.level = RIEL::Log::WARN
31
+ RIEL::Log.set_widths(-25, 5, -35)
32
+
33
+ if args.empty?
34
+ run_help args
35
+ end
36
+
37
+ while args.size > 0
38
+ arg = args.shift
39
+ info "arg: #{arg}"
40
+
41
+ case arg
42
+ when "--verbose"
43
+ RIEL::Log.level = RIEL::Log::DEBUG
44
+ when "help", "--help", "-h"
45
+ run_help args
46
+ when "log"
47
+ run_command PVN::Subcommands::Log::Command, args
48
+ when "pct"
49
+ $stderr.puts "subcommand 'pct' is not yet supported"
50
+ exit(-1)
51
+ else
52
+ $stderr.puts "ERROR: subcommand not valid: #{arg}"
53
+ exit(-1)
54
+ end
55
+ end
56
+
57
+ run_help args
58
+ end
59
+
60
+ def run_command cmdcls, args
61
+ begin
62
+ cmdcls.new args
63
+ exit(0)
64
+ rescue => e
65
+ # puts e.backtrace
66
+ $stderr.puts e
67
+ exit(-1)
68
+ end
69
+ end
70
+
71
+ # below is the old implementation. yes, I should have branched this.
72
+ # =======================================================
73
+
74
+ def self.run_command_with_output cmd
75
+ RIEL::Log.info "cmd: #{cmd}".on_black
76
+ puts cmd.output
77
+ true
78
+ end
79
+
80
+ def self.run_command_as_entries cmd
81
+ RIEL::Log.info "cmd: #{cmd}".on_black
82
+ cmd.write_entries
83
+ true
84
+ end
85
+
86
+ SUBCOMMANDS = [ PVN::Subcommands::Log::Command,
87
+ # DiffCommand,
88
+ # DescribeCommand,
89
+ # PctCommand,
90
+ # WhereCommand,
91
+ # UndeleteCommand,
92
+ ]
93
+
94
+ def run_help args
95
+ forwhat = args[0]
96
+
97
+ cls = SUBCOMMANDS.find do |cls|
98
+ cls.getdoc.subcommands.include? forwhat
99
+ end
100
+
101
+ if cls
102
+ cls.to_doc
103
+ else
104
+ puts "usage: pvn [--verbose] <command> [<options>] [<args>]"
105
+ puts "PVN, version #{PVN::VERSION}"
106
+ puts
107
+ puts "PVN has the subcommands:"
108
+ SUBCOMMANDS.each do |sc|
109
+ printf " %-10s %s\n", sc.getdoc.subcommands[0], sc.getdoc.description
110
+ end
111
+ end
112
+ exit(0)
113
+ end
114
+
115
+ def self.execute stdout, args = Array.new
116
+ while args.size > 0
117
+ arg = args.shift
118
+ RIEL::Log.debug "arg: #{arg}"
119
+
120
+ if arg == "--verbose"
121
+ RIEL::Log.level = RIEL::Log::DEBUG
122
+ next
123
+ end
124
+
125
+ if arg == "help"
126
+ return run_help args
127
+ end
128
+
129
+ SUBCOMMANDS.each do |sc|
130
+ if sc.doc.subcommands.include?(arg)
131
+ cmd = sc.new :execute => true, :command_args => args
132
+ if cmd.has_entries?
133
+ return run_command_as_entries cmd
134
+ else
135
+ return run_command_with_output cmd
136
+ end
137
+ end
138
+ end
139
+
140
+ $stderr.puts "ERROR: subcommand not valid: #{arg}"
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'rubygems'
5
+ require 'riel'
6
+
7
+ module PVN
8
+ class TextLines
9
+ include Loggable
10
+
11
+ attr_reader :lines
12
+
13
+ def initialize lines
14
+ @lines = lines
15
+ @lidx = 0
16
+ end
17
+
18
+ def match_line re, offset = 0
19
+ re.match line(offset)
20
+ end
21
+
22
+ def line offset = 0
23
+ @lines[@lidx + offset]
24
+ end
25
+
26
+ def has_line?
27
+ @lidx < @lines.length
28
+ end
29
+
30
+ def advance_line offset = 1
31
+ @lidx += offset
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ module PVN
5
+ module Util
6
+ POS_NEG_NUMERIC_RE = Regexp.new('^[\-\+]?\d+$')
7
+
8
+ # Returns the list joined by spaces, with each element in the list in double
9
+ # quotes.
10
+ def self.quote_list args
11
+ args.collect { |a| "\"#{a}\"" }.join(' ')
12
+ end
13
+ end
14
+ end
data/lib/pvn/cmddoc.rb ADDED
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'rubygems'
5
+ require 'riel'
6
+
7
+ module PVN
8
+ class CommandDoc
9
+ attr_accessor :subcommands
10
+ attr_accessor :description
11
+ attr_accessor :usage
12
+ attr_accessor :summary
13
+
14
+ attr_reader :examples
15
+ attr_reader :options
16
+
17
+ def initialize
18
+ @subcommands = nil
19
+ @description = nil
20
+ @usage = nil
21
+ @summary = nil
22
+ @options = Array.new
23
+ @examples = Array.new
24
+ end
25
+
26
+ def to_doc io = $stdout
27
+ doc = Array.new
28
+
29
+ subcmds = @subcommands
30
+
31
+ subcmdstr = subcmds[0].dup
32
+ if subcmds.size > 1
33
+ subcmdstr << " (" << subcmds[1 .. -1].join(" ") << ")"
34
+ end
35
+
36
+ io.puts subcmdstr + ": " + @description
37
+ io.puts "usage: " + subcmds[0] + " " + @usage
38
+ io.puts ""
39
+ io.puts @summary.collect { |line| " " + line }
40
+
41
+ write_section "options", @options, io do |opt, io|
42
+ option_to_doc opt, io
43
+ end
44
+
45
+ write_section "examples", @examples, io do |ex, io|
46
+ example_to_doc ex, io
47
+ end
48
+ end
49
+
50
+ def write_section name, section, io
51
+ if section.length > 0
52
+ io.puts ""
53
+ io.puts "#{name.capitalize}:"
54
+ io.puts ""
55
+
56
+ section.each do |opt|
57
+ yield opt, io
58
+ end
59
+ end
60
+ end
61
+
62
+ def example_to_doc ex, io
63
+ ex.each_with_index do |line, idx|
64
+ if idx == 0
65
+ io.puts " % #{line}"
66
+ else
67
+ io.puts " #{line}"
68
+ end
69
+ end
70
+ io.puts
71
+ end
72
+
73
+ def option_to_doc opt, io
74
+ opt.to_doc io
75
+ end
76
+ end
77
+ end
data/lib/pvn/config.rb ADDED
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'rubygems'
5
+ require 'riel'
6
+ require 'singleton'
7
+
8
+ module PVN
9
+ class Configuration
10
+ def initialize
11
+ @@instance = self
12
+ @values = Hash.new { |h, k| h[k] = Array.new }
13
+ end
14
+
15
+ def config &blk
16
+ blk.call self
17
+ end
18
+
19
+ def self.config &blk
20
+ @@instance.config(&blk)
21
+ end
22
+
23
+ def self.read
24
+ @@instance ||= begin
25
+ cfg = self.new
26
+ pvndir = ENV['HOME'] + '/.pvn'
27
+ cfgfile = pvndir + '/config'
28
+
29
+ begin
30
+ require cfgfile
31
+ rescue LoadError => e
32
+ # no configuration
33
+ end
34
+ cfg
35
+ end
36
+ end
37
+
38
+ def value name, field
39
+ @values[name][field]
40
+ end
41
+
42
+ def section name
43
+ @values[name]
44
+ end
45
+
46
+ def method_missing meth, *args, &blk
47
+ eqre = Regexp.new('^(\w+)=')
48
+ # puts "method missing: #{meth}"
49
+ if md = eqre.match(meth.to_s)
50
+ name = md[1]
51
+ @values[@current] << [ name.to_s, *args ]
52
+ # puts "@values: #{@values}"
53
+ else
54
+ @current = meth.to_s
55
+ yield self
56
+ @current = nil
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+
63
+ if __FILE__ == $0
64
+ cfg = PVN::Configuration.read
65
+ end
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'system/command'
5
+ # require 'pvn/diff'
6
+
7
+ module PVN
8
+ class DescribeCommand < Command
9
+ COMMAND = "describe"
10
+
11
+ self.doc do |doc|
12
+ doc.subcommands = [ COMMAND, 'desc' ]
13
+ doc.description = "Describes the changes of one or more revisions."
14
+ doc.usage = "[OPTIONS] FILE..."
15
+ doc.summary = [ " Prints the log message and the files changed for the given",
16
+ " revisions." ]
17
+ doc.examples << [ "pvn describe -1 foo.rb", "Prints the summary for the most recent revision of foo.rb." ]
18
+ end
19
+
20
+ # has_option :limit, '-l', "the number of log entries", DEFAULT_LIMIT, :negate => [ %r{^--no-?limit} ]
21
+ has_revision_option :multiple => true
22
+
23
+ def initialize args = Hash.new
24
+ info "args: #{args}".on_blue
25
+ super
26
+ end
27
+
28
+ def run args
29
+ info "args: #{args}".on_yellow
30
+ revisions = find_option(:revision).value
31
+
32
+ info "revisions: #{revisions}".yellow
33
+
34
+ revisions.each do |rev|
35
+ info "svn log -r #{rev}"
36
+ info "svn diff --summarize -c #{rev}"
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'pvn/config'
5
+ require 'pvn/svn/command/svncmd'
6
+ require 'pvn/diff/diffopts'
7
+
8
+ module PVN
9
+ class DiffCommand < SVNCommand
10
+ COMMAND = "diff"
11
+
12
+ attr_reader :options
13
+
14
+ self.doc do |doc|
15
+ doc.subcommands = [ COMMAND ]
16
+ doc.description = "Displays differences between revisions."
17
+ doc.usage = "[OPTIONS] FILE..."
18
+ doc.summary = [ "Compare two revisions, filtering through external programs.",
19
+ "For each file compared, the file extension is used to find",
20
+ "a diff program." ]
21
+ doc.options.concat DiffOptionSet.new.options
22
+ doc.examples << [ "pvn diff foo.rb", "Compares foo.rb against the last updated version." ]
23
+ doc.examples << [ "pvn diff -3 StringExt.java", "Compares StringExt.java at change (HEAD - 3), using a Java-specific program such as DiffJ." ]
24
+ doc.examples << [ "pvn diff -r +4 -w", "Compares the 4th revision against the working copy, ignoring whitespace." ]
25
+ end
26
+
27
+ def initialize args = Hash.new
28
+ @options = DiffOptionSet.new
29
+ debug "args: #{args.inspect}".yellow
30
+
31
+ super
32
+ end
33
+
34
+ def use_cache?
35
+ super && !against_head?
36
+ end
37
+
38
+ def against_head?
39
+ @options.change.value.nil? && @options.revision.head?
40
+ end
41
+
42
+ # @todo implement
43
+ if true
44
+ self.options do |opts|
45
+ # opts.add :diffcmd
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'pathname'
5
+ require 'pvn/config'
6
+
7
+ module PVN
8
+ # the app for svn --diff-cmd
9
+ class Differ
10
+ include Loggable
11
+
12
+ def initialize args
13
+ fromlabel = args[2]
14
+ tolabel = args[4]
15
+
16
+ fromname, fromrev = fromlabel.split("\t")
17
+ toname, torev = tolabel.split("\t")
18
+
19
+ fromfile = args[-2]
20
+ tofile = args[-1]
21
+
22
+ diffcmd = diff_command_by_ext fromname
23
+ info "diffcmd: #{diffcmd}"
24
+
25
+ if diffcmd
26
+ workingcmd = diffcmd.dup
27
+
28
+ [ fromlabel, tolabel, fromfile, tofile ].each_with_index do |str, idx|
29
+ workingcmd.gsub! Regexp.new('\{' + idx.to_s + '\}'), str
30
+ end
31
+
32
+ run_command workingcmd
33
+ else
34
+ run_diff_default fromlabel, tolabel, fromfile, tofile
35
+ end
36
+ end
37
+
38
+ def diff_command_by_ext fname
39
+ extname = Pathname.new(fname).extname
40
+ return nil if extname.empty?
41
+
42
+ ext = extname[1 .. -1]
43
+
44
+ cfg = PVN::Configuration.read
45
+
46
+ diffcfg = cfg.section "diff"
47
+ return nil unless diffcfg
48
+
49
+ diff_for_ext = diffcfg.assoc(ext)
50
+ diff_for_ext && diff_for_ext[1]
51
+ end
52
+
53
+ def run_diff_default fromfname, tofname, fromfile, tofile
54
+ cmd = "diff -u --label \"#{fromfname}\" --label \"#{tofname}\" #{fromfile} #{tofile}"
55
+ run_command cmd
56
+ end
57
+
58
+ def run_command cmd
59
+ info "cmd: #{cmd}".red
60
+ IO.popen(cmd) do |io|
61
+ io.each do |line|
62
+ puts line
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'synoption/set'
5
+ require 'pvn/subcommands/revision/revision_option'
6
+
7
+ module PVN
8
+ thisfile = Pathname.new __FILE__
9
+ PVNDIFF_CMD = (thisfile.parent.parent.parent.parent + "bin/pvndiff").expand_path
10
+
11
+ POS_NEG_NUMERIC_RE = Regexp.new('^[\-\+]?\d+$')
12
+
13
+ # "pvn diff -3" == "pvn diff -c -3", not "pvn diff -r -3", because
14
+ # we diff for the change, not from that revision to head.
15
+
16
+ class DiffRevisionOption < RevisionOption
17
+ def head?
18
+ value.nil? || value == 'HEAD'
19
+ end
20
+ end
21
+
22
+ class DiffChangeOption < Option
23
+ def initialize chgargs = Hash.new
24
+ chgargs[:setter] = :revision_from_args
25
+ chgargs[:regexp] = POS_NEG_NUMERIC_RE
26
+
27
+ super :change, '-c', "change", chgargs
28
+ end
29
+ end
30
+
31
+ class DiffWhitespaceOption < Option
32
+ def initialize wsargs = Hash.new
33
+ super :whitespace, '-W', "ignore all whitespace", wsargs
34
+ end
35
+
36
+ def to_command_line
37
+ if value
38
+ %w{ -x -w -x -b -x --ignore-eol-style }
39
+ end
40
+ end
41
+ end
42
+
43
+ class DiffOptionSet < OptionSet
44
+ attr_reader :change
45
+ attr_reader :revision
46
+
47
+ def initialize
48
+ super
49
+
50
+ # diffcmd is old/new option style (non-subclass of Option)
51
+ diffcmd = PVNDIFF_CMD.exist? && PVNDIFF_CMD
52
+ @diffcmdopt = add Option.new :diffcmd, "--diff-cmd", "the program to run diff through", diffcmd, :negate => [ %r{^--no-?diff-?cmd} ]
53
+ @change = add DiffChangeOption.new
54
+ @revision = add DiffRevisionOption.new
55
+ @whitespace = add DiffWhitespaceOption.new
56
+ end
57
+ end
58
+ end
data/lib/pvn/doc.rb ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'rubygems'
5
+ require 'riel'
6
+ require 'pvn/documenter'
7
+
8
+ # Log.level = Log::DEBUG
9
+
10
+ module PVN
11
+ module Doc
12
+ include Loggable
13
+
14
+ def self.included base
15
+ base.extend ClassMethods
16
+ end
17
+
18
+ module ClassMethods
19
+ [ :subcommands, :description, :usage, :summary, :examples ].each do |name|
20
+ define_method name do |val|
21
+ self.instance_eval do
22
+ @doc ||= Documenter.new
23
+ meth = (name.to_s + '=').to_sym
24
+ @doc.send meth, val
25
+ end
26
+ end
27
+ end
28
+
29
+ def to_doc io = $stdout
30
+ self.instance_eval { @doc.to_doc io }
31
+ end
32
+ end
33
+ end
34
+ end