pvn 0.0.5 → 0.0.6
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.markdown +3 -2
- data/bin/modify_timestamps.rb +31 -0
- data/bin/populate.rb +231 -0
- data/bin/quote.rb +206 -0
- data/lib/pvn/app.rb +4 -1
- data/lib/pvn/io/element.rb +9 -0
- data/lib/pvn/subcommands/base/command.rb +15 -15
- data/lib/pvn/subcommands/base/options.rb +4 -0
- data/lib/pvn/subcommands/diff/command.rb +46 -0
- data/lib/pvn/subcommands/diff/differ.rb +65 -0
- data/lib/pvn/subcommands/diff/local_differ.rb +103 -0
- data/lib/pvn/subcommands/diff/options.rb +28 -0
- data/lib/pvn/subcommands/diff/repository_differ.rb +145 -0
- data/lib/pvn/subcommands/log/command.rb +29 -11
- data/lib/pvn/subcommands/log/options.rb +0 -4
- data/lib/pvn/subcommands/pct/command.rb +10 -176
- data/lib/pvn/subcommands/pct/diffcount.rb +4 -2
- data/lib/pvn/subcommands/pct/differ.rb +34 -0
- data/lib/pvn/subcommands/pct/local_differ.rb +103 -0
- data/lib/pvn/subcommands/pct/options.rb +0 -4
- data/lib/pvn/subcommands/pct/repository_differ.rb +78 -0
- data/lib/pvn/subcommands/revision/base_option.rb +48 -0
- data/lib/pvn/subcommands/revision/revision_option.rb +2 -37
- data/lib/pvn/subcommands/status/command.rb +13 -8
- data/lib/pvn/subcommands/status/options.rb +0 -4
- data/lib/svnx/cat/command.rb +2 -0
- data/lib/svnx/info/entry.rb +3 -0
- data/lib/synoption/exception.rb +12 -0
- data/lib/synoption/set.rb +26 -0
- data/test/integration/pvn/subcommands/diff/command_test.rb +153 -0
- data/test/integration/svnx/log/test.rb +1 -1
- data/test/unit/pvn/revision/entry_test.rb +0 -13
- data/test/unit/svnx/info/entries_test.rb +3 -3
- data/test/unit/svnx/info/entry_test.rb +3 -2
- data/test/unit/svnx/status/entries_test.rb +1 -1
- data/test/unit/synoption/set_test.rb +34 -18
- metadata +20 -4
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'pvn/io/element'
|
5
|
+
require 'pvn/subcommands/diff/options'
|
6
|
+
require 'pvn/subcommands/base/command'
|
7
|
+
require 'tempfile'
|
8
|
+
|
9
|
+
$io = $stdout
|
10
|
+
|
11
|
+
module PVN::Subcommands::Diff
|
12
|
+
class Differ
|
13
|
+
include Loggable
|
14
|
+
|
15
|
+
attr_reader :whitespace
|
16
|
+
attr_reader :revision
|
17
|
+
|
18
|
+
def initialize options
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_revision_string rev
|
22
|
+
rev ? "revision #{rev}" : "working copy"
|
23
|
+
end
|
24
|
+
|
25
|
+
def write_to_temp entry, lines
|
26
|
+
Tempfile.open('pvn') do |to|
|
27
|
+
topath = to.path
|
28
|
+
info "topath: #{topath}"
|
29
|
+
to.puts lines
|
30
|
+
to.close
|
31
|
+
cmd = "diff -u"
|
32
|
+
label = " -L '#{entry.path} (revision 0)'"
|
33
|
+
2.times do
|
34
|
+
cmd << label
|
35
|
+
end
|
36
|
+
cmd << " #{frpath}"
|
37
|
+
cmd << " #{entry.path}"
|
38
|
+
IO.popen(cmd) do |io|
|
39
|
+
puts io.readlines
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def run_diff_command entry, fromrev, torev, frompath, topath
|
45
|
+
info "whitespace: #{whitespace}"
|
46
|
+
|
47
|
+
cmd = "diff -u"
|
48
|
+
if whitespace
|
49
|
+
cmd << " -x -b -x -w -x --ignore-eol-style"
|
50
|
+
end
|
51
|
+
|
52
|
+
[ fromrev, torev ].each do |rev|
|
53
|
+
revstr = to_revision_string rev
|
54
|
+
cmd << " -L '#{entry.path}\t(#{revstr})'"
|
55
|
+
end
|
56
|
+
cmd << " #{frompath}"
|
57
|
+
cmd << " #{topath}"
|
58
|
+
$io.puts "Index: #{entry.path}"
|
59
|
+
$io.puts "==================================================================="
|
60
|
+
IO.popen(cmd) do |io|
|
61
|
+
$io.puts io.readlines
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'pvn/io/element'
|
5
|
+
require 'pvn/subcommands/diff/options'
|
6
|
+
require 'tempfile'
|
7
|
+
require 'pvn/subcommands/diff/differ'
|
8
|
+
|
9
|
+
module PVN::Subcommands::Diff
|
10
|
+
class LocalDiffer < Differ
|
11
|
+
def initialize options
|
12
|
+
super
|
13
|
+
|
14
|
+
paths = options.paths
|
15
|
+
paths = %w{ . } if paths.empty?
|
16
|
+
|
17
|
+
info "paths: #{paths}".yellow
|
18
|
+
|
19
|
+
allentries = Array.new
|
20
|
+
|
21
|
+
# we sort only the sub-entries, so the order in which paths were specified is preserved
|
22
|
+
|
23
|
+
@whitespace = options.whitespace
|
24
|
+
|
25
|
+
paths.each do |path|
|
26
|
+
info "path: #{path}".red
|
27
|
+
elmt = PVN::IO::Element.new :local => path
|
28
|
+
entries = elmt.find_files_by_status
|
29
|
+
|
30
|
+
allentries.concat entries.sort_by { |n| n.path }
|
31
|
+
end
|
32
|
+
|
33
|
+
info "allentries: #{allentries}"
|
34
|
+
|
35
|
+
allentries.each do |entry|
|
36
|
+
info "entry: #{entry.inspect}".on_blue
|
37
|
+
case entry.status
|
38
|
+
when 'modified'
|
39
|
+
show_as_modified entry
|
40
|
+
when 'deleted'
|
41
|
+
show_as_deleted entry
|
42
|
+
when 'added'
|
43
|
+
show_as_added entry
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def read_working_copy entry
|
49
|
+
pn = Pathname.new entry.path
|
50
|
+
pn.readlines
|
51
|
+
end
|
52
|
+
|
53
|
+
def show_as_added entry
|
54
|
+
Tempfile.open('pvn') do |from|
|
55
|
+
# from is an empty file
|
56
|
+
from.close
|
57
|
+
|
58
|
+
# I think this is always revision 0
|
59
|
+
run_diff_command entry, 0, 0, from.path, entry.path
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def show_as_deleted entry
|
64
|
+
elmt = PVN::IO::Element.new :local => entry.path
|
65
|
+
|
66
|
+
svninfo = elmt.get_info
|
67
|
+
lines = elmt.cat_remote
|
68
|
+
|
69
|
+
Tempfile.open('pvn') do |from|
|
70
|
+
from.puts lines
|
71
|
+
from.close
|
72
|
+
Tempfile.open('pvn') do |to|
|
73
|
+
# to is an empty file
|
74
|
+
to.close
|
75
|
+
run_diff_command entry, svninfo.revision, nil, from.path, to.path
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def show_as_modified entry
|
81
|
+
# only doing working copy to remote now
|
82
|
+
elmt = PVN::IO::Element.new :local => entry.path
|
83
|
+
|
84
|
+
svninfo = elmt.get_info
|
85
|
+
remotelines = elmt.cat_remote
|
86
|
+
|
87
|
+
fromrev = svninfo.revision
|
88
|
+
torev = nil # AKA working copy
|
89
|
+
|
90
|
+
wclines = read_working_copy entry
|
91
|
+
|
92
|
+
Tempfile.open('pvn') do |from|
|
93
|
+
from.puts remotelines
|
94
|
+
from.close
|
95
|
+
Tempfile.open('pvn') do |to|
|
96
|
+
to.puts wclines
|
97
|
+
to.close
|
98
|
+
run_diff_command entry, fromrev, torev, from.path, to.path
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'synoption/boolean_option'
|
5
|
+
require 'pvn/subcommands/revision/multiple_revisions_option'
|
6
|
+
require 'pvn/subcommands/revision/base_option'
|
7
|
+
require 'pvn/subcommands/base/options'
|
8
|
+
|
9
|
+
module PVN::Subcommands::Diff
|
10
|
+
class WhitespaceOption < PVN::BooleanOption
|
11
|
+
def initialize optargs = Hash.new
|
12
|
+
super :whitespace, '-w', 'ignore all whitespace', false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class ChangeOption < PVN::BaseRevisionOption
|
17
|
+
def initialize optargs = Hash.new
|
18
|
+
super :change, '-c', 'use the given revision against the previous one', nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class OptionSet < PVN::Subcommands::Base::OptionSet
|
23
|
+
has_option :revision, PVN::MultipleRevisionsRegexpOption
|
24
|
+
has_option :change, ChangeOption
|
25
|
+
has_option :whitespace, WhitespaceOption
|
26
|
+
has_option :help, PVN::Subcommands::Base::HelpOption
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'pvn/io/element'
|
5
|
+
require 'pvn/subcommands/diff/options'
|
6
|
+
require 'tempfile'
|
7
|
+
require 'pvn/subcommands/diff/differ'
|
8
|
+
|
9
|
+
module PVN::Subcommands::Diff
|
10
|
+
# this will replace RevisionEntry
|
11
|
+
class Revision
|
12
|
+
include Loggable
|
13
|
+
|
14
|
+
attr_reader :value
|
15
|
+
attr_reader :from
|
16
|
+
attr_reader :to
|
17
|
+
|
18
|
+
def initialize from, to = nil
|
19
|
+
if to
|
20
|
+
@from = from
|
21
|
+
@to = to
|
22
|
+
else
|
23
|
+
@from, @to = from.split(':')
|
24
|
+
end
|
25
|
+
info "@from: #{@from}"
|
26
|
+
info "@to: #{@to}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
str = @from.to_s
|
31
|
+
if @to
|
32
|
+
str << ':' << @to.to_s
|
33
|
+
end
|
34
|
+
str
|
35
|
+
end
|
36
|
+
|
37
|
+
def head?
|
38
|
+
@to == nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class RepositoryDiffer < Differ
|
43
|
+
include Loggable
|
44
|
+
|
45
|
+
attr_reader :whitespace
|
46
|
+
attr_reader :revision
|
47
|
+
|
48
|
+
def initialize options
|
49
|
+
paths = options.paths
|
50
|
+
paths = %w{ . } if paths.empty?
|
51
|
+
|
52
|
+
info "paths: #{paths}"
|
53
|
+
|
54
|
+
allentries = Array.new
|
55
|
+
|
56
|
+
# we sort only the sub-entries, so the order in which paths were specified is preserved
|
57
|
+
|
58
|
+
@whitespace = options.whitespace
|
59
|
+
rev = options.revision
|
60
|
+
change = options.change
|
61
|
+
info "change: #{change}"
|
62
|
+
info "rev: #{rev}"
|
63
|
+
info "rev: #{rev.class}"
|
64
|
+
|
65
|
+
if change
|
66
|
+
@revision = Revision.new(change.to_i - 1, change.to_i)
|
67
|
+
elsif rev.kind_of?(Array)
|
68
|
+
if rev.size == 2
|
69
|
+
# this is some contorting, since -rx:y does not mean comparing the files
|
70
|
+
# in changelist x; it means all the entries from x+1 through y, inclusive.
|
71
|
+
|
72
|
+
### $$$ this doesn't handle dates:
|
73
|
+
@revision = Revision.new(rev[0].to_i + 1, rev[0].to_i)
|
74
|
+
else
|
75
|
+
from, to = rev[0].split(':')
|
76
|
+
@revision = Revision.new(from.to_i + 1, to)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
info "revision: #{@revision}; #{@revision.class}".on_blue
|
81
|
+
|
82
|
+
# maps from pathnames to { :first, :last } revision updated.
|
83
|
+
paths_to_revisions = Hash.new
|
84
|
+
|
85
|
+
paths.each do |path|
|
86
|
+
logentries = get_log_entries path, @revision
|
87
|
+
logentries.each do |logentry|
|
88
|
+
info "logentry: #{logentry}".yellow
|
89
|
+
info "logentry.revision: #{logentry.revision}".yellow
|
90
|
+
info "logentry.paths: #{logentry.paths}".yellow
|
91
|
+
|
92
|
+
# should add the revision to this, so we know which is the first
|
93
|
+
# version to compare against the last:
|
94
|
+
|
95
|
+
logentry.paths.each do |lp|
|
96
|
+
info "lp: #{lp.inspect}".cyan
|
97
|
+
allentries << { :path => lp, :revision => logentry.revision }
|
98
|
+
rec = paths_to_revisions[lp.name]
|
99
|
+
if rec
|
100
|
+
rec[:last] = logentry.revision
|
101
|
+
else
|
102
|
+
rec = { :first => logentry.revision, :action => lp.action }
|
103
|
+
end
|
104
|
+
paths_to_revisions[lp.name] = rec
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
paths_to_revisions.sort.each do |name, revisions|
|
110
|
+
puts "name: #{name}"
|
111
|
+
puts "revisions: #{revisions}"
|
112
|
+
end
|
113
|
+
|
114
|
+
info "allentries: #{allentries}"
|
115
|
+
|
116
|
+
allentries.each do |entry|
|
117
|
+
info "entry: #{entry.inspect}".on_blue
|
118
|
+
next if true
|
119
|
+
case entry.status
|
120
|
+
when 'modified'
|
121
|
+
show_as_modified entry
|
122
|
+
when 'deleted'
|
123
|
+
show_as_deleted entry
|
124
|
+
when 'added'
|
125
|
+
show_as_added entry
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def get_log_entries path, revision
|
131
|
+
cmdargs = Hash.new
|
132
|
+
cmdargs[:path] = path
|
133
|
+
cmdargs[:revision] = revision.to_s
|
134
|
+
cmdargs[:verbose] = true
|
135
|
+
|
136
|
+
# should be conditional on revision:
|
137
|
+
cmdargs[:use_cache] = false
|
138
|
+
|
139
|
+
logargs = SVNx::LogCommandArgs.new cmdargs
|
140
|
+
elmt = PVN::IO::Element.new :local => path
|
141
|
+
log = elmt.log logargs
|
142
|
+
entries = log.entries
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -31,10 +31,33 @@ module PVN::Subcommands::Log
|
|
31
31
|
example "pvn log -r 122 -v", "Prints log entry for revision 122, with the files in that change."
|
32
32
|
example "pvn log -u barney", "Prints log entries only for user 'barney', with the default limit."
|
33
33
|
|
34
|
-
def
|
35
|
-
|
34
|
+
def init options
|
35
|
+
paths = options.paths
|
36
36
|
|
37
|
-
|
37
|
+
paths = %w{ . } if paths.empty?
|
38
|
+
|
39
|
+
info "paths: #{paths}"
|
40
|
+
|
41
|
+
allentries = Array.new
|
42
|
+
|
43
|
+
paths.each do |path|
|
44
|
+
allentries.concat find_entries_for_path path, options
|
45
|
+
end
|
46
|
+
|
47
|
+
# we can show relative revisions for a single path, without filtering by
|
48
|
+
# user, or by limit or revision.
|
49
|
+
|
50
|
+
show_relative = !options.user && paths.size == 1 && !options.revision
|
51
|
+
|
52
|
+
# this should be refined to options.revision.head?
|
53
|
+
from_head = show_relative
|
54
|
+
from_tail = show_relative && !options.limit
|
55
|
+
|
56
|
+
ef = PVN::Log::EntriesFormatter.new options.color, allentries, from_head, from_tail
|
57
|
+
puts ef.format
|
58
|
+
end
|
59
|
+
|
60
|
+
def find_entries_for_path path, options
|
38
61
|
cmdargs = Hash.new
|
39
62
|
cmdargs[:path] = path
|
40
63
|
|
@@ -55,10 +78,6 @@ module PVN::Subcommands::Log
|
|
55
78
|
log = elmt.log logargs
|
56
79
|
entries = log.entries
|
57
80
|
|
58
|
-
# this should be refined to options.revision.head?
|
59
|
-
from_head = !options.revision
|
60
|
-
from_tail = !options.limit && !options.revision
|
61
|
-
|
62
81
|
info { "options: #{options}" }
|
63
82
|
info { "options.user: #{options.user}" }
|
64
83
|
|
@@ -69,10 +88,9 @@ module PVN::Subcommands::Log
|
|
69
88
|
# don't show relative revisions, since we've got a slice out of the list:
|
70
89
|
from_head = nil
|
71
90
|
from_tail = nil
|
72
|
-
end
|
73
|
-
|
74
|
-
|
75
|
-
puts ef.format
|
91
|
+
end
|
92
|
+
|
93
|
+
entries
|
76
94
|
end
|
77
95
|
|
78
96
|
def find_entries_for_user entries, user, limit
|
@@ -1,20 +1,14 @@
|
|
1
1
|
#!/usr/bin/ruby -w
|
2
2
|
# -*- ruby -*-
|
3
3
|
|
4
|
-
require 'pvn/io/element'
|
5
4
|
require 'pvn/subcommands/pct/options'
|
6
5
|
require 'pvn/subcommands/base/command'
|
7
|
-
require '
|
8
|
-
require '
|
9
|
-
require 'svnx/cat/command'
|
10
|
-
require 'pvn/subcommands/pct/diffcount'
|
11
|
-
require 'set'
|
6
|
+
require 'pvn/subcommands/pct/local_differ'
|
7
|
+
require 'pvn/subcommands/pct/repository_differ'
|
12
8
|
|
13
9
|
module PVN::Subcommands::Pct
|
14
10
|
class Command < PVN::Subcommands::Base::Command
|
15
11
|
|
16
|
-
DEFAULT_LIMIT = 15
|
17
|
-
|
18
12
|
subcommands [ "pct" ]
|
19
13
|
description "Compares revisions as a percentage of lines modified."
|
20
14
|
usage "[OPTIONS] FILE..."
|
@@ -33,177 +27,17 @@ module PVN::Subcommands::Pct
|
|
33
27
|
optscls
|
34
28
|
|
35
29
|
example "pvn pct foo.rb", "Prints the changes in foo.rb, working copy against BASE."
|
36
|
-
example "pvn pct -r114:121", "Prints the changes for all files, revision 114 against 121.
|
30
|
+
example "pvn pct -r114:121", "Prints the changes for all files, revision 114 against 121."
|
37
31
|
example "pvn pct -rHEAD", "Prints the changes, working copy against HEAD. (not yet supported)"
|
38
|
-
example "pvn pct -r117", "Prints the changes between revision 117 and the previous revision.
|
39
|
-
example "pvn pct -7", "Prints the changes between relative revision -7 and the previous revision.
|
40
|
-
example "pvn pct -r31 -4", "Prints the changes between revision 31 and relative revision -4.
|
41
|
-
|
42
|
-
class << self
|
43
|
-
# base command aliases new to init, so we're aliasing init to init2
|
44
|
-
alias_method :init2, :init
|
45
|
-
|
46
|
-
def init options
|
47
|
-
if options.revision && !options.revision.empty?
|
48
|
-
CommandRepository.init2 options
|
49
|
-
else
|
50
|
-
CommandLocal.init2 options
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def initialize options = nil
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
class CommandLocal < Command
|
60
|
-
def initialize options
|
61
|
-
# do we support multiple paths?
|
62
|
-
path = options.paths[0] || '.'
|
63
|
-
|
64
|
-
elmt = PVN::IO::Element.new :local => path || '.'
|
65
|
-
modified = elmt.find_modified_files
|
66
|
-
info "modified: #{modified}".blue
|
67
|
-
|
68
|
-
total = PVN::DiffCount.new
|
69
|
-
|
70
|
-
modified = modified.sort_by { |n| n.path }
|
71
|
-
|
72
|
-
modified.each do |entry|
|
73
|
-
catcmd = SVNx::CatCommand.new entry.path
|
74
|
-
info "catcmd: #{catcmd}"
|
75
|
-
|
76
|
-
svn_count = catcmd.execute.size
|
77
|
-
info "svn_count: #{svn_count}"
|
78
|
-
|
79
|
-
local_count = Pathname.new(entry.path).readlines.size
|
80
|
-
info "local_count: #{local_count}"
|
32
|
+
example "pvn pct -r117", "Prints the changes between revision 117 and the previous revision."
|
33
|
+
example "pvn pct -7", "Prints the changes between relative revision -7 and the previous revision."
|
34
|
+
example "pvn pct -r31 -4", "Prints the changes between revision 31 and relative revision -4."
|
81
35
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
|
-
total.print 'total'
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
class CommandRepository < Command
|
92
|
-
### $$$ this belongs in Revision
|
93
|
-
def get_from_to_revisions rev
|
94
|
-
if rev.kind_of? Array
|
95
|
-
if rev.size == 1
|
96
|
-
if md = Regexp.new('(.+):(.+)').match(rev[0])
|
97
|
-
return [ md[1], md[2] ]
|
98
|
-
else
|
99
|
-
return [ (rev[0].to_i - 1).to_s, rev[0] ]
|
100
|
-
end
|
101
|
-
else
|
102
|
-
return [ rev[0], rev[1] ]
|
103
|
-
end
|
36
|
+
def init options
|
37
|
+
if options.revision && !options.revision.empty?
|
38
|
+
RepositoryDiffer.new options
|
104
39
|
else
|
105
|
-
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def get_line_count path, revision
|
110
|
-
cmdargs = SVNx::CatCommandArgs.new :path => path, :revision => revision
|
111
|
-
catcmd = SVNx::CatCommand.new cmdargs
|
112
|
-
catcmd.execute.size
|
113
|
-
end
|
114
|
-
|
115
|
-
def initialize options
|
116
|
-
# what was modified between the revisions?
|
117
|
-
|
118
|
-
path = options.paths[0] || "."
|
119
|
-
info "path: #{path}"
|
120
|
-
|
121
|
-
elmt = PVN::IO::Element.new :local => path || '.'
|
122
|
-
modified = elmt.find_modified_entries options.revision
|
123
|
-
|
124
|
-
modnames = modified.collect { |m| m.name }.sort.uniq
|
125
|
-
|
126
|
-
fromrev, torev = get_from_to_revisions options.revision
|
127
|
-
|
128
|
-
total = PVN::DiffCount.new
|
129
|
-
|
130
|
-
reporoot = elmt.repo_root
|
131
|
-
|
132
|
-
direlmt = PVN::IO::Element.new :local => '.'
|
133
|
-
svninfo = direlmt.get_info
|
134
|
-
|
135
|
-
filter = svninfo.url.dup
|
136
|
-
filter.slice! svninfo.root
|
137
|
-
info "filter: #{filter}"
|
138
|
-
filterre = Regexp.new '^' + filter + '/'
|
139
|
-
|
140
|
-
modnames.each do |mod|
|
141
|
-
fullpath = reporoot + mod
|
142
|
-
elmt = PVN::IO::Element.new :path => fullpath
|
143
|
-
|
144
|
-
next unless elmt.has_revision? fromrev
|
145
|
-
next unless elmt.has_revision? torev
|
146
|
-
next if elmt.get_info.kind == 'dir'
|
147
|
-
|
148
|
-
from_count = get_line_count fullpath, fromrev
|
149
|
-
to_count = get_line_count fullpath, torev
|
150
|
-
|
151
|
-
dc = PVN::DiffCount.new from_count, to_count
|
152
|
-
total << dc
|
153
|
-
mod.slice! filterre
|
154
|
-
dc.print mod
|
155
|
-
end
|
156
|
-
|
157
|
-
total.print 'total'
|
158
|
-
end
|
159
|
-
|
160
|
-
|
161
|
-
end
|
162
|
-
|
163
|
-
end
|
164
|
-
|
165
|
-
__END__
|
166
|
-
|
167
|
-
elmt = PVN::IO::Element.new :local => clargs.path || '.'
|
168
|
-
info "elmt: #{elmt}".red
|
169
|
-
|
170
|
-
stats = { :modified => 0, :added => 0, :deleted => 0 }
|
171
|
-
|
172
|
-
if elmt.directory?
|
173
|
-
info "elmt.directory?: #{elmt.directory?}"
|
174
|
-
|
175
|
-
# $$$ todo: recurse even when local has been removed (this is the
|
176
|
-
# awaited "pvn find").
|
177
|
-
|
178
|
-
changed = Array.new
|
179
|
-
elmt.local.find do |fd|
|
180
|
-
info "fd: #{fd}; #{fd.class}"
|
181
|
-
Find.prune if fd.rootname.to_s == '.svn'
|
182
|
-
if fd.file?
|
183
|
-
subelmt = PVN::IO::Element.new :local => fd.to_s
|
184
|
-
info "subelmt: #{subelmt}"
|
185
|
-
status = subelmt.status
|
186
|
-
info "status: #{status}".red
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
# info "changed: #{changed}"
|
191
|
-
elsif elmt.file?
|
192
|
-
info "elmt.local: #{elmt.local}".cyan
|
193
|
-
|
194
|
-
status = elmt.status
|
195
|
-
info "status: #{status}"
|
196
|
-
|
197
|
-
case status
|
198
|
-
when "added"
|
199
|
-
info "elmt: #{elmt}".green
|
200
|
-
when "modified"
|
201
|
-
info "elmt: #{elmt}".yellow
|
202
|
-
when "deleted"
|
203
|
-
info "elmt: #{elmt}".red
|
204
|
-
else
|
205
|
-
info "elmt: #{elmt}".cyan
|
206
|
-
end
|
40
|
+
LocalDiffer.new options
|
207
41
|
end
|
208
42
|
end
|
209
43
|
end
|
@@ -5,13 +5,15 @@ module PVN
|
|
5
5
|
class DiffCount
|
6
6
|
attr_reader :from
|
7
7
|
attr_reader :to
|
8
|
+
attr_reader :name
|
8
9
|
|
9
|
-
def initialize from = 0, to = 0
|
10
|
+
def initialize from = 0, to = 0, name = nil
|
10
11
|
@from = from
|
11
12
|
@to = to
|
13
|
+
@name = name
|
12
14
|
end
|
13
15
|
|
14
|
-
def print name
|
16
|
+
def print name = @name
|
15
17
|
diff = to - from
|
16
18
|
diffpct = diff == 0 ? 0 : 100.0 * diff / from
|
17
19
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
# -*- ruby -*-
|
3
|
+
|
4
|
+
require 'pvn/subcommands/pct/diffcount'
|
5
|
+
|
6
|
+
module PVN::Subcommands::Pct
|
7
|
+
class Differ
|
8
|
+
include Loggable
|
9
|
+
|
10
|
+
def initialize options
|
11
|
+
show_diff_counts options
|
12
|
+
end
|
13
|
+
|
14
|
+
def show_diff_counts options
|
15
|
+
paths = options.paths
|
16
|
+
paths = %w{ . } if paths.empty?
|
17
|
+
|
18
|
+
info "paths: #{paths}"
|
19
|
+
|
20
|
+
total = PVN::DiffCount.new 0, 0, 'total'
|
21
|
+
|
22
|
+
paths.each do |path|
|
23
|
+
diff_counts = get_diff_counts path, options
|
24
|
+
|
25
|
+
diff_counts.each do |dc|
|
26
|
+
total << dc
|
27
|
+
dc.print
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
total.print
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|