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,42 +1,27 @@
1
1
  # -*- ruby -*-
2
- #
3
- # = api.rb
4
- #
5
- # API for interacting with accurev workspaces.
6
- #
7
- # Includes:
8
- #
9
- # * API
10
- #
11
- require 'stringio'
2
+ require 'rubygems'
12
3
  require 'rscm/base'
13
4
  require 'rscm/path_converter'
14
5
  require 'rexml/document'
15
6
  require 'rscm/scm/accurev/xml'
16
7
  require 'rscm/scm/accurev/filterio'
17
8
  require 'rscm/scm/accurev/command'
18
- require 'rscm/scm/accurev/exception'
19
9
 
20
- # need to define module within module before you can use module X::Y
21
- module RSCM; module Accurev; end; end
10
+ module RSCM
11
+ module Accurev; end
12
+ end
22
13
 
23
14
  module RSCM::Accurev
24
15
 
16
+ class AccurevException < Exception ; end
17
+
18
+ # Indicates a failure of the update command due to unkept local modifications
19
+ class StaleWorkspaceError < AccurevException; end
20
+
21
+ # RSCM implementation for Accurev (http://www.accurev.com/).
25
22
  #
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
23
+ # Requires an accurev cli executable on the path, and the correct
24
+ # environment for ac server/principal/password.
40
25
  #
41
26
  class API < RSCM::Base
42
27
  register self
@@ -47,32 +32,36 @@ module RSCM::Accurev
47
32
  ann :description => "Backing Stream (autodetected)"
48
33
  attr_accessor :backing_stream
49
34
 
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
35
  ann :description => "Workspace Stream"
54
36
  attr_accessor :workspace_stream
55
37
 
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
38
+ # defined in Base
39
+ # ann :description => "Filesystem Path to Workspace"
40
+ # attr_accessor :checkout_dir
41
+
42
+ STATUSES = {
43
+ '(backed)' => :backed,
44
+ '(external)' => :external,
45
+ '(modified)' => :modified,
46
+ '(kept)' => :kept,
47
+ '(defunct)' => :defunct,
48
+ '(missing)' => :missing,
49
+ '(stranded)' => :stranded,
50
+ '(overlap)' => :overlap
51
+ }
52
+
53
+ def initialize( checkout_dir=nil, depot=nil, workspace_stream=nil )
54
+ @depot = depot
67
55
  @checkout_dir = checkout_dir
68
- @overwrite = false
56
+ @workspace_stream = workspace_stream
57
+ @backing_stream = nil # will be pulled from files cmd output
69
58
  end
70
59
 
71
60
  def name()
72
61
  return "Accurev"
73
62
  end
74
63
 
75
- # Accurev operations are atomic: returns true.
64
+ # Accurev operations are atomic:
76
65
  def transactional?
77
66
  return true
78
67
  end
@@ -87,9 +76,6 @@ module RSCM::Accurev
87
76
  end
88
77
 
89
78
  # "Returns a Revisions object for the period specified ... (inclusive)."
90
- #
91
- # list txns (promotes to bs) from hist within the period
92
- #
93
79
  def revisions( from_identifier, to_identifier=Time.infinity )
94
80
  raise "XXX implement me"
95
81
  end
@@ -111,58 +97,20 @@ module RSCM::Accurev
111
97
 
112
98
  # --- ac specific
113
99
 
114
- # remember: ac_files is non-recursive
115
100
  def ac_files( relative_path )
116
- cmd = Command.instance
117
- ret = []
118
- with_working_dir( co_filepath ) do
119
- acresponse = cmd.accurev( "files", relative_path )
120
- if acresponse['element'].nil?
121
- return []
122
- end
123
- acresponse['element'].each do |fd|
124
- yield fd if block_given?
125
- ret << fd
126
- end
101
+ out = self.accurev( "files", relative_path )
102
+ # validate
103
+ raise AccurevException.new("Failed to get response") if out.nil?
104
+ if ( out.root.name!="AcResponse" )
105
+ raise AccurevException.new("Invalid response")
127
106
  end
