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,382 +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
- # remember: ac_files is non-recursive
115
- 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
127
- 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
- def ac_keep( files=[], message="" )
146
- raise "XXX implement me"
147
- end
148
-
149
- def ac_promote( files=[], message="" )
150
- raise "XXX implement me"
151
- end
152
-
153
- def ac_update( relative_path="." )
154
- d = accurev( "update", relative_path )
155
- if xxx_error_stale
156
- raise StaleWorkspaceError.new( "#{relative_path} is stale -- keep/anchor all changes and re-update" )
157
- end
158
- end
159
-
160
- def ac_purge( files=[] )
161
- raise "XXX implement me"
162
- end
163
-
164
- def ac_revert( files=[] )
165
- raise "XXX implement me"
166
- end
167
-
168
- def ac_move( current_file, new_file )
169
- raise "XXX implement me"
170
- end
171
-
172
- #
173
- # Performs an "accurev info" command in the workspace.
174
- # Returns a map of
175
- #
176
- # ac info: shows eg, backing stream
177
- # but doesn't support -fx!
178
- #
179
- def ac_info()
180
- co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
181
- unless File.exists?( co )
182
- raise AccurevException.new( "Checkout dir #{co} does not exist" )
183
- end
184
- info = {}
185
- with_working_dir( co ) do
186
- cmd = Command.instance
187
- io = StringIO.new( cmd.accurev_nofx( "info" ) )
188
- io.each_line do |line|
189
- next unless line =~ /\S/
190
- if line =~ /^(.*?):\s+(.*)$/
191
- info[$1] = $2
192
- end
193
- end
194
- end
195
- return info
196
- end
197
-
198
- # ac mkws
199
- # -b orbitz-host-gt3-0-impl
200
- # -w orbitz-host-gt3-0-impl-test2_gfast
201
- # -l `pwd`
202
- # - does not support fx (argh!@)
203
- # - does not pop
204
- #
205
-
206
- # diff: /usr/local/bin/acdiff (!) --fx
207
- # (after an ac cat on the backed file)
208
- # (eg, no in-process diffing ala cvs diff)
209
- # lists modified lines in xml
210
-
211
- #
212
- # "Checks out or updates[!] contents from a central SCM
213
- # to +checkout_dir+ - a local working copy."
214
- #
215
- # "The +to_identifier+ parameter may be optionally specified to
216
- # obtain files up to a particular time or label."
217
- #
218
- # For accurev, this:
219
- # * checks to see if +@checkout_dir+ exists and appears checked out.
220
- # If it's already checked out, this calls +update()+. If
221
- # +@checkout_dir+ exists and +to_identifier+ is given, an
222
- # exception is raised.
223
- # * otherwise, this creates a new workspace stream and populates it
224
- # at +@checkout_dir+.
225
- #
226
- # This both returns and yields a list of updated files.
227
- # Only updated files are returned, not directories.
228
- #
229
- # Current, ac_update returns both files and directories, including
230
- # deleted files.
231
- #
232
- def checkout( to_identifier=Time.infinite )
233
- co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
234
- if @backing_stream.nil?
235
- self.attempt_init_from_info()
236
- end
237
- if @workspace_stream.nil?
238
- self.checkout_pop()
239
- else
240
- unless File.exists?( co )
241
- # create new workspace
242
- self.checkout_workspace()
243
- end
244
- # update workspace
245
- self.update( to_identifier )
246
- end
247
- end
248
-
249
- def checkout_pop()
250
- co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
251
- raise "A backing stream is required" if @backing_stream.nil?
252
- raise "A working stream may not be given" unless @working_stream.nil?
253
- # for `accurev pop`: remove and re-pop the checkout copy
254
- if File.exists?( co )
255
- unless @overwrite
256
- raise "Checkout dir #{co} already exists (@overwrite=#@overwrite)"
257
- end
258
- rm_rf( co )
259
- end
260
- mkdir(co)
261
- with_working_dir( co ) do
262
- cmd = Command.instance
263
- pop_out = cmd.accurev_nofx("pop",
264
- "-R",
265
- "-v", @backing_stream,
266
- "-L", ".", ".")
267
- elems = []
268
- popio = StringIO.new( pop_out )
269
- popio.each_line do |line|
270
- if line =~ /^Populating element \/.\/(.*)$/
271
- loc = $1
272
- elems << loc
273
- yield loc if block_given?
274
- end
275
- end
276
- return elems
277
- end
278
- end
279
-
280
- def checkout_workspace()
281
- co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
282
- raise "A backing stream is required" if @backing_stream.nil?
283
- raise "A workspace is required" if @working_stream.nil?
284
- if File.exist?( co ) and !@overwrite
285
- raise "Checkout dir #{co} already exists (@overwrite=#@overwrite)"
286
- end
287
- cmd = Command.instance
288
- mkws_out = cmd.accurev_nofx( "mkws",
289
- "-b", @backing_stream,
290
- "-w", @workspace_stream,
291
- "-l", co )
292
- # kinda sucks:
293
- if ( mkws_out =~ /already exists/ )
294
- raise AccurevException.new( "Failed to checkout", mkws_out )
295
- end
296
- end
297
-
298
- def update( to_identifier=Time.infinite )
299
- co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
300
- unless File.exists?( co )
301
- raise AccurevException.new( "Workspace does not exist!" )
302
- end
303
- updated = []
304
- with_working_dir( co ) do
305
- cmd = Command.instance
306
- acresponse = cmd.accurev( "update" )
307
- if acresponse.error
308
- if acresponse.error =~ /workspace have been modified/
309
- raise StaleWorkspaceException.new( "Workspace stale",
310
- acresponse.error )
311
- else
312
- # some other update problem
313
- raise AccurevException.new( "Error on update", acresponse.error )
314
- end
315
- end
316
- if acresponse['element']
317
- acresponse['element'].each do |up|
318
- # "ac update" on a new workspace yields element locations
319
- # with leading "/"s, which should be removed to get a proper
320
- # relative path:
321
- loc = up.location.sub( /^\//, "" )
322
- yield loc if block_given?
323
- updated << loc
324
- end
325
- end
326
- end
327
- return updated
328
- end
329
-
330
- # --- internals
331
-
332
- # status flag mappings for "stat", "file" commands
333
- STATUSES = {
334
- '(backed)' => :backed,
335
- '(external)' => :external,
336
- '(modified)' => :modified,
337
- '(kept)' => :kept,
338
- '(defunct)' => :defunct,
339
- '(missing)' => :missing,
340
- '(stranded)' => :stranded,
341
- '(overlap)' => :overlap
342
- }
343
-
344
- # private
345
-
346
- # psuedo-accessor (cached)
347
- def co_filepath
348
- if @co_filepath.nil?
349
- @co_filepath = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
350
- end
351
- return @co_filepath
352
- end
353
-
354
- #
355
- # Runs an `ac info` command in +@checkout_dir+, and tries to
356
- # set +@backing_stream+ and +@workspace_stream+ from the output.
357
- #
358
- def attempt_init_from_info()
359
- if File.exists?( self.co_filepath )
360
- info = self.ac_info
361
- if info.has_key?( "Basis" )
362
- @backing_stream = info["Basis"]
363
- end
364
- if info.has_key?( "ws/ref" )
365
- @workspace_stream = info["ws/ref"]
366
- end
367
- end
368
- end
369
-
370
- # Takes a status flags line (eg, "(modified)(kept)")
371
- # and returns a list of status flags.
372
- def map_status( status_line )
373
- l = status_line.split( " " ).map {|x| x.trim}
374
- end
375
-
376
- end
377
-
378
- end
379
-
380
- #
381
- # Copyright (c) 2005 Gregory D. Fast <gdf@speakeasy.net>
382
- #