pvn 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +5 -1
- data/lib/pvn/app.rb +3 -0
- data/lib/pvn/{log/formatter → base}/color_formatter.rb +0 -0
- data/lib/pvn/io/element.rb +36 -29
- data/lib/pvn/log/formatter/log_formatter.rb +1 -10
- data/lib/pvn/log/formatter/summary_formatter.rb +0 -2
- data/lib/pvn/log/logcmd.rb +0 -1
- data/lib/pvn/revision/entry.rb +7 -2
- data/lib/pvn/status/formatter/entries_formatter.rb +27 -0
- data/lib/pvn/status/formatter/entry_formatter.rb +27 -0
- data/lib/pvn/status/formatter/status_formatter.rb +31 -0
- data/lib/pvn/subcommands/base/color_option.rb +12 -0
- data/lib/pvn/subcommands/base/command.rb +21 -2
- data/lib/pvn/subcommands/base/options.rb +1 -0
- data/lib/pvn/subcommands/log/command.rb +26 -30
- data/lib/pvn/subcommands/log/options.rb +2 -7
- data/lib/pvn/subcommands/pct/command.rb +71 -91
- data/lib/pvn/subcommands/pct/diffcount.rb +26 -0
- data/lib/pvn/subcommands/revision/revision_option.rb +7 -5
- data/lib/pvn/subcommands/status/command.rb +42 -0
- data/lib/pvn/subcommands/status/options.rb +16 -0
- data/lib/svnx/info/command.rb +14 -0
- data/lib/svnx/log/entry.rb +4 -0
- data/lib/synoption/fixnum_option.rb +1 -1
- data/test/{unit → integration}/pvn/subcommands/log/command_test.rb +0 -0
- data/test/unit/pvn/io/element/log/log_test.rb +3 -2
- data/test/unit/pvn/log/formatter/entry_formatter_test.rb +1 -1
- data/test/unit/pvn/revision/entry_test.rb +10 -10
- data/test/unit/pvn/subcommands/log/options_test.rb +12 -31
- data/test/unit/pvn/subcommands/revision/multiple_revisions_option_test.rb +14 -21
- data/test/unit/pvn/subcommands/revision/revision_option_test.rb +20 -13
- data/test/unit/pvn/subcommands/revision/revision_regexp_option_test.rb +17 -15
- metadata +15 -11
- data/lib/pvn/pct/linecount.rb +0 -33
- data/lib/pvn/pct/pctcmd.rb +0 -204
- data/lib/pvn/pct/statcmd.rb +0 -13
data/README.markdown
CHANGED
@@ -15,7 +15,7 @@ SUMMARY
|
|
15
15
|
FEATURES
|
16
16
|
--------
|
17
17
|
|
18
|
-
**Relative revisions
|
18
|
+
**Relative revisions**. Pvn supports revisions being specified as being relative
|
19
19
|
to their "index" in the list of svn revision. "+n" means the nth revision in
|
20
20
|
the list for a given path, and "-n" is the nth from the last revision, where
|
21
21
|
-1 means the last revision.
|
@@ -36,3 +36,7 @@ except that output is colorized, differing for the elements (file, directory) an
|
|
36
36
|
the status of the element (added, deleted, changed). The logging output also
|
37
37
|
shows the relative revision.
|
38
38
|
|
39
|
+
**Sorted names**. Pvn differs from Subversion in that for all subcommands, file names
|
40
|
+
are printed in sorted order, improving legibility.
|
41
|
+
|
42
|
+
|
data/lib/pvn/app.rb
CHANGED
@@ -10,6 +10,7 @@ require 'svnx/log/entries'
|
|
10
10
|
|
11
11
|
require 'pvn/subcommands/log/command'
|
12
12
|
require 'pvn/subcommands/pct/command'
|
13
|
+
require 'pvn/subcommands/status/command'
|
13
14
|
|
14
15
|
# the old ones:
|
15
16
|
require 'pvn/diff/diffcmd'
|
@@ -45,6 +46,8 @@ module PVN::App
|
|
45
46
|
run_command PVN::Subcommands::Log::Command, args
|
46
47
|
when "pct"
|
47
48
|
run_command PVN::Subcommands::Pct::Command, args
|
49
|
+
when "status"
|
50
|
+
run_command PVN::Subcommands::Status::Command, args
|
48
51
|
else
|
49
52
|
$stderr.puts "ERROR: subcommand not valid: #{arg}"
|
50
53
|
exit(-1)
|
File without changes
|
data/lib/pvn/io/element.rb
CHANGED
@@ -36,7 +36,8 @@ module PVN::IO
|
|
36
36
|
# $$$ todo: map svnurl to SVNElement, and fname to FSElement
|
37
37
|
|
38
38
|
@svn = args[:svn] || (args[:file] && SVNElement.new(:filename => args[:file]))
|
39
|
-
@local = PVN::FSElement.new
|
39
|
+
@local = args[:local] && PVN::FSElement.new(args[:local] || args[:file])
|
40
|
+
@path = args[:path]
|
40
41
|
|
41
42
|
info "local: #{@local}"
|
42
43
|
end
|
@@ -62,8 +63,9 @@ module PVN::IO
|
|
62
63
|
end
|
63
64
|
end
|
64
65
|
|
65
|
-
def get_info
|
66
|
-
|
66
|
+
def get_info revision = nil
|
67
|
+
usepath = @local || @path
|
68
|
+
cmdargs = SVNx::InfoCommandArgs.new :path => usepath, :revision => revision
|
67
69
|
infcmd = SVNx::InfoCommand.new cmdargs
|
68
70
|
output = infcmd.execute
|
69
71
|
|
@@ -75,13 +77,27 @@ module PVN::IO
|
|
75
77
|
get_info.root
|
76
78
|
end
|
77
79
|
|
80
|
+
def has_revision? rev
|
81
|
+
# was there a revision then?
|
82
|
+
begin
|
83
|
+
svninfo = get_info rev
|
84
|
+
true
|
85
|
+
rescue => e
|
86
|
+
# skip it
|
87
|
+
false
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
78
91
|
# returns a set of entries modified over the given revision
|
79
92
|
def find_modified_entries revision
|
80
93
|
cmdargs = Hash.new
|
81
94
|
|
82
|
-
|
95
|
+
svninfo = get_info
|
83
96
|
|
84
|
-
|
97
|
+
filter = svninfo.url.dup
|
98
|
+
filter.slice! svninfo.root
|
99
|
+
|
100
|
+
cmdargs[:path] = @local
|
85
101
|
|
86
102
|
# we can't cache this, because we don't know if there has been an svn
|
87
103
|
# update since the previous run:
|
@@ -95,12 +111,11 @@ module PVN::IO
|
|
95
111
|
|
96
112
|
modified = Set.new
|
97
113
|
|
98
|
-
info "entries: #{entries}"
|
99
114
|
entries.each do |entry|
|
100
|
-
info "entry: #{entry}".on_blue
|
101
|
-
info entry.paths
|
102
115
|
entry.paths.each do |epath|
|
103
|
-
|
116
|
+
if epath.action == 'M' && epath.name.start_with?(filter)
|
117
|
+
modified << epath
|
118
|
+
end
|
104
119
|
end
|
105
120
|
end
|
106
121
|
|
@@ -108,15 +123,22 @@ module PVN::IO
|
|
108
123
|
end
|
109
124
|
|
110
125
|
# returns a set of local files that are in the given status
|
111
|
-
def
|
112
|
-
|
126
|
+
def find_files
|
127
|
+
end
|
113
128
|
|
129
|
+
# returns a set of local files that are in the given status
|
130
|
+
def find_files_by_status status = nil
|
131
|
+
cmdargs = SVNx::StatusCommandArgs.new :path => @local, :use_cache => false
|
114
132
|
cmd = SVNx::StatusCommand.new cmdargs
|
115
133
|
xml = cmd.execute
|
116
134
|
entries = SVNx::Status::Entries.new :xmllines => xml
|
117
|
-
|
118
|
-
|
119
|
-
|
135
|
+
|
136
|
+
if status
|
137
|
+
entries.select do |entry|
|
138
|
+
entry.status == status
|
139
|
+
end
|
140
|
+
else
|
141
|
+
entries
|
120
142
|
end
|
121
143
|
end
|
122
144
|
|
@@ -143,21 +165,6 @@ module PVN::IO
|
|
143
165
|
entry.status
|
144
166
|
end
|
145
167
|
|
146
|
-
# def to_command subcmd, revcl, *args
|
147
|
-
# cmd = "svn #{subcmd}"
|
148
|
-
# info "cmd: #{cmd}".on_blue
|
149
|
-
# info "args: #{args}".on_blue
|
150
|
-
# args = args.flatten
|
151
|
-
|
152
|
-
# # revcl is [ -r, 3484 ]
|
153
|
-
# if revcl
|
154
|
-
# cmd << " " << revcl.join(" ")
|
155
|
-
# end
|
156
|
-
# cmd << " " << Util::quote_list(args)
|
157
|
-
# info "cmd: #{cmd}".on_blue
|
158
|
-
# cmd
|
159
|
-
# end
|
160
|
-
|
161
168
|
# def line_counts
|
162
169
|
# [ @svnelement && @svnelement.line_count, @fselement && @fselement.line_count ]
|
163
170
|
# end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# -*- ruby -*-
|
3
3
|
|
4
4
|
require 'svnx/log/entry'
|
5
|
-
require 'pvn/
|
5
|
+
require 'pvn/base/color_formatter'
|
6
6
|
|
7
7
|
module PVN; module Log; end; end
|
8
8
|
|
@@ -39,15 +39,6 @@ module PVN::Log
|
|
39
39
|
# should also turn this off if not on a terminal that supports colors ...
|
40
40
|
end
|
41
41
|
|
42
|
-
def write_entries entries, out = $stdout
|
43
|
-
entries.each_with_index do |entry, idx|
|
44
|
-
fmtlines = format entry, idx, entries.size
|
45
|
-
|
46
|
-
out.puts fmtlines
|
47
|
-
out.puts '-' * 55
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
42
|
def width field
|
52
43
|
WIDTHS[field]
|
53
44
|
end
|
data/lib/pvn/log/logcmd.rb
CHANGED
data/lib/pvn/revision/entry.rb
CHANGED
@@ -7,6 +7,9 @@ require 'svnx/log/entries'
|
|
7
7
|
# replace lib/pvn/revision.rb as PVN::Revision.
|
8
8
|
|
9
9
|
module PVN::Revision
|
10
|
+
class RevisionError < RuntimeError
|
11
|
+
end
|
12
|
+
|
10
13
|
DATE_REGEXP = Regexp.new '^\{(.*?)\}'
|
11
14
|
SVN_REVISION_WORDS = %w{ HEAD BASE COMMITTED PREV }
|
12
15
|
RELATIVE_REVISION_RE = Regexp.new '^([\+\-])(\d+)$'
|
@@ -77,7 +80,9 @@ module PVN::Revision
|
|
77
80
|
|
78
81
|
class RelativeEntry < FixnumEntry
|
79
82
|
def initialize value, xmllines
|
80
|
-
|
83
|
+
unless xmllines
|
84
|
+
raise RevisionError.new "cannot determine relative revision without xmllines"
|
85
|
+
end
|
81
86
|
|
82
87
|
logentries = SVNx::Log::Entries.new :xmllines => xmllines
|
83
88
|
|
@@ -86,7 +91,7 @@ module PVN::Revision
|
|
86
91
|
# logentries are in descending order, so the most recent one is index 0
|
87
92
|
|
88
93
|
if value.abs > nentries
|
89
|
-
raise "ERROR: no entry for revision: #{value.abs}; number of entries: #{nentries}"
|
94
|
+
raise RevisionError.new "ERROR: no entry for revision: #{value.abs}; number of entries: #{nentries}"
|
90
95
|
else
|
91
96
|
idx = value < 0 ? -1 + value.abs : nentries - value
|
92
97
|
@log_entry = logentries[idx]
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'pvn/status/formatter/status_formatter'
|
5
|
+
require 'pvn/status/formatter/entry_formatter'
|
6
|
+
|
7
|
+
module PVN; module Status; end; end
|
8
|
+
|
9
|
+
module PVN::Status
|
10
|
+
class EntriesFormatter < Formatter
|
11
|
+
def initialize use_color, entries
|
12
|
+
super use_color
|
13
|
+
@entries = entries
|
14
|
+
end
|
15
|
+
|
16
|
+
def format
|
17
|
+
lines = Array.new
|
18
|
+
total = @entries.size
|
19
|
+
@entries.each_with_index do |entry, idx|
|
20
|
+
ef = EntryFormatter.new use_colors, entry
|
21
|
+
lines.concat ef.format
|
22
|
+
# lines << '-' * 55
|
23
|
+
end
|
24
|
+
lines
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'pvn/status/formatter/status_formatter'
|
5
|
+
|
6
|
+
module PVN; module Status; end; end
|
7
|
+
|
8
|
+
module PVN::Status
|
9
|
+
class EntryFormatter < Formatter
|
10
|
+
attr_reader :entry
|
11
|
+
|
12
|
+
def initialize use_colors, entry
|
13
|
+
super use_colors
|
14
|
+
@entry = entry
|
15
|
+
end
|
16
|
+
|
17
|
+
def format
|
18
|
+
lines = Array.new
|
19
|
+
lines << if use_colors
|
20
|
+
" " + colorize(entry.path, entry.status.to_sym)
|
21
|
+
else
|
22
|
+
"#{entry.status[0 .. 0].upcase} #{entry.path}"
|
23
|
+
end
|
24
|
+
lines
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'svnx/status/entry'
|
5
|
+
require 'pvn/base/color_formatter'
|
6
|
+
|
7
|
+
module PVN; module Status; end; end
|
8
|
+
|
9
|
+
module PVN::Status
|
10
|
+
# a format for status entries
|
11
|
+
class Formatter < PVN::ColorFormatter
|
12
|
+
|
13
|
+
COLORS = {
|
14
|
+
:added => [ :green ],
|
15
|
+
:modified => [ :yellow ],
|
16
|
+
:deleted => [ :red ],
|
17
|
+
:renamed => [ :magenta ],
|
18
|
+
}
|
19
|
+
|
20
|
+
attr_reader :use_colors
|
21
|
+
|
22
|
+
def initialize use_colors
|
23
|
+
# should also turn this off if not on a terminal that supports colors ...
|
24
|
+
@use_colors = use_colors
|
25
|
+
end
|
26
|
+
|
27
|
+
def colors field
|
28
|
+
use_colors ? COLORS[field] : nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'synoption/boolean_option'
|
5
|
+
|
6
|
+
module PVN::Subcommands::Base
|
7
|
+
class ColorOption < PVN::BooleanOption
|
8
|
+
def initialize optargs = Hash.new
|
9
|
+
super :color, '-f', "show colorized output", true, :negate => [ '-C', %r{^--no-?color} ], :as_cmdline_option => nil
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -32,20 +32,39 @@ module PVN::Subcommands::Base
|
|
32
32
|
getdoc.summary = smry
|
33
33
|
end
|
34
34
|
|
35
|
+
### $$$ remove this:
|
35
36
|
def options opts
|
36
37
|
getdoc.options.concat opts
|
37
38
|
end
|
38
39
|
|
39
40
|
def optscls
|
40
|
-
|
41
|
+
getdoc.options.concat optset.options
|
42
|
+
end
|
43
|
+
|
44
|
+
def optset
|
45
|
+
optmodule = to_s.sub %r{::\w+$}, ''
|
41
46
|
optcls = optmodule + '::OptionSet'
|
42
47
|
optset = instance_eval optcls + '.new'
|
43
|
-
getdoc.options.concat optset.options
|
44
48
|
end
|
45
49
|
|
46
50
|
def example *ex
|
47
51
|
getdoc.examples << ex
|
48
52
|
end
|
53
|
+
|
54
|
+
alias_method :init, :new
|
55
|
+
alias_method :new_for_help, :new
|
56
|
+
|
57
|
+
def new args
|
58
|
+
options = optset
|
59
|
+
options.process args
|
60
|
+
|
61
|
+
if options.help
|
62
|
+
cmd = new_for_help nil
|
63
|
+
cmd.show_help
|
64
|
+
else
|
65
|
+
init options
|
66
|
+
end
|
67
|
+
end
|
49
68
|
end
|
50
69
|
|
51
70
|
def to_doc io
|
@@ -3,7 +3,6 @@
|
|
3
3
|
|
4
4
|
require 'pvn/io/element'
|
5
5
|
require 'pvn/log/formatter/entries_formatter'
|
6
|
-
require 'pvn/subcommands/base/doc'
|
7
6
|
require 'pvn/subcommands/log/options'
|
8
7
|
require 'pvn/subcommands/base/command'
|
9
8
|
|
@@ -24,22 +23,19 @@ module PVN::Subcommands::Log
|
|
24
23
|
|
25
24
|
optscls
|
26
25
|
|
27
|
-
example "pvn log foo.rb",
|
28
|
-
example "pvn log -l 25 foo.rb",
|
29
|
-
example "pvn log -3 foo.rb",
|
30
|
-
example "pvn log +3 foo.rb",
|
31
|
-
example "pvn log -l 10 -
|
32
|
-
example "pvn log -r 122 -v",
|
33
|
-
example "pvn log -u barney",
|
26
|
+
example "pvn log foo.rb", "Prints the latest #{DEFAULT_LIMIT} log entries for foo.rb."
|
27
|
+
example "pvn log -l 25 foo.rb", "Prints 25 log entries for the file."
|
28
|
+
example "pvn log -3 foo.rb", "Prints the log entry for revision (HEAD - 3)."
|
29
|
+
example "pvn log +3 foo.rb", "Prints the 3rd log entry."
|
30
|
+
example "pvn log -l 10 --no-color", "Prints the latest 10 entries, uncolorized."
|
31
|
+
example "pvn log -r 122 -v", "Prints log entry for revision 122, with the files in that change."
|
32
|
+
example "pvn log -u barney", "Prints log entries only for user 'barney', with the default limit."
|
34
33
|
|
35
|
-
def initialize
|
36
|
-
|
37
|
-
options.process args
|
34
|
+
def initialize options = nil
|
35
|
+
return unless options
|
38
36
|
|
39
|
-
|
40
|
-
|
41
|
-
path = options.paths[0] || "."
|
42
|
-
cmdargs = Hash.new
|
37
|
+
path = options.paths[0] || "."
|
38
|
+
cmdargs = Hash.new
|
43
39
|
cmdargs[:path] = path
|
44
40
|
|
45
41
|
[ :limit, :verbose, :revision ].each do |field|
|
@@ -63,30 +59,30 @@ module PVN::Subcommands::Log
|
|
63
59
|
from_head = !options.revision
|
64
60
|
from_tail = !options.limit && !options.revision
|
65
61
|
|
66
|
-
info "options: #{options}"
|
67
|
-
info "options.user: #{options.user}"
|
62
|
+
info { "options: #{options}" }
|
63
|
+
info { "options.user: #{options.user}" }
|
68
64
|
|
69
65
|
if options.user
|
70
|
-
|
71
|
-
|
72
|
-
entries = entries.select { |entry| entry.author == options.user }
|
73
|
-
|
74
|
-
raise "ERROR: no matching log entries for '#{options.user}'"
|
75
|
-
|
76
|
-
info "entries: #{entries}".red
|
66
|
+
entries = find_entries_for_user entries, options.user, options.limit
|
67
|
+
info { "entries: #{entries}" }
|
77
68
|
|
78
69
|
# don't show relative revisions, since we've got a slice out of the list:
|
79
70
|
from_head = nil
|
80
71
|
from_tail = nil
|
81
|
-
|
82
|
-
if options.limit
|
83
|
-
entries = entries[0 ... options.limit]
|
84
|
-
info "entries: #{entries}".red
|
85
|
-
end
|
86
72
|
end
|
87
73
|
|
88
|
-
ef = PVN::Log::EntriesFormatter.new options.
|
74
|
+
ef = PVN::Log::EntriesFormatter.new options.color, entries, from_head, from_tail
|
89
75
|
puts ef.format
|
90
76
|
end
|
77
|
+
|
78
|
+
def find_entries_for_user entries, user, limit
|
79
|
+
entries = entries.select { |entry| entry.author == user }
|
80
|
+
|
81
|
+
raise "ERROR: no matching log entries for '#{user}'" if entries.empty?
|
82
|
+
|
83
|
+
info { "entries: #{entries}" }
|
84
|
+
|
85
|
+
limit ? entries[0 ... limit] : entries
|
86
|
+
end
|
91
87
|
end
|
92
88
|
end
|
@@ -7,6 +7,7 @@ require 'synoption/fixnum_option'
|
|
7
7
|
require 'synoption/boolean_option'
|
8
8
|
require 'pvn/subcommands/revision/multiple_revisions_option'
|
9
9
|
require 'pvn/subcommands/base/options'
|
10
|
+
require 'pvn/subcommands/base/color_option'
|
10
11
|
|
11
12
|
module PVN::Subcommands::Log
|
12
13
|
DEFAULT_LIMIT = 5
|
@@ -23,12 +24,6 @@ module PVN::Subcommands::Log
|
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
26
|
-
class FormatOption < PVN::BooleanOption
|
27
|
-
def initialize optargs = Hash.new
|
28
|
-
super :format, '-f', "use the custom (colorized) format", true, :negate => [ '-F', %r{^--no-?format} ], :as_cmdline_option => nil
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
27
|
class UserOption < PVN::Option
|
33
28
|
def initialize optargs = Hash.new
|
34
29
|
super :user, '-u', "show only changes for the given user", nil, :as_cmdline_option => nil
|
@@ -37,7 +32,7 @@ module PVN::Subcommands::Log
|
|
37
32
|
|
38
33
|
class OptionSet < PVN::Subcommands::Base::OptionSet
|
39
34
|
has_option :revision, PVN::MultipleRevisionsRegexpOption, [ :unsets => :limit ]
|
40
|
-
has_option :
|
35
|
+
has_option :color, PVN::Subcommands::Base::ColorOption
|
41
36
|
has_option :help, PVN::Subcommands::Base::HelpOption
|
42
37
|
has_option :limit, LimitOption
|
43
38
|
has_option :user, UserOption
|