128
- return ret
129
- end
130
-
131
- def ac_stat( flag="-a" )
132
- cmd = Command.instance
133
- ret = []
134
- with_working_dir( co_filepath ) do
135
- acresponse = cmd.accurev( "stat", flag )
136
- return [] if acresponse['element'].nil?
137
- acresponse['element'].each do |fd|
138
- yield fd if block_given?
139
- ret << fd
140
- end
141
- end
142
- return ret
143
- end
144
-
145
- # yeilds the TransactionData objects for the given time period
146
- # (promotes only)
147
- def ac_hist( from, to=Time.infinite )
148
- cmd = Command.instance
149
- lower = from.to_accurev
150
- upper = "now"
151
- unless to == Time.infinite
152
- upper = to.to_accurev
153
- end
154
- with_working_dir( self.co_filepath ) do
155
- acresponse = cmd.accurev( "hist",
156
- "-t", "'#{upper}-#{lower}'",
157
- "-k", "promote"
158
- )
159
- ret = []
160
- acresponse['transaction'].each do |txn|
161
- ret << txn
162
- yield txn if block_given?
163
- end
164
- return ret
107
+ files = []
108
+ out.elements.each( "/AcResponse/element" ) do |e|
109
+ f = FileStatus.new( e )
110
+ yield f if block_given?
111
+ files << f
165
112
  end
113
+ return files
166
114
  end
167
115
 
168
116
  def ac_keep( files=[], message="" )
@@ -192,32 +140,9 @@ module RSCM::Accurev
192
140
  raise "XXX implement me"
193
141
  end
194
142
 
195
- #
196
- # Performs an "accurev info" command in the workspace.
197
- # Returns a map of
198
- #
199
143
  # ac info: shows eg, backing stream
200
- # but doesn't support -fx!
201
- #
202
- def ac_info()
203
- co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
204
- unless File.exists?( co )
205
- raise AccurevException.new( "Checkout dir #{co} does not exist" )
206
- end
207
- info = {}
208
- with_working_dir( co ) do
209
- cmd = Command.instance
210
- io = StringIO.new( cmd.accurev_nofx( "info" ) )
211
- io.each_line do |line|
212
- next unless line =~ /\S/
213
- if line =~ /^(.*?):\s+(.*)$/
214
- info[$1] = $2
215
- end
216
- end
217
- end
218
- return info
219
- end
220
-
144
+ # but doesn't support -fx!
145
+
221
146
  # ac mkws
222
147
  # -b orbitz-host-gt3-0-impl
223
148
  # -w orbitz-host-gt3-0-impl-test2_gfast
@@ -231,7 +156,7 @@ module RSCM::Accurev
231
156
  # (eg, no in-process diffing ala cvs diff)
232
157
  # lists modified lines in xml
233
158
 
234
- #
159
+ # checkout():
235
160
  # "Checks out or updates[!] contents from a central SCM
236
161
  # to +checkout_dir+ - a local working copy."
237
162
  #
@@ -239,156 +164,60 @@ module RSCM::Accurev
239
164
  # obtain files up to a particular time or label."
240
165
  #
241
166
  # For accurev, this:
242
- # * checks to see if +@checkout_dir+ exists and appears checked out.
243
- # If it's already checked out, this calls +update()+. If
244
- # +@checkout_dir+ exists and +to_identifier+ is given, an
245
- # exception is raised.
167
+ # * checks to see if @checkout_dir exists and appears checked out.
168
+ # If it's already checked out, this calls update().
246
169
  # * otherwise, this creates a new workspace stream and populates it
247
- # at +@checkout_dir+.
248
- #
249
- # This both returns and yields a list of updated files.
250
- # Only updated files are returned, not directories.
170
+ # at @checkout_dir.
251
171
  #
252
- # Current, ac_update returns both files and directories, including
253
- # deleted files.
172
+ # Unknown: support for +to_identifier+ (esp for update)?
254
173
  #
174
+ # This method yields files in the workspace and doesn't need to be
175
+ # overridden.
176
+ # The checkout_silent() method does the actual work.
177
+ #
178
+ # Only yields files, not directories
255
179
  def checkout( to_identifier=Time.infinite )
256
- co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
257
- if @backing_stream.nil?
258
- self.attempt_init_from_info()
259
- end
260
- if @workspace_stream.nil?
261
- self.checkout_pop()
262
- else
263
- unless File.exists?( co )
264
- # create new workspace
265
- self.checkout_workspace()
180
+ co = PathConverter.nativepath_to_filepath( @checkout_dir )
181
+ unless File.exists?( co )
182
+ puts "> creating new workspace..."
183
+ if @backing_stream.nil?
184
+ raise "Backing stream must be set"
266
185
  end
267
- # update workspace
268
- self.update( to_identifier )
269
- end
270
- end
271
-
272
- def checkout_pop()
273
- co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
274
- raise "A backing stream is required" if @backing_stream.nil?
275
- raise "A working stream may not be given" unless @working_stream.nil?
276
- # for `accurev pop`: remove and re-pop the checkout copy
277
- if File.exists?( co )
278
- unless @overwrite
279
- raise "Checkout dir #{co} already exists (@overwrite=#@overwrite)"
186
+ if @workspace_stream.nil?
187
+ raise "Workspace stream must be set"
280
188
  end
