rscm-accurev 0.0.4 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +55 -8
- data/TODO +1 -1
- data/bumprelease.sh +3 -0
- data/lib/rscm/accurev.rb +3 -2
- data/lib/rscm/scm/accurev/api.rb +181 -71
- data/lib/rscm/scm/accurev/exception.rb +38 -0
- data/lib/rscm/scm/accurev/xml.rb +42 -0
- data/test/coverage/analyzer.rb +127 -0
- data/test/coverage/c_loader.rb +34 -0
- data/test/coverage/cover.rb +91 -0
- data/test/coverage/coverage_loader.rb +21 -0
- data/test/coverage/coveragetask.rb +38 -0
- data/test/coverage/index_tmpl.html +42 -0
- data/test/coverage/template.html +36 -0
- data/test/eg/ac-files.xml +39 -39
- data/test/eg/ac-pop.txt +195 -0
- data/test/eg/files-various-states.xml +188 -0
- data/test/eg/hist-oneweek-all.xml +1483 -0
- data/test/eg/hist-oneweek-external.xml +246 -0
- data/test/eg/hist-oneweek-promotes.xml +1092 -0
- data/test/eg/info.txt +7 -7
- data/test/eg/stat-a-various.xml +1789 -0
- data/test/eg/stat-m.xml +13 -0
- data/test/eg/stat-overlap.xml +13 -0
- data/test/eg/stat-x.xml +20 -0
- data/test/eg/update-i-mods-and-updates-and-overlap.xml +73 -0
- data/test/eg/update-i-updates.xml +46 -46
- data/test/eg/update-newwksp.xml +88 -88
- data/test/eg/update-updates.xml +46 -46
- data/test/fl +18 -0
- data/test/suite_all.rb +34 -0
- data/test/t_api.rb +47 -5
- data/test/t_command.rb +1 -0
- data/test/t_load.rb +1 -0
- data/test/t_rscm.rb +26 -0
- data/test/t_scrubio.rb +1 -0
- data/test/t_xmlmapper.rb +1 -0
- metadata +25 -3
- data/apitest.rb +0 -21
@@ -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
|
data/lib/rscm/scm/accurev/xml.rb
CHANGED
@@ -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>
|