rscm-accurev 0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/Rakefile +7 -76
  2. data/TODO +3 -17
  3. data/lib/rscm/accurev.rb +1 -13
  4. data/lib/rscm/scm/accurev/#command.rb# +95 -0
  5. data/lib/rscm/scm/accurev/api.rb +77 -258
  6. data/lib/rscm/scm/accurev/command.rb +40 -97
  7. data/lib/rscm/scm/accurev/filterio.rb +4 -6
  8. data/lib/rscm/scm/accurev/xml.rb +11 -199
  9. data/test/t_command.rb +11 -59
  10. data/test/t_load.rb +0 -1
  11. data/test/t_scrubio.rb +6 -1
  12. data/{apitest.rb → test.rb} +0 -1
  13. data/{test/eg/update-newwksp.xml → testing.log} +138 -0
  14. metadata +15 -57
  15. data/STATUS +0 -63
  16. data/bumprelease.sh +0 -13
  17. data/lib/rscm/scm/accurev/api.rb.mine +0 -382
  18. data/lib/rscm/scm/accurev/api.rb.r263 +0 -364
  19. data/lib/rscm/scm/accurev/api.rb.r265 +0 -393
  20. data/lib/rscm/scm/accurev/exception.rb +0 -38
  21. data/lib/test/unit/ui/xml/testrunner.rb +0 -165
  22. data/lib/test/unit/ui/xml/xmltestrunner.xslt +0 -79
  23. data/test/coverage/analyzer.rb +0 -127
  24. data/test/coverage/c_loader.rb +0 -34
  25. data/test/coverage/cover.rb +0 -91
  26. data/test/coverage/coverage_loader.rb +0 -21
  27. data/test/coverage/coveragetask.rb +0 -38
  28. data/test/coverage/index_tmpl.html +0 -42
  29. data/test/coverage/template.html +0 -36
  30. data/test/eg/ac-files.xml +0 -172
  31. data/test/eg/ac-pop.txt +0 -195
  32. data/test/eg/files-various-states.xml +0 -188
  33. data/test/eg/hist-oneweek-all.xml +0 -1483
  34. data/test/eg/hist-oneweek-external.xml +0 -246
  35. data/test/eg/hist-oneweek-promotes.xml +0 -1092
  36. data/test/eg/info.txt +0 -14
  37. data/test/eg/stat-a-various.xml +0 -1789
  38. data/test/eg/stat-m.xml +0 -13
  39. data/test/eg/stat-overlap.xml +0 -13
  40. data/test/eg/stat-x.xml +0 -20
  41. data/test/eg/update-i-mods-and-updates-and-overlap.xml +0 -73
  42. data/test/eg/update-i-nochanges.xml +0 -8
  43. data/test/eg/update-i-stale.xml +0 -0
  44. data/test/eg/update-i-updates.xml +0 -125
  45. data/test/eg/update-nochanges.xml +0 -7
  46. data/test/eg/update-stale.xml +0 -12
  47. data/test/eg/update-updates.xml +0 -147
  48. data/test/t_api.rb +0 -163
  49. data/test/t_xmlmapper.rb +0 -75
