rscm-accurev 0.0 → 0.0.1

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.
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>