rscm-accurev 0.0.4 → 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.
@@ -0,0 +1,38 @@
1
+ # -*- ruby -*-
2
+ #
3
+ # = exception.rb
4
+ #
5
+ # Exception classes for RSCM::Accurev
6
+ #
7
+ # Includes:
8
+ #
9
+ # * AccurevException
10
+ #
11
+ # * StaleWorkspaceException
12
+ #
13
+ module RSCM
14
+ module Accurev
15
+
16
+ #
17
+ # General exception class for errors processing commands.
18
+ #
19
+ # @attr error_msg Error message output by accurev.
20
+ #
21
+ class AccurevException < Exception
22
+ attr_reader :error_msg
23
+ def initialize( msg, error_msg=nil )
24
+ super( "#{msg}: #{error_msg}" )
25
+ @error_msg = error_msg
26
+ end
27
+ end
28
+
29
+ #
30
+ # Exception thrown when an update is performed
31
+ # on a workspace with unkept/unanchored modifications.
32
+ # Accurev requires that all modifications be handled before
33
+ # an update is performed.
34
+ #
35
+ class StaleWorkspaceException < AccurevException; end
36
+
37
+ end
38
+ end
@@ -109,6 +109,11 @@ module RSCM::Accurev
109
109
  end.send( :define_method, "element_name" ) {name}
110
110
  end
111
111
 
112
+ # currently advisory only
113
+ def self.children( *kidtypes )
114
+ # nothing XXX
115
+ end
116
+
112
117
  def initialize( element=nil )
113
118
  @children = {}
114
119
  unless element.nil?
@@ -121,6 +126,18 @@ module RSCM::Accurev
121
126
  return self.children[key]
122
127
  end
123
128
 
129
+ def to_s
130
+ s = "<#{self.class.element_name} "
131
+ self.instance_variables.each do |a|
132
+ unless a == "@children"
133
+ attr = a.sub( /^@/, "" )
134
+ s += "#{attr}='#{self.send(attr)}' "
135
+ end
136
+ end
137
+ s += "/>"
138
+ return s
139
+ end
140
+
124
141
  protected
125
142
  # Does the work of calling object setters for each XML attribute.
126
143
  def set_from_element( e )
@@ -179,4 +196,29 @@ module RSCM::Accurev
179
196
  attr_accessor :error, :text_content
180
197
  end
181
198
 