281
- rm_rf( co )
282
- end
283
- mkdir(co)
284
- with_working_dir( co ) do
285
- cmd = Command.instance
286
- pop_out = cmd.accurev_nofx("pop",
287
- "-R",
288
- "-v", @backing_stream,
289
- "-L", ".", ".")
290
- elems = []
291
- popio = StringIO.new( pop_out )
292
- popio.each_line do |line|
293
- if line =~ /^Populating element \/.\/(.*)$/
294
- loc = $1
295
- elems << loc
296
- yield loc if block_given?
297
- end
189
+ mkws_out = self.accurev_nofx( "mkws",
190
+ "-b", @backing_stream,
191
+ "-w", @workspace_stream,
192
+ "-l", co )
193
+ # sucks:
194
+ if ( mkws_out =~ /already exists/ )
195
+ raise AccurevException.new( mkws_out )
298
196
  end
299
- return elems
300
- end
301
- end
302
-
303
- def checkout_workspace()
304
- co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
305
- raise "A backing stream is required" if @backing_stream.nil?
306
- raise "A workspace is required" if @working_stream.nil?
307
- if File.exist?( co ) and !@overwrite
308
- raise "Checkout dir #{co} already exists (@overwrite=#@overwrite)"
309
- end
310
- cmd = Command.instance
311
- mkws_out = cmd.accurev_nofx( "mkws",
312
- "-b", @backing_stream,
313
- "-w", @workspace_stream,
314
- "-l", co )
315
- # kinda sucks:
316
- if ( mkws_out =~ /already exists/ )
317
- raise AccurevException.new( "Failed to checkout", mkws_out )
318
197
  end
198
+ puts "> Updating workspace.."
199
+ self.update( to_identifier )
319
200
  end
320
201
 
321
202
  def update( to_identifier=Time.infinite )
322
- co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
203
+ co = PathConverter.nativepath_to_filepath( @checkout_dir )
323
204
  unless File.exists?( co )
324
205
  raise AccurevException.new( "Workspace does not exist!" )
325
206
  end
326
207
  updated = []
327
208
  with_working_dir( co ) do
