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
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'rubygems'
5
+ require 'riel'
6
+ require 'pvn/base/util'
7
+
8
+ require 'svnx/log/command'
9
+ require 'svnx/log/entries'
10
+
11
+ require 'svnx/status/command'
12
+ require 'svnx/status/entries'
13
+
14
+ require 'svnx/info/command'
15
+ require 'svnx/info/entries'
16
+
17
+ require 'pvn/io/fselement'
18
+
19
+ module PVN; module IO; end; end
20
+
21
+ module PVN::IO
22
+ # An element unites an svn element and a file/directory (at least one of
23
+ # which should exist).
24
+
25
+ class Element
26
+ include Loggable
27
+
28
+ attr_reader :svn
29
+ attr_reader :local
30
+
31
+ def initialize args = Hash.new
32
+ info "args: #{args}"
33
+
34
+ svnurl = args[:svnurl]
35
+ fname = args[:filename] || args[:file] # legacy
36
+ # $$$ todo: map svnurl to SVNElement, and fname to FSElement
37
+
38
+ @svn = args[:svn] || (args[:file] && SVNElement.new(:filename => args[:file]))
39
+ @local = PVN::FSElement.new args[:local] || args[:file]
40
+
41
+ info "local: #{@local}"
42
+ end
43
+
44
+ def exist?
45
+ @local && @local.exist?
46
+ end
47
+
48
+ def directory?
49
+ if exist?
50
+ @local.directory?
51
+ else
52
+ # look it up with svn info
53
+ false
54
+ end
55
+ end
56
+
57
+ def file?
58
+ if exist?
59
+ @local.file?
60
+ else
61
+ raise "need this"
62
+ end
63
+ end
64
+
65
+ def svninfo
66
+ end
67
+
68
+ # returns log entries
69
+ def log cmdargs = SVNx::LogCommandArgs.new
70
+ # $$$ todo: this should be either @local if set, otherwise @svn (url)
71
+ # cmdargs.path = @local
72
+ cmd = SVNx::LogCommand.new cmdargs
73
+ SVNx::Log::Entries.new :xmllines => cmd.execute
74
+ end
75
+
76
+ # returns :added, :deleted, "modified"
77
+ def status
78
+ cmdargs = SVNx::StatusCommandArgs.new :path => @local
79
+ cmd = SVNx::StatusCommand.new :cmdargs => cmdargs
80
+ xml = cmd.execute.join ''
81
+ entries = SVNx::Status::Entries.new :xml => SVNx::Status::XMLEntries.new(xml)
82
+ entry = entries[0]
83
+ entry.status
84
+ end
85
+
86
+ # def to_command subcmd, revcl, *args
87
+ # cmd = "svn #{subcmd}"
88
+ # info "cmd: #{cmd}".on_blue
89
+ # info "args: #{args}".on_blue
90
+ # args = args.flatten
91
+
92
+ # # revcl is [ -r, 3484 ]
93
+ # if revcl
94
+ # cmd << " " << revcl.join(" ")
95
+ # end
96
+ # cmd << " " << Util::quote_list(args)
97
+ # info "cmd: #{cmd}".on_blue
98
+ # cmd
99
+ # end
100
+
101
+ # def line_counts
102
+ # [ @svnelement && @svnelement.line_count, @fselement && @fselement.line_count ]
103
+ # end
104
+
105
+ def <=> other
106
+ @svn <=> other.svn
107
+ end
108
+
109
+ def to_s
110
+ "svn => " + @svn.to_s + "; local => " + @local.to_s
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'rubygems'
5
+ require 'riel'
6
+
7
+ module PVN
8
+ # A filesystem element (directory or file).
9
+ class FSElement < Pathname
10
+ include Loggable
11
+ attr_reader :name
12
+
13
+ def initialize name
14
+ @name = name
15
+ super
16
+ end
17
+
18
+ def line_count
19
+ readlines.size
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'rubygems'
5
+ require 'riel/log'
6
+
7
+ module PVN
8
+ class ColorFormatter
9
+ include Loggable
10
+
11
+ def pad what, field
12
+ nspaces = [ width(field) - what.length, 1 ].max
13
+ " " * nspaces
14
+ end
15
+
16
+ def colorize what, field
17
+ colors = colors field
18
+ return what if colors.nil? || colors.empty?
19
+ colors.each do |col|
20
+ what = what.send col
21
+ end
22
+ what
23
+ end
24
+
25
+ def add_field value, field
26
+ colorize(value, field) + pad(value, field)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'pvn/log/formatter/log_formatter'
5
+ require 'pvn/log/formatter/entry_formatter'
6
+
7
+ module PVN; module Log; end; end
8
+
9
+ module PVN::Log
10
+ class EntriesFormatter < Formatter
11
+ attr_reader :from_head
12
+ attr_reader :from_tail
13
+
14
+ def initialize use_color, entries, from_head, from_tail
15
+ super use_color
16
+ @entries = entries
17
+ @from_head = from_head
18
+ @from_tail = from_tail
19
+ end
20
+
21
+ def format
22
+ lines = Array.new
23
+ total = @entries.size
24
+ @entries.each_with_index do |entry, idx|
25
+ ef = EntryFormatter.new use_colors, entry, idx, from_head, from_tail, total
26
+ lines.concat ef.format
27
+
28
+ lines << '-' * 55
29
+ end
30
+ lines
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'pvn/log/formatter/log_formatter'
5
+ require 'pvn/log/formatter/summary_formatter'
6
+ require 'pvn/log/formatter/message_formatter'
7
+ require 'pvn/log/formatter/path_formatter'
8
+
9
+ module PVN; module Log; end; end
10
+
11
+ module PVN::Log
12
+ class EntryFormatter < Formatter
13
+ attr_reader :entry
14
+ attr_reader :idx
15
+ attr_reader :from_head
16
+ attr_reader :from_tail
17
+ attr_reader :total
18
+
19
+ def initialize use_colors, entry, idx, from_head, from_tail, total
20
+ super use_colors
21
+ @entry = entry
22
+ @idx = idx
23
+ @from_head = from_head
24
+ @from_tail = from_tail
25
+ @total = total
26
+ end
27
+
28
+ def format
29
+ if false
30
+ info "@entry.revision: #{@entry.revision}"
31
+ info "@entry.author : #{@entry.author}"
32
+ info "@entry.date : #{@entry.date}"
33
+ info "@entry.message : #{@entry.message}"
34
+ @entry.paths.each do |path|
35
+ info " path.kind : #{path.kind}"
36
+ info " path.action: #{path.action}"
37
+ info " path.name : #{path.name}"
38
+ end
39
+ end
40
+
41
+ lines = Array.new
42
+
43
+ sf = SummaryFormatter.new use_colors, entry, idx, from_head, from_tail, total
44
+ lines << sf.format
45
+ lines << ""
46
+
47
+ mf = MessageFormatter.new use_colors, entry.message
48
+ lines << mf.format
49
+ lines << ""
50
+
51
+ pf = PathFormatter.new use_colors, entry.paths
52
+ lines.concat pf.format
53
+
54
+ lines
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'svnx/log/entry'
5
+ require 'pvn/log/formatter/color_formatter'
6
+
7
+ module PVN; module Log; end; end
8
+
9
+ module PVN::Log
10
+ # a format for log entries
11
+ class Formatter < PVN::ColorFormatter
12
+
13
+ WIDTHS = {
14
+ :revision => 10,
15
+ :neg_revision => 5,
16
+ :pos_revision => 5,
17
+ :author => 25
18
+ }
19
+
20
+ COLORS = {
21
+ :revision => [ :bold ],
22
+ :neg_revision => [ :bold ],
23
+ :pos_revision => [ :bold ],
24
+ :author => [ :bold, :cyan ],
25
+ :date => [ :bold, :magenta ],
26
+
27
+ :added => [ :green ],
28
+ :modified => [ :yellow ],
29
+ :deleted => [ :red ],
30
+ :renamed => [ :magenta ],
31
+
32
+ :dir => [ :bold ],
33
+ }
34
+
35
+ attr_reader :use_colors
36
+
37
+ def initialize use_colors
38
+ @use_colors = use_colors
39
+ # should also turn this off if not on a terminal that supports colors ...
40
+ end
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
+ def width field
52
+ WIDTHS[field]
53
+ end
54
+
55
+ def colors field
56
+ use_colors ? COLORS[field] : nil
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'pvn/log/formatter/log_formatter'
5
+
6
+ module PVN; module Log; end; end
7
+
8
+ module PVN::Log
9
+ class MessageFormatter < Formatter
10
+ def initialize use_colors, msg
11
+ super use_colors
12
+ @msg = msg
13
+ end
14
+
15
+ def format
16
+ use_colors ? @msg.white : @msg
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'pvn/log/formatter/log_formatter'
5
+
6
+ module PVN; module Log; end; end
7
+
8
+ module PVN::Log
9
+ class PathFormatter < Formatter
10
+ PATH_ACTIONS = {
11
+ 'M' => :modified,
12
+ 'A' => :added,
13
+ 'D' => :deleted,
14
+ 'R' => :renamed
15
+ }
16
+
17
+ def initialize use_colors, paths
18
+ super use_colors
19
+ @paths = paths
20
+ end
21
+
22
+ def format
23
+ lines = Array.new
24
+ @paths.sort_by { |path| path.name }.each do |path|
25
+ pstr = " "
26
+ if field = PATH_ACTIONS[path.action]
27
+ pstr << colorize(path.name, field)
28
+ else
29
+ raise "wtf?: #{path.action}"
30
+ end
31
+
32
+ if path.kind == 'dir'
33
+ pstr = colorize(pstr, :dir)
34
+ end
35
+
36
+ lines << pstr
37
+ end
38
+ lines
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'pvn/log/formatter/log_formatter'
5
+
6
+ module PVN; module Log; end; end
7
+
8
+ module PVN::Log
9
+ class SummaryFormatter < Formatter
10
+ attr_reader :entry
11
+ attr_reader :idx
12
+ attr_reader :from_head
13
+ attr_reader :from_tail
14
+ attr_reader :total
15
+
16
+ def initialize use_colors, entry, idx, from_head, from_tail, total
17
+ super use_colors
18
+ @entry = entry
19
+ @idx = idx
20
+ @from_head = from_head
21
+ @from_tail = from_tail
22
+ @total = total
23
+ end
24
+
25
+ def format
26
+ lines = add_field(entry.revision, :revision)
27
+ negidx = (-1 - idx).to_s
28
+
29
+ if from_head
30
+ lines << add_field(negidx, :neg_revision)
31
+ else
32
+ lines << pad("", :neg_revision)
33
+ end
34
+
35
+ # info "@total: #{total}"
36
+
37
+ if from_tail
38
+ posidx = "+#{total - idx - 1}"
39
+ lines << add_field(posidx, :pos_revision)
40
+ else
41
+ lines << pad("", :pos_revision)
42
+ end
43
+
44
+ lines << add_field(entry.author, :author)
45
+ lines << colorize(entry.date, :date)
46
+ lines
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'system/command'
5
+ require 'system/cachecmd'
6
+ require 'pvn/svn/command/svncmd'
7
+ require 'pvn/log/logfactory'
8
+ require 'pvn/log/logoptions'
9
+
10
+ module PVN
11
+ class LogCommand < SVNCommand
12
+ COMMAND = "log"
13
+ REVISION_ARG = '-r'
14
+
15
+ attr_reader :options
16
+
17
+ self.doc do |doc|
18
+ doc.subcommands = [ COMMAND, 'l' ]
19
+ doc.description = "Print log messages for the given files."
20
+ doc.usage = "[OPTIONS] FILE..."
21
+ doc.summary = [ "Prints the log entries for the given files, with colorized",
22
+ "output. Unlike 'svn log', which prints all log entries, ",
23
+ "'pvn log' prints #{DEFAULT_LIMIT} entries by default.",
24
+ "As with other pvn commands, 'pvn log' accepts relative ",
25
+ "revisions."
26
+ ]
27
+ doc.options.concat LogOptionSet.new.options
28
+ doc.examples << [ "pvn log foo.rb", "Prints the latest #{DEFAULT_LIMIT} log entries for foo.rb." ]
29
+ doc.examples << [ "pvn log -l 25 foo.rb", "Prints 25 log entries for the file." ]
30
+ doc.examples << [ "pvn log -3 foo.rb", "Prints the log entry for revision (HEAD - 3)." ]
31
+ doc.examples << [ "pvn log +3 foo.rb", "Prints the 3rd log entry." ]
32
+ doc.examples << [ "pvn log -l 10 -F", "Prints the latest 10 entries, unformatted." ]
33
+ doc.examples << [ "pvn log -r 122 -v", "Prints log entry for revision 122, with the files in that change." ]
34
+ end
35
+
36
+ def initialize args = Hash.new
37
+ @options = LogOptionSet.new
38
+
39
+ debug "args: #{args.inspect}"
40
+
41
+ @options.revision.fromdate = args[:fromdate]
42
+ @options.revision.todate = args[:todate]
43
+
44
+ @options.options.each do |opt|
45
+ info "opt: #{opt}".blue
46
+ end
47
+
48
+ @entries = nil
49
+
50
+ super
51
+ end
52
+
53
+ def has_entries?
54
+ true
55
+ end
56
+
57
+ def use_cache?
58
+ # use cache unless log is to head.
59
+ super && !@options.revision.head?
60
+ end
61
+
62
+ def entries
63
+ @entries ||= begin
64
+ # of course this assumes that output is in plain text (non-XML)
65
+ factory = PVN::Log::TextFactory.new output
66
+ factory.entries
67
+ end
68
+ end
69
+
70
+ def revision_of_nth_entry num
71
+ entry = nth_entry num
72
+ entry && entry.revision.to_i
73
+ end
74
+
75
+ def nth_entry n
76
+ entries[-1 * n]
77
+ end
78
+
79
+ def write_entries
80
+ info "@options: #{@options.inspect}"
81
+ info "@options.format: #{@options.format.inspect}".yellow
82
+
83
+ entries.each do |entry|
84
+ info "@options.format.value: #{@options.format.value}"
85
+ entry.write @options.format.value
86
+ end
87
+ unless @options.format
88
+ puts PVN::Log::Entry::BANNER
89
+ end
90
+ end
91
+
92
+ # this may be faster than get_nth_entry
93
+ def read_from_log_output n_matches
94
+ loglines = output.reverse
95
+
96
+ entries = entries
97
+ entry = entries[-1 * n_matches]
98
+
99
+ if true
100
+ return entry && entry.revision.to_i
101
+ end
102
+
103
+ loglines.each do |line|
104
+ next unless md = SVN_LOG_SUMMARY_LINE_RE.match(line)
105
+
106
+ info "md: #{md}".yellow
107
+
108
+ n_matches -= 1
109
+ if n_matches == 0
110
+ return md[1].to_i
111
+ end
112
+ end
113
+ nil
114
+ end
115
+ end
116
+ end
117
+
118
+ module PVN::Log
119
+ class Command < CachableCommand
120
+ def initialize args
121
+ command = %w{ svn log }
122
+
123
+ # todo: handle revision conversion:
124
+ fromrev = args[:fromrev]
125
+ torev = args[:torev]
126
+
127
+ if fromrev && torev
128
+ command << "-r" << "#{fromrev}:#{torev}"
129
+ elsif args[:fromdate] && args[:todate]
130
+ command << "-r" << "\{#{fromdate}\}:\{#{todate}\}"
131
+ end
132
+ debug "command: #{command}".on_red
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+
4
+ require 'rubygems'
5
+ require 'riel'
6
+ require 'pvn/config'
7
+
8
+ module PVN; module Log; end; end
9
+
10
+ module PVN::Log
11
+ class Entry
12
+ include Loggable
13
+
14
+ FIELDS = [ :revision,
15
+ :user,
16
+ :date,
17
+ :time,
18
+ :tz,
19
+ :dtg,
20
+ :nlines,
21
+ :files,
22
+ :comment ]
23
+
24
+ FIELDS.each do |field|
25
+ attr_reader field
26
+ end
27
+
28
+ WRITE_FORMAT_DEFAULT = ('#{revision.yellow}\t#{user.green}\t#{date} #{time}\n' +
29
+ '#{list(comment)}#{cr(files)}' +
30
+ '#{list(files, :blue, :on_yellow)}\n')
31
+
32
+ WRITE_SUMMARY_LINE = 'r#{revision} | #{user} | #{date} #{time} #{tz} (#{dtg}) | #{nlines} #{nlines.to_i == 1 ? "line" : "lines"}\n'
33
+
34
+ WRITE_UNFORMATTED_VERBOSE = (WRITE_SUMMARY_LINE +
35
+ 'Changed Paths:\n' +
36
+ '#{list(files)}\n' +
37
+ '#{plainlist(comment)}')
38
+
39
+ WRITE_UNFORMATTED_TERSE = (WRITE_SUMMARY_LINE + '\n' +
40
+ '#{plainlist(comment)}')
41
+
42
+ BANNER = '-' * 72
43
+
44
+ def set_from_args name, args
45
+ self.instance_variable_set '@' + name.to_s, args[name]
46
+ end
47
+
48
+ # Reads a log entry from the text, starting at the first line at or after
49
+ # lidx, matching the svn log separator line. Returns [ entry, new_index ],
50
+ # where new_index is the updated index into the lines. Returns nil if the
51
+ # text does not match the expected plain text format.
52
+ def self.create_from_text lines, lidx = 0
53
+ return TextOutputReader.create_from_text lines, lidx
54
+ end
55
+
56
+ def initialize args = Hash.new
57
+ FIELDS.each do |field|
58
+ set_from_args field, args
59
+ end
60
+ end
61
+
62
+ def cr ary
63
+ ary && !ary.empty? ? "\n" : ''
64
+ end
65
+
66
+ def list lines, *colors
67
+ return '' unless lines
68
+
69
+ lines.collect do |line|
70
+ ln = line.chomp
71
+ colors.each do |color|
72
+ ln = ln.send(color)
73
+ end
74
+ " " + ln + "\n"
75
+ end.join('')
76
+ end
77
+
78
+ def plainlist lines
79
+ return '' unless lines
80
+
81
+ # ensure that each has a newline
82
+ lines.collect do |line|
83
+ line.chomp + "\n"
84
+ end.join('')
85
+ end
86
+
87
+ def write formatted
88
+ # ------------------------------------------------------------------------
89
+ # r1907 | hielke.hoeve@gmail.com | 2011-11-14 05:50:38 -0500 (Mon, 14 Nov 2011) | 1 line
90
+ #
91
+ # back to dev
92
+
93
+ if formatted
94
+ cfg = PVN::Configuration.read
95
+
96
+ logcfg = cfg.section "log"
97
+ info "logcfg: #{logcfg}"
98
+ format = logcfg && logcfg.assoc('format') && logcfg.assoc('format')[1]
99
+ info "format: #{format}"
100
+
101
+ format ||= WRITE_FORMAT_DEFAULT
102
+
103
+ # @todo allow reformatting of date and time
104
+ # format = WRITE_FORMAT_DEFAULT
105
+ msg = eval('"' + format + '"')
106
+ print msg
107
+ else
108
+ puts BANNER
109
+
110
+ fmt = files ? WRITE_UNFORMATTED_VERBOSE : WRITE_UNFORMATTED_TERSE
111
+
112
+ puts eval('"' + fmt + '"')
113
+ end
114
+ end
115
+ end
116
+ end