199
+ #
200
+ # Version (element) records in a history transaction
201
+ #
202
+ class VersionData < ElementBackedClass
203
+ element_name 'version'
204
+ attr_accessor :path, :eid, :virtual, :real, :elem_type
205
+ end
206
+
207
+ #
208
+ # Commit messages on transactions
209
+ #
210
+ class CommentData < ElementBackedClass
211
+ element_name 'comment'
212
+ end
213
+
214
+ #
215
+ # Data from "accurev hist" - transaction groups
216
+ # Contains one or more VersionData.
217
+ #
218
+ class TransactionData < ElementBackedClass
219
+ element_name 'transaction'
220
+ children VersionData, CommentData
221
+ attr_accessor :id, :type, :time, :user
222
+ end
223
+
182
224
  end
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/ruby
2
+ require 'erb'
3
+ require 'fileutils'
4
+ include FileUtils
5
+
6
+ #
7
+ # usage:
8
+ # rake coverage
9
+ #
10
+ #
11
+
12
+ trace_file = ARGV.shift
13
+ output_dir = ARGV.shift
14
+ template_file = ARGV.shift
15
+ template_index = ARGV.shift
16
+
17
+ if trace_file.nil? or output_dir.nil?
18
+ raise "Usage: $0 <tracefile> <output_dir> <template> <index_template>"
19
+ end
20
+
21
+ # stdout.printf("#%d:%s:%d:%s:%s: %s",
22
+ # get_thread_no,
23
+ # file,
24
+ # line,
25
+ # klass || '',
26
+ # EVENT_SYMBOL[event],
27
+ # get_line(file, line))
28
+
29
+ puts "Reading trace data #{trace_file}..."
30
+ files = {}
31
+ File.open( trace_file, "r" ).each_line do |line|
32
+ data, linedump = line.split(/ /)
33
+ threadno, file, n, classname, eventsym = data.split(/:/)
34
+ files[file] ||= []
35
+ files[file][n.to_i] ||= 0
36
+ files[file][n.to_i] += 1
37
+ end
38
+
39
+ class Summary
40
+ attr_accessor :filename, :total_lines, :covered_lines
41
+ attr_accessor :lines, :seen
42
+ def initialize( filename )
43
+ @filename = filename
44
+ @total_lines = 0
45
+ @covered_lines = 0
46
+ @lines = []
47
+ @seen = []
48
+ end
49
+ def pct
50
+ @covered_lines.to_f / @total_lines.to_f
51
+ end
52
+ def htmlfile
53
+ @filename.gsub(/[\.\/]/, '_') + ".html"
54
+ end
55
+ def get_binding
56
+ binding
57
+ end
58
+ end
59
+
60
+ class IndexSummary
61
+ attr_accessor :summary
62
+ def get_binding
63
+ binding
64
+ end
65
+ end
66
+
67
+ def pretty( template, output_dir, s )
68
+ htmlfile = "#{output_dir}/#{s.htmlfile}"
69
+ puts htmlfile
70
+ File.open( htmlfile, "w" ) do |out|
71
+ rhtml = ERB.new( template )
72
+ out.print( rhtml.result( s.get_binding ) )
73
+ end
74
+ end
75
+
76
+ def index( template, output_dir, summaries )
77
+ idx = IndexSummary.new
78
+ idx.summary = summaries
79
+ puts "#{output_dir}/index.html"
80
+ File.open( "#{output_dir}/index.html", "w" ) do |out|
81
+ rhtml = ERB.new( template )
82
+ out.print( rhtml.result( idx.get_binding ) )
83
+ end
84
+ end
85
+
86
+ template = File.read( template_file )
87
+ index_tmpl = File.read( template_index )
88
+
89
+ puts "Outputting to #{output_dir}..."
90
+ mkdir_p( output_dir )
91
+ summary = {}
92
+ files.each do |file, linelist|
93
+ s = Summary.new( file )
94
+ lineno = 0
95
+ File.open( file ).each_line do |line|
96
+ lineno += 1
97
+ seen_this = false
98
+ # basic: line was traced
99
+ unless linelist[lineno].nil?
100
+ seen_this = true
101
+ end
102
+ # misc: various comments, blank lines, other "untraceables"
103
+ # mark them as seen
104
+ if line =~ /^\s*$/
105
+ seen_this = true
106
+ end
107
+ if line =~ /^\s*#/
108
+ seen_this = true
109
+ end
110
+ if line =~ /^\s*(require|class|module|end|else|include|def)/
111
+ seen_this = true
112
+ end
113
+ s.seen << seen_this
114
+ if seen_this
115
+ s.covered_lines += 1
116
+ end
117
+ s.total_lines +=1
118
+ s.lines << line
119
+ end
120
+ summary[file] = s
121
+ pretty( template, output_dir, summary[file] )
122
+ end
123
+ index( index_tmpl, output_dir, summary )
124
+
125
+
126
+
127
+
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+ require 'tracer'
3
+
4
+ # Initialize tracer
5
+ TRACE_FILE = "xxx.trace"
6
+ OUTPUT = File.open( TRACE_FILE, "w" )
7
+ puts "Tracing to #{TRACE_FILE}"
8
+ t = Tracer.new()
9
+ def t.stdout
10
+ OUTPUT
11
+ end
12
+ def t.coverage_filter( event, file, line, id, binding, klass )
13
+ # skip c libs
14
+ return false if event == 'c-call'
15
+ return false if event == 'c-return'
16
+ return false if event == 'class'
17
+ # skip any (other) core libs
18
+ return false if file =~ /^\//
19
+ # skip magical eval code
20
+ return false if file =~ /\(eval\)/
21
+ # log everything else
22
+ return true
23
+ end
24
+ t.add_filter( t.method(:coverage_filter).to_proc )
25
+
26
+ # load in test files
27
+ ARGV.each do |f|
28
+ load f unless f =~ /^-/
29
+ end
30
+
31
+ # turn tracing on: test::unit::autorunner runs test in an at_exit proc
32
+ t.on
33
+
34
+
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # set_trace_func proc do |event,file,line,id,binding,classname|
4
+ # 'c-call' # call into clib - file:line -> caller
5
+ # 'c-return' # return out of clib - file:line -> caller
6
+ # 'call' # call into ruby fn - file:line -> fn def
7
+ # 'class' # start class/mod def (only for dyn classes?)
8
+ # 'end' # end class/mod def
9
+ # 'line' # exec line
10
+ # 'raise' # exception
11
+ # 'return' # return from ruby fn - file:line -> returning stmt
12
+ # end
13
+
14
+ require 'rexml/document'
15
+ include REXML
16
+
17
+ # defining script_lines make ruby dump all scripts into this hash
18
+ SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
19
+
20
+
21
+ module Test
22
+
23
+ class Cover
24
+
25
+ attr_accessor :codebase_files
26
+
27
+ def initialize()
28
+ @codebase_files = []
29
+ # seen_lines is a hash of hashes
30
+ @seen_lines = {}
31
+ end
32
+
33
+ def trace_func( event, file, line, id, binding, classname )
34
+ return if event == 'c-call'
35
+ return if event == 'c-return'
36
+ return if event == 'class'
37
+ @seen_lines[file] ||= {}
38
+ @seen_lines[file][line] ||= 0
39
+ @seen_lines[file][line] += 1
40
+ end
41
+
42
+ def coverage()
43
+ set_trace_func( self.method(:trace_func).to_proc )
44
+ yield self
45
+ set_trace_func( nil )
46
+ end
47
+
48
+ def coverage_all()
49
+ set_trace_func( self.method(:trace_func).to_proc )
50
+ end
51
+
52
+ def coverage_clear()
53
+ set_trace_func( nil )
54
+ end
55
+
56
+ def to_xml
57
+ doc = Document.new()
58
+ doc << XMLDecl.new()
59
+ root = Element.new( "coverage" )
60
+ doc << root
61
+ root.attributes['timestamp'] = Time.now
62
+ codebase = Element.new( "codebase" )
63
+ root << codebase
64
+ @codebase_files.each do |file|
65
+ e = Element.new( "file" )
66
+ e.attributes['name'] = file
67
+ codebase << e
68
+ if @seen_lines.has_key?( file )
69
+ seen = Element.new( "seen" )
70
+ e << seen
71
+ linehash = @seen_lines[file]
72
+ next unless SCRIPT_LINES__.has_key?( file )
73
+ linehash.each do |n,occur|
74
+ le = Element.new( "line" )
75
+ le.attributes['n'] = n
76
+ le.attributes['occur'] = occur
77
+ seen << le
78
+ end
79
+ ce = Element.new( "coverage" )
80
+ ce.attributes['seen'] = linehash.size
81
+ ce.attributes['total'] = SCRIPT_LINES__[file].size
82
+ ce.attributes['pct'] = linehash.size.to_f / SCRIPT_LINES__[file].size.to_f
83
+ seen << ce
84
+ end
85
+ end
86
+ return doc
87
+ end
88
+
89
+ end
90
+
91
+ end
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ #require 'tracer'
4
+ require 'test/cover'
5
+
6
+ cover = Test::Cover.new()
7
+ cover.coverage_all
8
+ cover.codebase_files << "./lib/rscm/accurev.rb"
9
+ cover.codebase_files << "./lib/rscm/scm/accurev/command.rb"
10
+
11
+ #Tracer.on
12
+ ARGV.each do |f|
13
+ load f unless f =~ /^-/
14
+ end
15
+
16
+ END {
17
+ cover.coverage_clear
18
+ File.open( "xxx.xml", "w" ) do |f|
19
+ f.puts( cover.to_xml )
20
+ end
21
+ }
@@ -0,0 +1,38 @@
1
+ #/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'rake'
4
+ require 'rake/tasklib'
5
+
6
+ module Rake
7
+
8
+ class CoverageTask < TaskLib
9
+ attr_accessor :name
10
+ attr_accessor :libs
11
+ attr_accessor :test_files
12
+ attr_accessor :ruby_opts
13
+
14
+ def initialize( name=:coverage )
15
+ @name = name
16
+ @libs = ["lib"]
17
+ @test_files = nil
18
+ @ruby_opts = []
19
+ yield self if block_given?
20
+ define
21
+ end
22
+
23
+ def define
24
+ lib_path = @libs.join( File::PATH_SEPARATOR )
25
+ @ruby_opts.unshift( "-I#{lib_path}" )
26
+ task @name do
27
+ ruby @ruby_opts.join(" ") +
28
+ "test/coverage_loader.rb " +
29
+ file_list.collect {|fn| "\"#{fn}\"".join(" ")
30
+ end
31
+ end
32
+
33
+ def test_loader()
34
+ find_file( 'test/coverage_loader' ) or fail "I DIE"
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,42 @@
1
+ <html>
2
+ <head>
3
+ <title>Coverage Summary</title>
4
+ </head>
5
+ <body>
6
+ <h1>Coverage Summary</h1>
7
+
8
+ <%
9
+ def grad( pct )
10
+ zero_end = [255,0,0]
11
+ one_end = [0,255,0]
12
+ g = []
13
+ (0..2).each do |i|
14
+ g[i] = (pct * (one_end[i]-zero_end[i])) + zero_end[i]
15
+ end
16
+ return "#"+g.collect{|x| "%02x" % x }.join("")
17
+ end
18
+ %>
19
+ <p>
20
+ Codebase:
21
+
22
+ <table border="1">
23
+ <tr>
24
+ <td>File</td>
25
+ <td>Lines</td>
26
+ <td>Covered</td>
27
+ <td>% Covered</td>
28
+ </tr>
29
+
30
+ <% summary.each do |filename,s| %>
31
+ <tr>
32
+ <td><a href="<%= s.htmlfile %>"><%= filename %></a></td>
33
+ <td><%= s.total_lines %></td>
34
+ <td><%= s.covered_lines %></td>
35
+ <td bgcolor="<%= grad(s.pct) %>"><%= s.pct %></td>
36
+ </tr>
37
+ <% end %>
38
+
39
+ </table>
40
+ </p>
41
+ </body>
42
+ </html>