328
- cmd = Command.instance
329
- acresponse = cmd.accurev( "update" )
330
- if acresponse.error
331
- if acresponse.error =~ /workspace have been modified/
332
- raise StaleWorkspaceException.new( "Workspace stale",
333
- acresponse.error )
334
- else
335
- # some other update problem
336
- raise AccurevException.new( "Error on update", acresponse.error )
337
- end
338
- end
339
- if acresponse['element']
340
- acresponse['element'].each do |up|
341
- # "ac update" on a new workspace yields element locations
342
- # with leading "/"s, which should be removed to get a proper
343
- # relative path:
344
- loc = up.location.sub( /^\//, "" )
345
- yield loc if block_given?
346
- updated << loc
347
- end
209
+ accurev_elements( UpdateData, "update" ) do |up|
210
+ yield up.location
211
+ updated << up.location
348
212
  end
349
213
  end
350
214
  return updated
351
215
  end
352
216
 
353
- # --- internals
354
217
 
355
- # status flag mappings for "stat", "file" commands
356
- STATUSES = {
357
- '(backed)' => :backed,
358
- '(external)' => :external,
359
- '(modified)' => :modified,
360
- '(kept)' => :kept,
361
- '(defunct)' => :defunct,
362
- '(missing)' => :missing,
363
- '(stranded)' => :stranded,
364
- '(overlap)' => :overlap
365
- }
366
-
367
- # private
368
-
369
- # psuedo-accessor (cached)
370
- def co_filepath
371
- if @co_filepath.nil?
372
- @co_filepath = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
373
- end
374
- return @co_filepath
375
- end
218
+ # --- internals
376
219
 
377
- #
378
- # Runs an `ac info` command in +@checkout_dir+, and tries to
379
- # set +@backing_stream+ and +@workspace_stream+ from the output.
380
- #
381
- def attempt_init_from_info()
382
- if File.exists?( self.co_filepath )
383
- info = self.ac_info
384
- if info.has_key?( "Basis" )
385
- @backing_stream = info["Basis"]
386
- end
387
- if info.has_key?( "ws/ref" )
388
- @workspace_stream = info["ws/ref"]
389
- end
390
- end
391
- end
220
+ private
392
221
 
393
222
  # Takes a status flags line (eg, "(modified)(kept)")
394
223
  # and returns a list of status flags.
@@ -399,13 +228,3 @@ module RSCM::Accurev
399
228
  end
400
229
 
401
230
  end
402
-
403
- class Time
404
- def to_accurev
405
- self.strftime( "%Y/%m/%d %H:%M:%S" )
406
- end
407
- end
408
-
409
- #
410
- # Copyright (c) 2005 Gregory D. Fast <gdf@speakeasy.net>
411
- #
@@ -1,49 +1,35 @@
1
1
  # -*- ruby -*-
2
2
 
3
+ require 'singleton'
4
+
3
5
  module RSCM
4
6
  module Accurev
5
7
 
6
- #
7
- # Executes accurev commands and deals with the output.
8
- # This class is a thread local singleton: each thread
9
- # calling +Command.instance+ gets a different instance.
10
- #
11
8
  class Command
9
+ include Singleton
12
10
 
13
- attr_accessor :debug, :debug_to, :accurev_bin
14
-
15
- # If you need to swap out the mapper class
16
- attr_accessor :xmlmapper
11
+ attr_accessor :debug, :debug_to, :accurev, :working_dir
17
12
 
18
- def initialize()
19
- @xmlmapper = XMLMapper
13
+ def initialize( working_dir="." )
20
14
  @debug = false
21
15
  @debug_to = STDOUT
22
- @accurev_bin = "accurev"
16
+ @accurev = "accurev"
17
+ @working_dir = working_dir
23
18
  end
24
19
 
25
- #
26
- # Returns a command line string for executing the given
27
- # accurev subcomment +cmd+ with arguments +opts+.
28
- #
29
20
  def accurev_cmdline( cmd, *opts )
30
- return "#{@accurev_bin} #{cmd} #{opts.join(' ')}";
21
+ return "#{@accurev} #{cmd} #{opts.join(' ')}";
31
22
  end
32
-
33
- #
34
- # Executes the given accurev subcommand +cmd+ with the
35
- # given arguments +opts+. The command will be executed with
36
- # standard (non-xml) output format. This method returns
37
- # the stdout from the command execution.
38
- #
39
- # (Not all accurev subcommands (eg, `accurev info`) support
40
- # `-fx` for xml output.)
41
- #
23
+
24
+ # Execute the given accurev subcommand, and return its
25
+ # output as a plain uninterpreted string.
26
+ # Not all accurev subcommands (eg, `accurev info`) support
27
+ # `-fx` for xml output.
42
28
  def accurev_nofx( cmd, *opts )
43
- ## # nativepath_to_filepath is actually generic to native
44
- ## dir = PathConverter.nativepath_to_filepath( @working_dir )
45
- ## dir = File.expand_path( dir )
46
- ## with_working_dir( dir ) do
29
+ # nativepath_to_filepath is actually generic to native
30
+ dir = PathConverter.nativepath_to_filepath( @working_dir )
31
+ dir = File.expand_path( dir )
32
+ with_working_dir( dir ) do
47
33
  cmdline = self.accurev_cmdline( cmd, opts )
48
34
  if @debug
49
35
  @debug_to.puts("ac> #{cmdline}")
@@ -51,26 +37,20 @@ module RSCM
51
37
  Better.popen( cmdline ) do |stdout|
52
38
  return stdout.read()
53
39
  end
54
- ## end
40
+ end
55
41
  end
56
-
57
- #
58
- # Executes the given accurev subcommand +cmd+ with the
59
- # given arguments +opts+ in XML mode. The output of the command
60
- # will be converted to an REXML document and returned.
61
- # The command's options list will have `-fx` appended,
62
- # to specify xml output format.
63
- #
42
+
43
+ # Execute the given accurev subcommand, and return its
44
+ # output as an REXML document. The options list to the command
45
+ # will automatically have `-fx` prepended, to specify xml output.
64
46
  # Certain quirks in <AcResponse>-type documents will be
65
- # corrected (see Accurev::AcXMLScrubIO). Note that not all
66
- # accurev subcommands support the "-fx" option.
67
- #
68
- def accurev_xml( cmd, *opts )
47
+ # corrected (see Accurev::AcXMLScrubIO).
48
+ def accurev( cmd, *opts )
49
+ # nativepath_to_filepath is actually generic to native
50
+ dir = PathConverter.nativepath_to_filepath( @working_dir )
51
+ dir = File.expand_path( dir )
69
52
  opts << "-fx"
70
- ## # nativepath_to_filepath is actually generic to native
71
- ## dir = PathConverter.nativepath_to_filepath( @working_dir )
72
- ## dir = File.expand_path( dir )
73
- ## with_working_dir( dir ) do
53
+ with_working_dir( dir ) do
74
54
  cmdline = self.accurev_cmdline( cmd, opts )
75
55
  if @debug
76
56
  @debug_to.puts("ac> #{cmdline}")
@@ -78,8 +58,7 @@ module RSCM
78
58
  Better.popen( cmdline ) do |stdout|
79
59
  output = stdout.read()
80
60
  if @debug
81
- @debug_to.puts( "raw>" )
82
- @debug_to.puts( output )
61
+ @debug_to.puts( "raw>\n#{output}" )
83
62
  end
84
63
  begin
85
64
  return REXML::Document.new( AcXMLScrubIO.new( output ) )
@@ -87,64 +66,28 @@ module RSCM
87
66
  raise "Unexpected output from #{cmdline}: #{e}"
88
67
  end
89
68
  end
90
- ## end
69
+ end
91
70
  end
92
71
 
93
- #
94
- # Execute the given accurev subcommand using +accurev_xml+,
95
- # and return an object tree mirroring the structure of the
96
- # XML output.
97
- #
98
- # This uses +XMLMapper+ to build the object tree.
99
- #
100
- def accurev( cmd, *opts )
101
- doc = self.accurev_xml( cmd, opts )
72
+ # Execute the given accurev subcommand using +accurev+,
73
+ # and return the <element> REXML elements from the
74
+ # resulting document.
75
+ # For ac commands which emit the common <elements> format.
76
+ def accurev_elements( mapclass, cmd, *opts )
77
+ doc = self.accurev( cmd, opts )
102
78
  if @debug
103
- @debug_to.puts( "doc>" )
104
79
  @debug_to.puts( doc )
105
80
  end
106
81
  if doc.elements.size==0
107
82
  raise "Unexpected output from #{cmd}: #{doc}"
108
83
  end
109
- mapper = @xmlmapper.new()
110
- return mapper.map( doc.root )
111
- end
112
-
113
- # static methods
114
-
115
- # Retrieve this thread's +Command+ instance.
116
- #
117
- # eg:
118
- # cmd = Command.instance
119
- # eg:
120
- # Command.instance do |cmd|
121
- # cmd.workspace_dir = "/var/tmp"
122
- # end
123
- #
124
- def Command.instance()
125
- if Thread.current[ :RSCM_ACCUREV_COMMAND ].nil?
126
- Thread.current[ :RSCM_ACCUREV_COMMAND ] = Command.new
84
+ doc.elements.each( "/AcResponse/element" ) do |e|
85
+ o = mapclass.new( e )
86
+ yield o
127
87
  end
128
- yield Thread.current[ :RSCM_ACCUREV_COMMAND ] if block_given?
129
- return Thread.current[ :RSCM_ACCUREV_COMMAND ]
130
- end
131
-
132
- # Discard the current thread's Command object.
133
- # The next call to +Command.instance+ in this thread will
134
- # return a new instance configured with the defaults.
135
- def Command.discard()
136
- Thread.current[ :RSCM_ACCUREV_COMMAND ] = nil
137
- end
138
-
139
- private
140
-
141
- # new() is marked private, use Command.instance().
142
- def new( *args )
143
- super(args)
144
88
  end
145
89
 
146
- end # class Command
147
-
90
+ end
148
91
  end
149
92
  end
150
93
 
@@ -3,19 +3,17 @@ require 'stringio'
3
3
  module RSCM
4
4
  module Accurev
5
5
 
6
- #
7
6
  # IO stream which cleans irregularities out of accurev xml output.
8
7
  #
9
8
  # In particular:
10
9
  #
11
- # * Unlike other commands, the +-fx+ output from _accurev update_
12
- # has a root element of +<acResponse>+, not +<AcResponse>+.
10
+ # * the -fx output from `accurev update` has a root element of
11
+ # <acResponse>, not <AcResponse> like the other commands
13
12
  #
14
- # * _accurev update_ emits broken XML when there are no files
15
- # to update.
13
+ # * `accurev update` emits broken XML when there are no files
14
+ # needing updates.
16
15
  #
17
16
  class AcXMLScrubIO < StringIO
18
-
19
17
  # @param: sourceio - io or string source to wrap
20
18
  def initialize( sourceio )
21
19
  if sourceio.respond_to?( :read )