pvn 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +38 -0
- data/bin/pvn +12 -0
- data/bin/pvndiff +10 -0
- data/lib/pvn/app.rb +144 -0
- data/lib/pvn/base/textlines.rb +35 -0
- data/lib/pvn/base/util.rb +14 -0
- data/lib/pvn/cmddoc.rb +77 -0
- data/lib/pvn/config.rb +65 -0
- data/lib/pvn/describe.rb +40 -0
- data/lib/pvn/diff/diffcmd.rb +49 -0
- data/lib/pvn/diff/differ.rb +67 -0
- data/lib/pvn/diff/diffopts.rb +58 -0
- data/lib/pvn/doc.rb +34 -0
- data/lib/pvn/io/element.rb +113 -0
- data/lib/pvn/io/fselement.rb +22 -0
- data/lib/pvn/log/formatter/color_formatter.rb +29 -0
- data/lib/pvn/log/formatter/entries_formatter.rb +33 -0
- data/lib/pvn/log/formatter/entry_formatter.rb +57 -0
- data/lib/pvn/log/formatter/log_formatter.rb +59 -0
- data/lib/pvn/log/formatter/message_formatter.rb +19 -0
- data/lib/pvn/log/formatter/path_formatter.rb +41 -0
- data/lib/pvn/log/formatter/summary_formatter.rb +49 -0
- data/lib/pvn/log/logcmd.rb +136 -0
- data/lib/pvn/log/logentry.rb +116 -0
- data/lib/pvn/log/logfactory.rb +101 -0
- data/lib/pvn/log/logoptions.rb +43 -0
- data/lib/pvn/pct/linecount.rb +33 -0
- data/lib/pvn/pct/pctcmd.rb +204 -0
- data/lib/pvn/pct/statcmd.rb +13 -0
- data/lib/pvn/revision/entry.rb +94 -0
- data/lib/pvn/revision.rb +119 -0
- data/lib/pvn/subcommands/base/clargs.rb +53 -0
- data/lib/pvn/subcommands/base/command.rb +60 -0
- data/lib/pvn/subcommands/base/doc.rb +94 -0
- data/lib/pvn/subcommands/base/options.rb +22 -0
- data/lib/pvn/subcommands/log/command.rb +70 -0
- data/lib/pvn/subcommands/log/options.rb +43 -0
- data/lib/pvn/subcommands/pct/clargs.rb +33 -0
- data/lib/pvn/subcommands/pct/command.rb +57 -0
- data/lib/pvn/subcommands/revision/multiple_revisions_option.rb +43 -0
- data/lib/pvn/subcommands/revision/revision_option.rb +74 -0
- data/lib/pvn/subcommands/revision/revision_regexp_option.rb +39 -0
- data/lib/pvn/svn/command/svncmd.rb +39 -0
- data/lib/pvn/svn/environment.rb +23 -0
- data/lib/pvn/svn/svnelement.rb +89 -0
- data/lib/pvn/svn/svninfo.rb +42 -0
- data/lib/pvn/svn/svnroot.rb +29 -0
- data/lib/pvn/upp/uppcmd.rb +112 -0
- data/lib/pvn/wherecmd.rb +55 -0
- data/lib/pvn.rb +8 -0
- data/lib/svnx/command.rb +60 -0
- data/lib/svnx/entry.rb +34 -0
- data/lib/svnx/info/command.rb +21 -0
- data/lib/svnx/info/entries.rb +27 -0
- data/lib/svnx/info/entry.rb +34 -0
- data/lib/svnx/log/command.rb +93 -0
- data/lib/svnx/log/entries.rb +57 -0
- data/lib/svnx/log/entry.rb +54 -0
- data/lib/svnx/status/command.rb +21 -0
- data/lib/svnx/status/entries.rb +22 -0
- data/lib/svnx/status/entry.rb +33 -0
- data/lib/synoption/base_option.rb +149 -0
- data/lib/synoption/boolean_option.rb +21 -0
- data/lib/synoption/doc.rb +81 -0
- data/lib/synoption/fixnum_option.rb +13 -0
- data/lib/synoption/match.rb +47 -0
- data/lib/synoption/option.rb +10 -0
- data/lib/synoption/optionable.rb +66 -0
- data/lib/synoption/set.rb +114 -0
- data/lib/system/cachecmd.rb +65 -0
- data/lib/system/cmdexec.rb +13 -0
- data/lib/system/cmdline.rb +70 -0
- data/lib/system/command/arg.rb +12 -0
- data/lib/system/command/cachefile.rb +39 -0
- data/lib/system/command/caching.rb +36 -0
- data/lib/system/command/line.rb +47 -0
- data/lib/system/command.rb +72 -0
- data/test/integration/svnx/log/test.rb +43 -0
- data/test/unit/pvn/app_test.rb +22 -0
- data/test/unit/pvn/io/element/log/log_test.rb +35 -0
- data/test/unit/pvn/log/formatter/entry_formatter_test.rb +90 -0
- data/test/unit/pvn/revision/entry_test.rb +123 -0
- data/test/unit/pvn/subcommands/log/command_test.rb +22 -0
- data/test/unit/pvn/subcommands/log/options_test.rb +85 -0
- data/test/unit/pvn/subcommands/revision/multiple_revisions_option_test.rb +67 -0
- data/test/unit/pvn/subcommands/revision/revision_option_test.rb +57 -0
- data/test/unit/pvn/subcommands/revision/revision_regexp_option_test.rb +69 -0
- data/test/unit/svnx/info/entry_test.rb +52 -0
- data/test/unit/svnx/log/cmargs_test.rb +22 -0
- data/test/unit/svnx/log/entries_test.rb +73 -0
- data/test/unit/svnx/log/entry_test.rb +21 -0
- data/test/unit/svnx/status/entry_test.rb +39 -0
- data/test/unit/synoption/base_option_test.rb +182 -0
- data/test/unit/synoption/match_test.rb +61 -0
- data/test/unit/synoption/option_test.rb +15 -0
- data/test/unit/synoption/set_test.rb +37 -0
- data/test/unit/system/command/caching_test.rb +97 -0
- data/test/unit/system/command/line_test.rb +33 -0
- 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
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
|
data/lib/pvn/describe.rb
ADDED
@@ -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
|