@@ -1,393 +0,0 @@
1
- # -*- ruby -*-
2
- #
3
- # = api.rb
4
- #
5
- # API for interacting with accurev workspaces.
6
- #
7
- # Includes:
8
- #
9
- # * API
10
- #
11
- require 'stringio'
12
- require 'rscm/base'
13
- require 'rscm/path_converter'
14
- require 'rexml/document'
15
- require 'rscm/scm/accurev/xml'
16
- require 'rscm/scm/accurev/filterio'
17
- require 'rscm/scm/accurev/command'
18
- require 'rscm/scm/accurev/exception'
19
-
20
- # need to define module within module before you can use module X::Y
21
- module RSCM; module Accurev; end; end
22
-
23
- module RSCM::Accurev
24
-
25
- #
26
- # RSCM implementation for Accurev (http://www.accurev.com).
27
- #
28
- # Requires an accurev cli executable on the path (see also
29
- # RSCM::Accurev::Command), and the correct environment
30
- # configuration for ac server/principal/password.
31
- #
32
- # ---
33
- #
34
- # === Example
35
- #
36
- # api = RSCM::Accurev::API.new( "./ws/proj-1", "proj", "proj-1" )
37
- # api.checkout() each do |file|
38
- # puts "Updated #{file}..."
39
- # end
40
- #
41
- class API < RSCM::Base
42
- register self
43
-
44
- ann :description => "Accurev Depot"
45
- attr_accessor :depot
46
-
47
- ann :description => "Backing Stream (autodetected)"
48
- attr_accessor :backing_stream
49
-
50
- # If workspace stream is nil (the default), checkout/update will be
51
- # done using `accurev pop`. This is faster and more appropriate for
52
- # read-only use; however a workspace is required for commits.
53
- ann :description => "Workspace Stream"
54
- attr_accessor :workspace_stream
55
-
56
- # [defined in Base]
57
- # ann :description => "Filesystem Path to Workspace"
58
- # attr_accessor :checkout_dir
59
-
60
- ann :description => "Overwrite Mode: if true, co overwrites existing"
61
- attr_accessor :overwrite
62
-
63
- def initialize(checkout_dir=nil, backing_stream=nil, workspace_stream=nil)
64
- @depot = nil # will be pulled from files cmd output
65
- @workspace_stream = workspace_stream
66
- @backing_stream = backing_stream
67
- @checkout_dir = checkout_dir
68
- @overwrite = false
69
- end
70
-
71
- def name()
72
- return "Accurev"
73
- end
74
-
75
- # Accurev operations are atomic: returns true.
76
- def transactional?
77
- return true
78
- end
79
-
80
- # "Adds +relative_filename+ to the working copy."
81
- def add( relative_filename )
82
- raise "XXX implement me"
83
- end
84
-
85
- def edit( relative_filename )
86
- # NOP - not required for ac
87
- end
88
-
89
- # "Returns a Revisions object for the period specified ... (inclusive)."
90
- #
91
- # list txns (promotes to bs) from hist within the period
92
- #
93
- def revisions( from_identifier, to_identifier=Time.infinity )
94
- raise "XXX implement me"
95
- end
96
-
97
- # default impl depends on a correct impl of revisions()
98
- # def uptodate?( identifier=nil )
99
- #
100
- # end
101
-
102
- # def checked_out? - base
103
-
104
- # accurev actually does have triggers, but I haven't implemented that yet
105
- def supports_trigger?
106
- false
107
- end
108
-
109
- # def diff() XXX
110
-
111
-
112
- # --- ac specific
113
-
114
- def ac_files( relative_path )
115
- cmd = Command.instance
116
- ret = []
117
- with_working_dir( @checkout_dir ) do
118
- acresponse = cmd.accurev( "files", relative_path )
119
- acresponse['element'].each do |fd|
120
- yield fd if block_given?
121
- ret << fd
122
- end
123
- end
124
- return ret
125
- end
126
-
127
- # yeilds the TransactionData objects for the given time period
128
- # (promotes only)
129
- def ac_hist( from, to=Time.infinite )
130
- cmd = Command.instance
131
- lower = from.to_accurev
132
- upper = "now"
133
- unless to == Time.infinite
134
- upper = to.to_accurev
135
- end
136
- with_working_dir( self.co_filepath ) do
137
- acresponse = cmd.accurev( "hist",
138
- "-t", "'#{upper}-#{lower}'",
139
- "-k", "promote"
140
- )
141
- ret = []
142
- acresponse['transaction'].each do |txn|
143
- ret << txn
144
- yield txn if block_given?
145
- end
146
- return ret
147
- end
148
- end
149
-
150
- def ac_keep( files=[], message="" )
151
- raise "XXX implement me"
152
- end
153
-
154
- def ac_promote( files=[], message="" )
155
- raise "XXX implement me"
156
- end
157
-
158
- def ac_update( relative_path="." )
159
- d = accurev( "update", relative_path )
160
- if xxx_error_stale
161
- raise StaleWorkspaceError.new( "#{relative_path} is stale -- keep/anchor all changes and re-update" )
162
- end
163
- end
164
-
165
- def ac_purge( files=[] )
166
- raise "XXX implement me"
167
- end
168
-
169
- def ac_revert( files=[] )
170
- raise "XXX implement me"
171
- end
172
-
173
- def ac_move( current_file, new_file )
174
- raise "XXX implement me"
175
- end
176
-
177
- #
178
- # Performs an "accurev info" command in the workspace.
179
- # Returns a map of
180
- #
181
- # ac info: shows eg, backing stream
182
- # but doesn't support -fx!
183
- #
184
- def ac_info()
185
- co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
186
- unless File.exists?( co )
187
- raise AccurevException.new( "Checkout dir #{co} does not exist" )
188
- end
189
- info = {}
190
- with_working_dir( co ) do
191
- cmd = Command.instance
192
- io = StringIO.new( cmd.accurev_nofx( "info" ) )
193
- io.each_line do |line|
194
- next unless line =~ /\S/
195
- if line =~ /^(.*?):\s+(.*)$/
196
- info[$1] = $2
197
- end
198
- end
199
- end
200
- return info
201
- end
202
-
203
- # ac mkws
204
- # -b orbitz-host-gt3-0-impl
205
- # -w orbitz-host-gt3-0-impl-test2_gfast
206
- # -l `pwd`
207
- # - does not support fx (argh!@)
208
- # - does not pop
209
- #
210
-
211
- # diff: /usr/local/bin/acdiff (!) --fx
212
- # (after an ac cat on the backed file)
213
- # (eg, no in-process diffing ala cvs diff)
214
- # lists modified lines in xml
215
-
216
- #
217
- # "Checks out or updates[!] contents from a central SCM
218
- # to +checkout_dir+ - a local working copy."
219
- #
220
- # "The +to_identifier+ parameter may be optionally specified to
221
- # obtain files up to a particular time or label."
222
- #
223
- # For accurev, this:
224
- # * checks to see if +@checkout_dir+ exists and appears checked out.
225
- # If it's already checked out, this calls +update()+. If
226
- # +@checkout_dir+ exists and +to_identifier+ is given, an
227
- # exception is raised.
228
- # * otherwise, this creates a new workspace stream and populates it
229
- # at +@checkout_dir+.
230
- #
231
- # This both returns and yields a list of updated files.
232
- # Only updated files are returned, not directories.
233
- #
234
- # Current, ac_update returns both files and directories, including
235
- # deleted files.
236
- #
237
- def checkout( to_identifier=Time.infinite )
238
- co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
239
- if @backing_stream.nil?
240
- self.attempt_init_from_info()
241
- end
242
- if @workspace_stream.nil?
243
- self.checkout_pop()
244
- else
245
- unless File.exists?( co )
246
- # create new workspace
247
- self.checkout_workspace()
248
- end
249
- # update workspace
250
- self.update( to_identifier )
251
- end
252
- end
253
-
254
- def checkout_pop()
255
- co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
256
- raise "A backing stream is required" if @backing_stream.nil?
257
- raise "A working stream may not be given" unless @working_stream.nil?
258
- # for `accurev pop`: remove and re-pop the checkout copy
259
- if File.exists?( co )
260
- unless @overwrite
261
- raise "Checkout dir #{co} already exists (@overwrite=#@overwrite)"
262
- end
263
- rm_rf( co )
264
- end
265
- mkdir(co)
266
- with_working_dir( co ) do
267
- cmd = Command.instance
268
- pop_out = cmd.accurev_nofx("pop",
269
- "-R",
270
- "-v", @backing_stream,
271
- "-L", ".", ".")
272
- elems = []
273
- popio = StringIO.new( pop_out )
274
- popio.each_line do |line|
275
- if line =~ /^Populating element \/.\/(.*)$/
276
- loc = $1
277
- elems << loc
278
- yield loc if block_given?
279
- end
280
- end
281
- return elems
282
- end
283
- end
284
-
285
- def checkout_workspace()
286
- co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
287
- raise "A backing stream is required" if @backing_stream.nil?
288
- raise "A workspace is required" if @working_stream.nil?
289
- if File.exist?( co ) and !@overwrite
290
- raise "Checkout dir #{co} already exists (@overwrite=#@overwrite)"
291
- end
292
- cmd = Command.instance
293
- mkws_out = cmd.accurev_nofx( "mkws",
294
- "-b", @backing_stream,
295
- "-w", @workspace_stream,
296
- "-l", co )
297
- # kinda sucks:
298
- if ( mkws_out =~ /already exists/ )
299
- raise AccurevException.new( "Failed to checkout", mkws_out )
300
- end
301
- end
302
-
303
- def update( to_identifier=Time.infinite )
304
- co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
305
- unless File.exists?( co )
306
- raise AccurevException.new( "Workspace does not exist!" )
307
- end
308
- updated = []
309
- with_working_dir( co ) do
310
- cmd = Command.instance
311
- acresponse = cmd.accurev( "update" )
312
- if acresponse.error
313
- if acresponse.error =~ /workspace have been modified/
314
- raise StaleWorkspaceException.new( "Workspace stale",
315
- acresponse.error )
316
- else
317
- # some other update problem
318
- raise AccurevException.new( "Error on update", acresponse.error )
319
- end
320
- end
321
- if acresponse['element']
322
- acresponse['element'].each do |up|
323
- # "ac update" on a new workspace yields element locations
324
- # with leading "/"s, which should be removed to get a proper
325
- # relative path:
326
- loc = up.location.sub( /^\//, "" )
327
- yield loc if block_given?
328
- updated << loc
329
- end
330
- end
331
- end
332
- return updated
333
- end
334
-
335
- # --- internals
336
-
337
- # status flag mappings for "stat", "file" commands
338
- STATUSES = {
339
- '(backed)' => :backed,
340
- '(external)' => :external,
341
- '(modified)' => :modified,
342
- '(kept)' => :kept,
343
- '(defunct)' => :defunct,
344
- '(missing)' => :missing,
345
- '(stranded)' => :stranded,
346
- '(overlap)' => :overlap
347
- }
348
-
349
- # private
350
-
351
- # psuedo-accessor (cached)
352
- def co_filepath
353
- if @co_filepath.nil?
354
- @co_filepath = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
355
- end
356
- return @co_filepath
357
- end
358
-
359
- #
360
- # Runs an `ac info` command in +@checkout_dir+, and tries to
361
- # set +@backing_stream+ and +@workspace_stream+ from the output.
362
- #
363
- def attempt_init_from_info()
364
- if File.exists?( self.co_filepath )
365
- info = self.ac_info
366
- if info.has_key?( "Basis" )
367
- @backing_stream = info["Basis"]
368
- end
369
- if info.has_key?( "ws/ref" )
370
- @workspace_stream = info["ws/ref"]
371
- end
372
- end
373
- end
374
-
375
- # Takes a status flags line (eg, "(modified)(kept)")
376
- # and returns a list of status flags.
377
- def map_status( status_line )
378
- l = status_line.split( " " ).map {|x| x.trim}
379
- end
380
-
381
- end
382
-
383
- end
384
-
385
- class Time
386
- def to_accurev
387
- self.strftime( "%Y/%m/%d %H:%M:%S" )
388
- end
389
- end
390
-
391
- #
392
- # Copyright (c) 2005 Gregory D. Fast <gdf@speakeasy.net>
393
- #
@@ -1,38 +0,0 @@
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
@@ -1,165 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'test/unit/ui/testrunnermediator'
4
- require 'test/unit/ui/testrunnerutilities'
5
- require 'test/unit/ui/console/testrunner'
6
- require 'test/unit/autorunner'
7
- require 'rexml/document'
8
-
9
- module Test
10
- module Unit
11
- module UI
12
- module XML
13
-
14
- #
15
- # XML::TestRunner - generate xml output for test results
16
- #
17
- # Example use:
18
- #
19
- # $ ruby -rtest/unit/ui/xml/testrunner test/test_1.rb --runner=xml
20
- #
21
- # By default, XML::TestRunner will output to stdout.
22
- # You can set the environment variable $XMLTEST_OUTPUT to
23
- # a filename to send the output to that file.
24
- #
25
- # The summary file created by this testrunner is XML, but
26
- # this module also includes a stylesheet
27
- # (test/unit/ui/xml/xmltestrunner.xslt) which converts it to
28
- # HTML. Copy the XSLT file into the same directory as the
29
- # test results file, and open the results file with a browser.
30
- #
31
- # ---
32
- #
33
- # (todo: use with rake)
34
- #
35
- class TestRunner < Test::Unit::UI::Console::TestRunner
36
-
37
- def initialize( suite, output_level )
38
- super( suite )
39
- if ENV['XMLTEST_OUTPUT']
40
- fn = ENV['XMLTEST_OUTPUT']
41
- puts "Writing to #{fn}"
42
- @io = File.open( fn, "w" )
43
- @using_stdout = false
44
- else
45
- puts "Writing to stdout (along with everyone else...)"
46
- @io = STDOUT
47
- @using_stdout = true
48
- end
49
- create_document()
50
- end
51
-
52
- def create_document()
53
- @doc = REXML::Document.new()
54
- @doc << REXML::XMLDecl.new()
55
-
56
- pi = REXML::Instruction.new(
57
- "xml-stylesheet",
58
- "type='text/xsl' href='xmltestrunner.xslt' "
59
- )
60
- @doc << pi
61
-
62
- e = REXML::Element.new( "testsuite" )
63
- e.attributes['rundate'] = Time.now
64
- @doc << e
65
- end
66
-
67
- def to_s
68
- @doc.to_s
69
- end
70
-
71
- def start
72
- @current_test = nil
73
- # setup_mediator
74
- @mediator = TestRunnerMediator.new( @suite )
75
- suite_name = @suite.to_s
76
- if @suite.kind_of?(Module)
77
- suite_name = @suite.name
78
- end
79
- @doc.root.attributes['name'] = suite_name
80
- # attach_to_mediator - define callbacks
81
- @mediator.add_listener( TestResult::FAULT,
82
- &method(:add_fault) )
83
- @mediator.add_listener( TestRunnerMediator::STARTED,
84
- &method(:started) )
85
- @mediator.add_listener( TestRunnerMediator::FINISHED,
86
- &method(:finished) )
87
- @mediator.add_listener( TestCase::STARTED,
88
- &method(:test_started) )
89
- @mediator.add_listener( TestCase::FINISHED,
90
- &method(:test_finished) )
91
- # return start_mediator
92
- return @mediator.run_suite
93
- end
94
-
95
- # callbacks
96
-
97
- def add_fault( fault )
98
- ##STDERR.puts "Fault:"
99
- @faults << fault
100
- e = REXML::Element.new( "fault" )
101
- e << REXML::CData.new( fault.long_display )
102
- @current_test << e
103
- end
104
-
105
- def started( result )
106
- #STDERR.puts "Started"
107
- @result = result
108
- end
109
-
110
- def finished( elapsed_time )
111
- #STDERR.puts "Finished"
112
- res = REXML::Element.new( "result" )
113
- summ = REXML::Element.new( "summary" )
114
- summ.text = @result
115
- res << summ
116
- # @result is a Test::Unit::TestResults
117
- res.attributes['passed'] = @result.passed?
118
- res.attributes['testcount'] = @result.run_count
119
- res.attributes['assertcount'] = @result.assertion_count
120
- res.attributes['failures'] = @result.failure_count
121
- res.attributes['errors'] = @result.error_count
122
- @doc.root << res
123
-
124
- e = REXML::Element.new( "elapsed-time" )
125
- e.text = elapsed_time
126
- @doc.root << e
127
- @io.puts( @doc.to_s )
128
-
129
- unless @using_stdout
130
- puts @result
131
- end
132
- end
133
-
134
- def test_started( name )
135
- #STDERR.puts "Test: #{name} started"
136
- e = REXML::Element.new( "test" )
137
- e.attributes['name'] = name
138
- #e.attributes['status'] = "failed"
139
- @doc.root << e
140
- @current_test = e
141
- end
142
-
143
- def test_finished( name )
144
- #STDERR.puts "Test: #{name} finished"
145
- # find //test[@name='name']
146
- @current_test = nil
147
- end
148
-
149
- end
150
- end
151
- end
152
- end
153
- end
154
-
155
- # "plug in" xmltestrunner into autorunner's list of known runners
156
- # This enables the "--runner=xml" commandline option.
157
- Test::Unit::AutoRunner::RUNNERS[:xml] = proc do |r|
158
- require 'test/unit/ui/xml/testrunner'
159
- Test::Unit::UI::XML::TestRunner
160
- end
161
-
162
- if __FILE__ == $0
163
- Test::Unit::UI::XML::TestRunner.start_command_line_test
164
- end
165
-
@@ -1,79 +0,0 @@
1
- <?xml version="1.0"?>
2
- <xsl:stylesheet
3
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
4
- >
5
-
6
- <xsl:output method="html" />
7
-
8
- <xsl:template match="/testsuite">
9
- <html>
10
- <head>
11
- <title>Test Suite Results for <xsl:value-of select="@name" /></title>
12
- <style>
13
- .error { color: #ff0000; }
14
- .eresult {
15
- background: #ffcccc;
16
- color: #ff0000;
17
- }
18
- h1,h2 {
19
- background: #cccccc;
20
- color: #000055;
21
- border: 1px dotted black;
22
- }
23
- </style>
24
- </head>
25
- <body>
26
- <h1>Test Suite Results</h1>
27
-
28
- <p>Results for: <xsl:value-of select="@name" /></p>
29
-
30
- <p>
31
- Test suite run at: <b><xsl:value-of select="@rundate" /></b>
32
- </p>
33
-
34
- <h2>Summary</h2>
35
-
36
- <p>
37
- <xsl:if test="result[@passed = 'false']">
38
- <xsl:attribute name="class">error</xsl:attribute>
39
- </xsl:if>
40
- <xsl:value-of select="result/summary/text()" />
41
- </p>
42
- <p>
43
- Elapsed time: <xsl:value-of select="elapsed-time/text()" />
44
- </p>
45
-
46
- <table border="1">
47
- <tr>
48
- <th>Case</th>
49
- <th>Result</th>
50
- </tr>
51
- <xsl:for-each select="test">
52
- <tr>
53
- <td>
54
- <xsl:if test="fault/text()">
55
- <xsl:attribute name="class">error</xsl:attribute>
56
- </xsl:if>
57
- <xsl:value-of select="@name" />
58
- </td>
59
- <td>
60
- <xsl:choose>
61
- <xsl:when test="fault/text()">
62
- <xsl:attribute name="class">eresult</xsl:attribute>
63
- <pre>
64
- <xsl:value-of select="fault/text()" />
65
- </pre>
66
- </xsl:when>
67
- <xsl:otherwise>
68
- (pass)
69
- </xsl:otherwise>
70
- </xsl:choose>
71
- </td>
72
- </tr>
73
- </xsl:for-each>
74
- </table>
75
- </body>
76
- </html>
77
- </xsl:template>
78
-
79
- </xsl:stylesheet>