rscm-accurev 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/TODO +1 -0
- data/lib/rscm/accurev.rb +1 -0
- data/lib/rscm/scm/accurev/api.rb +33 -16
- data/lib/rscm/scm/accurev/command.rb +50 -32
- data/lib/rscm/scm/accurev/xml.rb +128 -12
- data/test/eg/update-i-nochanges.xml +8 -0
- data/test/eg/update-i-updates.xml +125 -0
- data/test/eg/update-nochanges.xml +7 -0
- data/test/eg/update-updates.xml +147 -0
- data/test/t_api.rb +42 -4
- data/test/t_command.rb +11 -15
- data/test/t_xmlmapper.rb +74 -0
- metadata +8 -3
- data/lib/rscm/scm/accurev/#api.rb# +0 -226
data/TODO
CHANGED
data/lib/rscm/accurev.rb
CHANGED
data/lib/rscm/scm/accurev/api.rb
CHANGED
@@ -13,10 +13,15 @@ end
|
|
13
13
|
|
14
14
|
module RSCM::Accurev
|
15
15
|
|
16
|
-
class AccurevException < Exception
|
16
|
+
class AccurevException < Exception
|
17
|
+
attr_reader :error_msg
|
18
|
+
def initialize( msg, error_msg=nil )
|
19
|
+
super( "#{msg}: #{error_msg}" )
|
20
|
+
@error_msg = error_msg
|
21
|
+
end
|
22
|
+
end
|
17
23
|
|
18
|
-
|
19
|
-
class StaleWorkspaceError < AccurevException; end
|
24
|
+
class StaleWorkspaceException < AccurevException; end
|
20
25
|
|
21
26
|
# RSCM implementation for Accurev (http://www.accurev.com/).
|
22
27
|
#
|
@@ -52,9 +57,9 @@ module RSCM::Accurev
|
|
52
57
|
|
53
58
|
def initialize( checkout_dir=nil, depot=nil, workspace_stream=nil )
|
54
59
|
@depot = depot
|
55
|
-
@checkout_dir = checkout_dir
|
56
60
|
@workspace_stream = workspace_stream
|
57
61
|
@backing_stream = nil # will be pulled from files cmd output
|
62
|
+
@checkout_dir = checkout_dir
|
58
63
|
end
|
59
64
|
|
60
65
|
def name()
|
@@ -99,13 +104,13 @@ module RSCM::Accurev
|
|
99
104
|
|
100
105
|
def ac_files( relative_path )
|
101
106
|
cmd = Command.instance
|
102
|
-
|
103
|
-
|
104
|
-
|
107
|
+
ret = []
|
108
|
+
acresponse = cmd.accurev( "files", relative_path )
|
109
|
+
acresponse['element'].each do |fd|
|
105
110
|
yield fd if block_given?
|
106
|
-
|
111
|
+
ret << fd
|
107
112
|
end
|
108
|
-
return
|
113
|
+
return ret
|
109
114
|
end
|
110
115
|
|
111
116
|
def ac_keep( files=[], message="" )
|
@@ -187,7 +192,7 @@ module RSCM::Accurev
|
|
187
192
|
"-l", co )
|
188
193
|
# sucks:
|
189
194
|
if ( mkws_out =~ /already exists/ )
|
190
|
-
raise AccurevException.new( mkws_out )
|
195
|
+
raise AccurevException.new( "Failed to checkout", mkws_out )
|
191
196
|
end
|
192
197
|
end
|
193
198
|
puts "> Updating workspace.."
|
@@ -195,21 +200,33 @@ module RSCM::Accurev
|
|
195
200
|
end
|
196
201
|
|
197
202
|
def update( to_identifier=Time.infinite )
|
198
|
-
co = PathConverter.nativepath_to_filepath( @checkout_dir )
|
203
|
+
co = RSCM::PathConverter.nativepath_to_filepath( @checkout_dir )
|
199
204
|
unless File.exists?( co )
|
200
205
|
raise AccurevException.new( "Workspace does not exist!" )
|
201
206
|
end
|
202
207
|
updated = []
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
208
|
+
Command.instance do |cmd|
|
209
|
+
cmd.working_dir = co
|
210
|
+
acresponse = cmd.accurev( "update" )
|
211
|
+
if acresponse.error
|
212
|
+
if acresponse.error =~ /workspace have been modified/
|
213
|
+
raise StaleWorkspaceException.new( "Workspace stale",
|
214
|
+
acresponse.error )
|
215
|
+
else
|
216
|
+
# some other update problem
|
217
|
+
raise AccurevException.new( "Error on update", acresponse.error )
|
218
|
+
end
|
219
|
+
end
|
220
|
+
if acresponse['element']
|
221
|
+
acresponse['element'].each do |up|
|
222
|
+
yield up.location if block_given?
|
223
|
+
updated << up.location
|
224
|
+
end
|
207
225
|
end
|
208
226
|
end
|
209
227
|
return updated
|
210
228
|
end
|
211
229
|
|
212
|
-
|
213
230
|
# --- internals
|
214
231
|
|
215
232
|
private
|
@@ -10,27 +10,36 @@ module RSCM
|
|
10
10
|
#
|
11
11
|
class Command
|
12
12
|
|
13
|
-
attr_accessor :debug, :debug_to, :
|
13
|
+
attr_accessor :debug, :debug_to, :accurev_bin, :working_dir
|
14
14
|
|
15
|
-
#
|
16
|
-
|
17
|
-
attr_accessor :classmap
|
15
|
+
# If you need to swap out the mapper class
|
16
|
+
attr_accessor :xmlmapper
|
18
17
|
|
19
18
|
def initialize()
|
19
|
+
@xmlmapper = XMLMapper
|
20
20
|
@debug = false
|
21
21
|
@debug_to = STDOUT
|
22
|
-
@
|
22
|
+
@accurev_bin = "accurev"
|
23
23
|
@working_dir = "."
|
24
24
|
end
|
25
25
|
|
26
|
+
#
|
27
|
+
# Returns a command line string for executing the given
|
28
|
+
# accurev subcomment +cmd+ with arguments +opts+.
|
29
|
+
#
|
26
30
|
def accurev_cmdline( cmd, *opts )
|
27
|
-
return "#{@
|
31
|
+
return "#{@accurev_bin} #{cmd} #{opts.join(' ')}";
|
28
32
|
end
|
29
|
-
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
33
|
+
|
34
|
+
#
|
35
|
+
# Executes the given accurev subcommand +cmd+ with the
|
36
|
+
# given arguments +opts+. The command will be executed with
|
37
|
+
# standard (non-xml) output format. This method returns
|
38
|
+
# the stdout from the command execution.
|
39
|
+
#
|
40
|
+
# (Not all accurev subcommands (eg, `accurev info`) support
|
41
|
+
# `-fx` for xml output.)
|
42
|
+
#
|
34
43
|
def accurev_nofx( cmd, *opts )
|
35
44
|
# nativepath_to_filepath is actually generic to native
|
36
45
|
dir = PathConverter.nativepath_to_filepath( @working_dir )
|
@@ -45,13 +54,19 @@ module RSCM
|
|
45
54
|
end
|
46
55
|
end
|
47
56
|
end
|
48
|
-
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
57
|
+
|
58
|
+
#
|
59
|
+
# Executes the given accurev subcommand +cmd+ with the
|
60
|
+
# given arguments +opts+ in XML mode. The output of the command
|
61
|
+
# will be converted to an REXML document and returned.
|
62
|
+
# The command's options list will have `-fx` appended,
|
63
|
+
# to specify xml output format.
|
64
|
+
#
|
52
65
|
# Certain quirks in <AcResponse>-type documents will be
|
53
|
-
# corrected (see Accurev::AcXMLScrubIO).
|
54
|
-
|
66
|
+
# corrected (see Accurev::AcXMLScrubIO). Note that not all
|
67
|
+
# accurev subcommands support the "-fx" option.
|
68
|
+
#
|
69
|
+
def accurev_xml( cmd, *opts )
|
55
70
|
# nativepath_to_filepath is actually generic to native
|
56
71
|
dir = PathConverter.nativepath_to_filepath( @working_dir )
|
57
72
|
dir = File.expand_path( dir )
|
@@ -64,7 +79,8 @@ module RSCM
|
|
64
79
|
Better.popen( cmdline ) do |stdout|
|
65
80
|
output = stdout.read()
|
66
81
|
if @debug
|
67
|
-
@debug_to.puts( "raw
|
82
|
+
@debug_to.puts( "raw>" )
|
83
|
+
@debug_to.puts( output )
|
68
84
|
end
|
69
85
|
begin
|
70
86
|
return REXML::Document.new( AcXMLScrubIO.new( output ) )
|
@@ -75,27 +91,28 @@ module RSCM
|
|
75
91
|
end
|
76
92
|
end
|
77
93
|
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
|
83
|
-
|
94
|
+
#
|
95
|
+
# Execute the given accurev subcommand using +accurev_xml+,
|
96
|
+
# and return an object tree mirroring the structure of the
|
97
|
+
# XML output.
|
98
|
+
#
|
99
|
+
# This uses +XMLMapper+ to build the object tree.
|
100
|
+
#
|
101
|
+
def accurev( cmd, *opts )
|
102
|
+
doc = self.accurev_xml( cmd, opts )
|
84
103
|
if @debug
|
104
|
+
@debug_to.puts( "doc>" )
|
85
105
|
@debug_to.puts( doc )
|
86
106
|
end
|
87
107
|
if doc.elements.size==0
|
88
108
|
raise "Unexpected output from #{cmd}: #{doc}"
|
89
109
|
end
|
90
|
-
|
91
|
-
|
92
|
-
o = mapclass.new( e )
|
93
|
-
yield o if block_given?
|
94
|
-
objs << o
|
95
|
-
end
|
96
|
-
return objs
|
110
|
+
mapper = @xmlmapper.new()
|
111
|
+
return mapper.map( doc.root )
|
97
112
|
end
|
98
113
|
|
114
|
+
# static methods
|
115
|
+
|
99
116
|
# Retrieve this thread's +Command+ instance.
|
100
117
|
#
|
101
118
|
# eg:
|
@@ -120,8 +137,9 @@ module RSCM
|
|
120
137
|
Thread.current[ :RSCM_ACCUREV_COMMAND ] = nil
|
121
138
|
end
|
122
139
|
|
140
|
+
private
|
141
|
+
|
123
142
|
# new() is marked private, use Command.instance().
|
124
|
-
private
|
125
143
|
def new( *args )
|
126
144
|
super(args)
|
127
145
|
end
|
data/lib/rscm/scm/accurev/xml.rb
CHANGED
@@ -1,36 +1,152 @@
|
|
1
1
|
module RSCM; module Accurev; end; end
|
2
2
|
|
3
|
+
require 'rexml/element'
|
4
|
+
|
3
5
|
module RSCM::Accurev
|
4
6
|
|
7
|
+
#
|
8
|
+
# XMLMapper creates an object tree from an XML element and its children.
|
9
|
+
#
|
10
|
+
# For each XML node, it locates a class associated with that node's name,
|
11
|
+
# and builds a new object of that type from the element.
|
12
|
+
#
|
13
|
+
# The nodename-class associations are determined by finding all
|
14
|
+
# classes derived from +RSCM::Accurev::ElementBackedClass+ and checking
|
15
|
+
# each of those classes +element_name+ methods.
|
16
|
+
#
|
17
|
+
class XMLMapper
|
18
|
+
|
19
|
+
# Map of element (tag) names to (ruby) class.
|
20
|
+
attr_accessor :classmap
|
21
|
+
|
22
|
+
def initialize()
|
23
|
+
@classmap = {}
|
24
|
+
ObjectSpace.each_object( Class ) do |k|
|
25
|
+
if k.ancestors.delete( ElementBackedClass ) and k != ElementBackedClass
|
26
|
+
if k.respond_to?( :element_name )
|
27
|
+
@classmap[ k.element_name ] = k
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# Build an object tree from the given REXML element and its children.
|
35
|
+
# The returned object will be a subclass of +ElementBackedClass+.
|
36
|
+
#
|
37
|
+
def map( e )
|
38
|
+
unless @classmap.has_key?( e.name )
|
39
|
+
return nil
|
40
|
+
end
|
41
|
+
o = @classmap[e.name].new( e )
|
42
|
+
e.children.each do |child|
|
43
|
+
if child.kind_of?( REXML::Element )
|
44
|
+
a = self.map( child )
|
45
|
+
unless a.nil?
|
46
|
+
if o.children[ a.class.element_name ].nil?
|
47
|
+
o.children[ a.class.element_name ] = []
|
48
|
+
end
|
49
|
+
o.children[ a.class.element_name ] << a
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
return o
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
# Generic base class for defining typed mirror classes for XML elements.
|
59
|
+
#
|
60
|
+
# A subclass of ElementBackedClass has:
|
61
|
+
#
|
62
|
+
# * A class static +element_name+ method, identifying what
|
63
|
+
# type of XML element it shadows
|
64
|
+
#
|
65
|
+
# * A set of attributes shadowing the XML attributes of its target element
|
66
|
+
#
|
67
|
+
# * A map (+children+) of child elements, keyed by element name
|
68
|
+
#
|
69
|
+
# * A (optional) +text_content+ attribute, populated when the
|
70
|
+
# target element has text subnodes.
|
71
|
+
#
|
5
72
|
class ElementBackedClass
|
73
|
+
|
74
|
+
attr_accessor :children
|
75
|
+
|
6
76
|
def self.element_name( name )
|
7
|
-
|
77
|
+
class << self
|
78
|
+
self
|
79
|
+
end.send( :define_method, "element_name" ) {name}
|
8
80
|
end
|
81
|
+
|
9
82
|
def initialize( element=nil )
|
83
|
+
@children = {}
|
10
84
|
unless element.nil?
|
11
85
|
self.set_from_element(element)
|
12
86
|
end
|
13
87
|
end
|
88
|
+
|
89
|
+
# ebc['foo'] is a synonym for ebc.children['foo']
|
90
|
+
def []( key )
|
91
|
+
return self.children[key]
|
92
|
+
end
|
93
|
+
|
94
|
+
protected
|
95
|
+
# Does the work of calling object setters for each XML attribute.
|
14
96
|
def set_from_element( e )
|
15
97
|
e.attributes.each do |attr, value|
|
16
|
-
|
17
|
-
|
98
|
+
# downcase the attr name for method-happiness
|
99
|
+
# (also hacks around some inconsistent accurev attr names...)
|
100
|
+
mattr = attr.downcase
|
101
|
+
if self.respond_to?( "#{mattr}=" )
|
102
|
+
self.send( "#{mattr}=", value )
|
18
103
|
end
|
19
104
|
end
|
105
|
+
if self.respond_to?( :text_content= ) and ! e.text.nil?
|
106
|
+
self.text_content = e.text
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# Data from the typical AcResponse root node.
|
114
|
+
#
|
115
|
+
class AcResponseData < ElementBackedClass
|
116
|
+
element_name 'AcResponse'
|
117
|
+
attr_accessor :command, :directory
|
118
|
+
|
119
|
+
# Returns this response's error message, or nil if no error detected.
|
120
|
+
def error
|
121
|
+
if self.children['message']
|
122
|
+
zmsg = self.children['message'][0]
|
123
|
+
if zmsg.error and zmsg.error == 'true'
|
124
|
+
return zmsg.text_content
|
125
|
+
end
|
126
|
+
else
|
127
|
+
return nil
|
128
|
+
end
|
20
129
|
end
|
21
130
|
end
|
22
131
|
|
23
|
-
#
|
24
|
-
|
132
|
+
#
|
133
|
+
# Data from "accurev file", "accure update", "accurev stat" commands.
|
134
|
+
# Identifies workspace objects (files, directories, etc).
|
135
|
+
#
|
136
|
+
class ElementData < ElementBackedClass
|
25
137
|
element_name 'element'
|
26
138
|
attr_accessor :location, :status, :dir, :id
|
27
|
-
attr_accessor :elemType, :namedVersion, :
|
139
|
+
attr_accessor :elemType, :namedVersion, :virtual, :real
|
28
140
|
end
|
29
|
-
|
30
|
-
#
|
31
|
-
|
32
|
-
|
33
|
-
|
141
|
+
|
142
|
+
#
|
143
|
+
# Data from "accurev {file,update,stat}" commands.
|
144
|
+
# Streamed status/info messages, usually interleaved with ElementData
|
145
|
+
# nodes.
|
146
|
+
#
|
147
|
+
class MessageData < ElementBackedClass
|
148
|
+
element_name 'message'
|
149
|
+
attr_accessor :error, :text_content
|
34
150
|
end
|
35
|
-
|
151
|
+
|
36
152
|
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
<acResponse
|
2
|
+
command="update"Scanning entire workspace for files touched since last scan - ok
|
3
|
+
>
|
4
|
+
<progress
|
5
|
+
phase="Calculating changes"
|
6
|
+
increment="100"/>
|
7
|
+
<progress
|
8
|
+
phase="results"
|
9
|
+
number="23"/>
|
10
|
+
<message>Would remove "src/java/com/orbitz/dc/service/hc/HcItinerary.java" .
|
11
|
+
</message>
|
12
|
+
<element
|
13
|
+
location="src/java/com/orbitz/dc/service/hc/HcItinerary.java"/>
|
14
|
+
<checkpoint/>
|
15
|
+
<message>Would replace content of "src/java/com/orbitz/dc/core/Pricing.java" .
|
16
|
+
</message>
|
17
|
+
<element
|
18
|
+
location="src/java/com/orbitz/dc/core/Pricing.java"/>
|
19
|
+
<checkpoint/>
|
20
|
+
<message>Would replace content of "src/java/com/orbitz/dc/service/hc/HcSearchRequest.java" .
|
21
|
+
</message>
|
22
|
+
<element
|
23
|
+
location="src/java/com/orbitz/dc/service/hc/HcSearchRequest.java"/>
|
24
|
+
<checkpoint/>
|
25
|
+
<message>Would replace content of "src/java/com/orbitz/dc/service/hc/HcCreateReservationRequest.java" .
|
26
|
+
</message>
|
27
|
+
<element
|
28
|
+
location="src/java/com/orbitz/dc/service/hc/HcCreateReservationRequest.java"/>
|
29
|
+
<checkpoint/>
|
30
|
+
<message>Would replace content of "src/java/com/orbitz/dc/core/HcJourney.java" .
|
31
|
+
</message>
|
32
|
+
<element
|
33
|
+
location="src/java/com/orbitz/dc/core/HcJourney.java"/>
|
34
|
+
<checkpoint/>
|
35
|
+
<message>Would replace content of "src/java/com/orbitz/dc/service/hc/HcCreateReservationResponse.java" .
|
36
|
+
</message>
|
37
|
+
<element
|
38
|
+
location="src/java/com/orbitz/dc/service/hc/HcCreateReservationResponse.java"/>
|
39
|
+
<checkpoint/>
|
40
|
+
<message>Would replace content of "src/java/com/orbitz/dc/service/hc/HcCancelReservationRequest.java" .
|
41
|
+
</message>
|
42
|
+
<element
|
43
|
+
location="src/java/com/orbitz/dc/service/hc/HcCancelReservationRequest.java"/>
|
44
|
+
<checkpoint/>
|
45
|
+
<message>Would replace content of "src/java/com/orbitz/dc/service/hc/HcCancelReservationResponse.java" .
|
46
|
+
</message>
|
47
|
+
<element
|
48
|
+
location="src/java/com/orbitz/dc/service/hc/HcCancelReservationResponse.java"/>
|
49
|
+
<checkpoint/>
|
50
|
+
<message>Would replace content of "src/java/com/orbitz/dc/service/hc/HcModifyReservationResponse.java" .
|
51
|
+
</message>
|
52
|
+
<element
|
53
|
+
location="src/java/com/orbitz/dc/service/hc/HcModifyReservationResponse.java"/>
|
54
|
+
<checkpoint/>
|
55
|
+
<message>Would replace content of "src/java/com/orbitz/dc/service/hc/HcModifyReservationRequest.java" .
|
56
|
+
</message>
|
57
|
+
<element
|
58
|
+
location="src/java/com/orbitz/dc/service/hc/HcModifyReservationRequest.java"/>
|
59
|
+
<checkpoint/>
|
60
|
+
<message>Would replace content of "src/java/com/orbitz/dc/core/RateInfo.java" .
|
61
|
+
</message>
|
62
|
+
<element
|
63
|
+
location="src/java/com/orbitz/dc/core/RateInfo.java"/>
|
64
|
+
<checkpoint/>
|
65
|
+
<message>Would replace content of "src/java/com/orbitz/dc/core/VariableRateInfo.java" .
|
66
|
+
</message>
|
67
|
+
<element
|
68
|
+
location="src/java/com/orbitz/dc/core/VariableRateInfo.java"/>
|
69
|
+
<checkpoint/>
|
70
|
+
<message>Would replace content of "src/java/com/orbitz/dc/core/RATE_CATEGORY.java" .
|
71
|
+
</message>
|
72
|
+
<element
|
73
|
+
location="src/java/com/orbitz/dc/core/RATE_CATEGORY.java"/>
|
74
|
+
<checkpoint/>
|
75
|
+
<message>Would replace content of "src/java/com/orbitz/dc/core/RATE_COVERAGE.java" .
|
76
|
+
</message>
|
77
|
+
<element
|
78
|
+
location="src/java/com/orbitz/dc/core/RATE_COVERAGE.java"/>
|
79
|
+
<checkpoint/>
|
80
|
+
<message>Would replace content of "src/java/com/orbitz/dc/core/FlatRateInfo.java" .
|
81
|
+
</message>
|
82
|
+
<element
|
83
|
+
location="src/java/com/orbitz/dc/core/FlatRateInfo.java"/>
|
84
|
+
<checkpoint/>
|
85
|
+
<message>Would replace content of "src/java/com/orbitz/dc/core/HcItinerary.java" .
|
86
|
+
</message>
|
87
|
+
<element
|
88
|
+
location="src/java/com/orbitz/dc/core/HcItinerary.java"/>
|
89
|
+
<checkpoint/>
|
90
|
+
<message>Would replace content of "src/java/com/orbitz/dc/service/hc/HcSearch.java" .
|
91
|
+
</message>
|
92
|
+
<element
|
93
|
+
location="src/java/com/orbitz/dc/service/hc/HcSearch.java"/>
|
94
|
+
<checkpoint/>
|
95
|
+
<message>Would replace content of "src/java/com/orbitz/dc/service/hc/HcCreateReservation.java" .
|
96
|
+
</message>
|
97
|
+
<element
|
98
|
+
location="src/java/com/orbitz/dc/service/hc/HcCreateReservation.java"/>
|
99
|
+
<checkpoint/>
|
100
|
+
<message>Would replace content of "src/java/com/orbitz/dc/service/hc/HcModifyReservation.java" .
|
101
|
+
</message>
|
102
|
+
<element
|
103
|
+
location="src/java/com/orbitz/dc/service/hc/HcModifyReservation.java"/>
|
104
|
+
<checkpoint/>
|
105
|
+
<message>Would replace content of "src/java/com/orbitz/dc/service/hc/HcCancelReservation.java" .
|
106
|
+
</message>
|
107
|
+
<element
|
108
|
+
location="src/java/com/orbitz/dc/service/hc/HcCancelReservation.java"/>
|
109
|
+
<checkpoint/>
|
110
|
+
<message>Would replace content of "src/java/com/orbitz/dc/service/hc/HcRetrieveItinerary.java" .
|
111
|
+
</message>
|
112
|
+
<element
|
113
|
+
location="src/java/com/orbitz/dc/service/hc/HcRetrieveItinerary.java"/>
|
114
|
+
<checkpoint/>
|
115
|
+
<message>Would replace content of "src/java/com/orbitz/dc/service/hc/HcRetrieveItineraryRequest.java" .
|
116
|
+
</message>
|
117
|
+
<element
|
118
|
+
location="src/java/com/orbitz/dc/service/hc/HcRetrieveItineraryRequest.java"/>
|
119
|
+
<checkpoint/>
|
120
|
+
<message>Would replace content of "src/java/com/orbitz/dc/service/hc/HcRetrieveItineraryResponse.java" .
|
121
|
+
</message>
|
122
|
+
<element
|
123
|
+
location="src/java/com/orbitz/dc/service/hc/HcRetrieveItineraryResponse.java"/>
|
124
|
+
<checkpoint/>
|
125
|
+
</acResponse>
|
@@ -0,0 +1,147 @@
|
|
1
|
+
<acResponse
|
2
|
+
command="update"Scanning entire workspace for files touched since last scan - ok
|
3
|
+
>
|
4
|
+
<progress
|
5
|
+
phase="Calculating changes"
|
6
|
+
increment="100"/>
|
7
|
+
<progress
|
8
|
+
phase="results"
|
9
|
+
number="23"/>
|
10
|
+
<message>Removing "src/java/com/orbitz/dc/service/hc/HcItinerary.java" .
|
11
|
+
</message>
|
12
|
+
<element
|
13
|
+
location="src/java/com/orbitz/dc/service/hc/HcItinerary.java"/>
|
14
|
+
<checkpoint/>
|
15
|
+
<message>Content (1 K) of "src/java/com/orbitz/dc/core/Pricing.java" - ok
|
16
|
+
</message>
|
17
|
+
<element
|
18
|
+
location="src/java/com/orbitz/dc/core/Pricing.java"
|
19
|
+
size="1398"/>
|
20
|
+
<checkpoint/>
|
21
|
+
<message>Content (1 K) of "src/java/com/orbitz/dc/service/hc/HcSearchRequest.java" - ok
|
22
|
+
</message>
|
23
|
+
<element
|
24
|
+
location="src/java/com/orbitz/dc/service/hc/HcSearchRequest.java"
|
25
|
+
size="793"/>
|
26
|
+
<checkpoint/>
|
27
|
+
<message>Content (1 K) of "src/java/com/orbitz/dc/service/hc/HcCreateReservationRequest.java" - ok
|
28
|
+
</message>
|
29
|
+
<element
|
30
|
+
location="src/java/com/orbitz/dc/service/hc/HcCreateReservationRequest.java"
|
31
|
+
size="1712"/>
|
32
|
+
<checkpoint/>
|
33
|
+
<message>Content (3 K) of "src/java/com/orbitz/dc/core/HcJourney.java" - ok
|
34
|
+
</message>
|
35
|
+
<element
|
36
|
+
location="src/java/com/orbitz/dc/core/HcJourney.java"
|
37
|
+
size="3846"/>
|
38
|
+
<checkpoint/>
|
39
|
+
<message>Content (1 K) of "src/java/com/orbitz/dc/service/hc/HcCreateReservationResponse.java" - ok
|
40
|
+
</message>
|
41
|
+
<element
|
42
|
+
location="src/java/com/orbitz/dc/service/hc/HcCreateReservationResponse.java"
|
43
|
+
size="849"/>
|
44
|
+
<checkpoint/>
|
45
|
+
<message>Content (3 K) of "src/java/com/orbitz/dc/service/hc/HcCancelReservationRequest.java" - ok
|
46
|
+
</message>
|
47
|
+
<element
|
48
|
+
location="src/java/com/orbitz/dc/service/hc/HcCancelReservationRequest.java"
|
49
|
+
size="3046"/>
|
50
|
+
<checkpoint/>
|
51
|
+
<message>Content (1 K) of "src/java/com/orbitz/dc/service/hc/HcCancelReservationResponse.java" - ok
|
52
|
+
</message>
|
53
|
+
<element
|
54
|
+
location="src/java/com/orbitz/dc/service/hc/HcCancelReservationResponse.java"
|
55
|
+
size="756"/>
|
56
|
+
<checkpoint/>
|
57
|
+
<message>Content (1 K) of "src/java/com/orbitz/dc/service/hc/HcModifyReservationResponse.java" - ok
|
58
|
+
</message>
|
59
|
+
<element
|
60
|
+
location="src/java/com/orbitz/dc/service/hc/HcModifyReservationResponse.java"
|
61
|
+
size="849"/>
|
62
|
+
<checkpoint/>
|
63
|
+
<message>Content (1 K) of "src/java/com/orbitz/dc/service/hc/HcModifyReservationRequest.java" - ok
|
64
|
+
</message>
|
65
|
+
<element
|
66
|
+
location="src/java/com/orbitz/dc/service/hc/HcModifyReservationRequest.java"
|
67
|
+
size="1806"/>
|
68
|
+
<checkpoint/>
|
69
|
+
<message>Content (3 K) of "src/java/com/orbitz/dc/core/RateInfo.java" - ok
|
70
|
+
</message>
|
71
|
+
<element
|
72
|
+
location="src/java/com/orbitz/dc/core/RateInfo.java"
|
73
|
+
size="3495"/>
|
74
|
+
<checkpoint/>
|
75
|
+
<message>Content (2 K) of "src/java/com/orbitz/dc/core/VariableRateInfo.java" - ok
|
76
|
+
</message>
|
77
|
+
<element
|
78
|
+
location="src/java/com/orbitz/dc/core/VariableRateInfo.java"
|
79
|
+
size="2523"/>
|
80
|
+
<checkpoint/>
|
81
|
+
<message>Content (2 K) of "src/java/com/orbitz/dc/core/RATE_CATEGORY.java" - ok
|
82
|
+
</message>
|
83
|
+
<element
|
84
|
+
location="src/java/com/orbitz/dc/core/RATE_CATEGORY.java"
|
85
|
+
size="2513"/>
|
86
|
+
<checkpoint/>
|
87
|
+
<message>Content (2 K) of "src/java/com/orbitz/dc/core/RATE_COVERAGE.java" - ok
|
88
|
+
</message>
|
89
|
+
<element
|
90
|
+
location="src/java/com/orbitz/dc/core/RATE_COVERAGE.java"
|
91
|
+
size="2537"/>
|
92
|
+
<checkpoint/>
|
93
|
+
<message>Content (1 K) of "src/java/com/orbitz/dc/core/FlatRateInfo.java" - ok
|
94
|
+
</message>
|
95
|
+
<element
|
96
|
+
location="src/java/com/orbitz/dc/core/FlatRateInfo.java"
|
97
|
+
size="975"/>
|
98
|
+
<checkpoint/>
|
99
|
+
<message>Content (2 K) of "src/java/com/orbitz/dc/core/HcItinerary.java" - ok
|
100
|
+
</message>
|
101
|
+
<element
|
102
|
+
location="src/java/com/orbitz/dc/core/HcItinerary.java"
|
103
|
+
size="2707"/>
|
104
|
+
<checkpoint/>
|
105
|
+
<message>Content (1 K) of "src/java/com/orbitz/dc/service/hc/HcSearch.java" - ok
|
106
|
+
</message>
|
107
|
+
<element
|
108
|
+
location="src/java/com/orbitz/dc/service/hc/HcSearch.java"
|
109
|
+
size="1123"/>
|
110
|
+
<checkpoint/>
|
111
|
+
<message>Content (1 K) of "src/java/com/orbitz/dc/service/hc/HcCreateReservation.java" - ok
|
112
|
+
</message>
|
113
|
+
<element
|
114
|
+
location="src/java/com/orbitz/dc/service/hc/HcCreateReservation.java"
|
115
|
+
size="1146"/>
|
116
|
+
<checkpoint/>
|
117
|
+
<message>Content (1 K) of "src/java/com/orbitz/dc/service/hc/HcModifyReservation.java" - ok
|
118
|
+
</message>
|
119
|
+
<element
|
120
|
+
location="src/java/com/orbitz/dc/service/hc/HcModifyReservation.java"
|
121
|
+
size="1156"/>
|
122
|
+
<checkpoint/>
|
123
|
+
<message>Content (1 K) of "src/java/com/orbitz/dc/service/hc/HcCancelReservation.java" - ok
|
124
|
+
</message>
|
125
|
+
<element
|
126
|
+
location="src/java/com/orbitz/dc/service/hc/HcCancelReservation.java"
|
127
|
+
size="1150"/>
|
128
|
+
<checkpoint/>
|
129
|
+
<message>Content (1 K) of "src/java/com/orbitz/dc/service/hc/HcRetrieveItinerary.java" - ok
|
130
|
+
</message>
|
131
|
+
<element
|
132
|
+
location="src/java/com/orbitz/dc/service/hc/HcRetrieveItinerary.java"
|
133
|
+
size="1150"/>
|
134
|
+
<checkpoint/>
|
135
|
+
<message>Content (1 K) of "src/java/com/orbitz/dc/service/hc/HcRetrieveItineraryRequest.java" - ok
|
136
|
+
</message>
|
137
|
+
<element
|
138
|
+
location="src/java/com/orbitz/dc/service/hc/HcRetrieveItineraryRequest.java"
|
139
|
+
size="1477"/>
|
140
|
+
<checkpoint/>
|
141
|
+
<message>Content (1 K) of "src/java/com/orbitz/dc/service/hc/HcRetrieveItineraryResponse.java" - ok
|
142
|
+
</message>
|
143
|
+
<element
|
144
|
+
location="src/java/com/orbitz/dc/service/hc/HcRetrieveItineraryResponse.java"
|
145
|
+
size="756"/>
|
146
|
+
<checkpoint/>
|
147
|
+
</acResponse>
|
data/test/t_api.rb
CHANGED
@@ -9,7 +9,7 @@ class AccurevAPITest < Test::Unit::TestCase
|
|
9
9
|
def test_ac_files()
|
10
10
|
Command.instance do |cmd|
|
11
11
|
cmd.working_dir = "test"
|
12
|
-
cmd.
|
12
|
+
cmd.accurev_bin = "./acreplay.rb eg/ac-files.xml"
|
13
13
|
end
|
14
14
|
api = API.new( ".", "test-bogus-depot", "test-bogus-depot-0-impl" )
|
15
15
|
# test array returns
|
@@ -28,11 +28,49 @@ class AccurevAPITest < Test::Unit::TestCase
|
|
28
28
|
assert_equal( count, 23 )
|
29
29
|
end
|
30
30
|
|
31
|
-
def
|
31
|
+
def test_update_stale()
|
32
32
|
Command.instance do |cmd|
|
33
|
-
cmd.
|
34
|
-
|
33
|
+
cmd.accurev_bin = "./acreplay.rb eg/update-stale.xml"
|
34
|
+
end
|
35
|
+
api = API.new( "test", "test-bogus-depot", "test-bogus-depot-0-impl" )
|
36
|
+
begin
|
37
|
+
u_elements = api.update()
|
38
|
+
flunk( "Simulated update with stale data should throw exception" )
|
39
|
+
rescue StaleWorkspaceException => e
|
40
|
+
assert( true, "Caught expected exception" )
|
41
|
+
assert( e.error_msg =~ /workspace have been modified/ )
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_update_nochanges()
|
46
|
+
Command.instance do |cmd|
|
47
|
+
cmd.accurev_bin = "./acreplay.rb eg/update-nochanges.xml"
|
48
|
+
end
|
49
|
+
api = API.new( "test", "test-bogus-depot", "test-bogus-depot-0-impl" )
|
50
|
+
u_elements = api.update()
|
51
|
+
assert_not_nil( u_elements )
|
52
|
+
assert( u_elements.size == 0 )
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_update_newwksp()
|
56
|
+
Command.instance do |cmd|
|
57
|
+
cmd.accurev_bin = "./acreplay.rb eg/update-newwksp.xml"
|
58
|
+
end
|
59
|
+
api = API.new( "test", "test-bogus-depot", "test-bogus-depot-0-impl" )
|
60
|
+
u_elements = api.update()
|
61
|
+
assert_not_nil( u_elements )
|
62
|
+
assert_equal( 44, u_elements.length )
|
63
|
+
u_elements.each do |location|
|
64
|
+
# api.update returns a list of relative filenames
|
65
|
+
assert( location =~ /^\// )
|
66
|
+
end
|
67
|
+
# test yield and array return XXX
|
68
|
+
updated = 0
|
69
|
+
api.update().each do |location|
|
70
|
+
updated += 1
|
71
|
+
assert( location =~ /^\// )
|
35
72
|
end
|
73
|
+
assert_equal( 44, updated )
|
36
74
|
end
|
37
75
|
|
38
76
|
end
|
data/test/t_command.rb
CHANGED
@@ -13,7 +13,7 @@ class CommandTest < Test::Unit::TestCase
|
|
13
13
|
s = cmd.accurev_cmdline( "foo", "bar" )
|
14
14
|
assert_equal( "accurev foo bar", s )
|
15
15
|
|
16
|
-
cmd.
|
16
|
+
cmd.accurev_bin = "xyzzy"
|
17
17
|
|
18
18
|
s = cmd.accurev_cmdline( "foo", "bar" )
|
19
19
|
assert_equal( "xyzzy foo bar", s )
|
@@ -24,22 +24,18 @@ class CommandTest < Test::Unit::TestCase
|
|
24
24
|
def test_a_e
|
25
25
|
cmd = Command.instance
|
26
26
|
cmd.working_dir = "test"
|
27
|
-
|
28
|
-
|
29
|
-
cmd.
|
27
|
+
cmd.debug = true
|
28
|
+
cmd.debug_to = File.open( "/tmp/testing.log", "w" )
|
29
|
+
cmd.accurev_bin = "./acreplay.rb eg/update-newwksp.xml"
|
30
30
|
# test listy output
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
acresponse = cmd.accurev( "files" )
|
32
|
+
assert_not_nil( acresponse )
|
33
|
+
assert( acresponse.kind_of?( AcResponseData ) )
|
34
|
+
assert( acresponse['element'].size == 44 )
|
35
|
+
assert( acresponse['message'].size == 44 )
|
36
|
+
acresponse['element'].each do |e|
|
37
|
+
assert( e.kind_of?( ElementData ) )
|
35
38
|
end
|
36
|
-
# test yieldy output
|
37
|
-
got_any = false
|
38
|
-
cmd.accurev_elements( RSCM::Accurev::StatData, "files" ) do |fd|
|
39
|
-
got_any = true
|
40
|
-
assert( fd.respond_to?( :location ) )
|
41
|
-
end
|
42
|
-
assert( got_any )
|
43
39
|
Command.discard
|
44
40
|
end
|
45
41
|
|
data/test/t_xmlmapper.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'test/unit'
|
3
|
+
require 'stringio'
|
4
|
+
require 'rexml/document'
|
5
|
+
require 'rscm/scm/accurev/xml'
|
6
|
+
include REXML
|
7
|
+
include RSCM::Accurev
|
8
|
+
|
9
|
+
class ReadQueue < ElementBackedClass
|
10
|
+
element_name 'readqueue'
|
11
|
+
attr_accessor :owner
|
12
|
+
end
|
13
|
+
|
14
|
+
class Book < ElementBackedClass
|
15
|
+
element_name 'book'
|
16
|
+
attr_accessor :title, :author
|
17
|
+
end
|
18
|
+
|
19
|
+
class Paper < ElementBackedClass
|
20
|
+
element_name 'paper'
|
21
|
+
attr_accessor :uri
|
22
|
+
end
|
23
|
+
|
24
|
+
class Note < ElementBackedClass
|
25
|
+
element_name 'note'
|
26
|
+
attr_accessor :text, :text_content
|
27
|
+
end
|
28
|
+
|
29
|
+
INPUT = <<-EOI
|
30
|
+
<?xml version="1.0"?>
|
31
|
+
<readqueue owner="gdf">
|
32
|
+
<book title="Iron Council" author="China Mieville" />
|
33
|
+
<paper uri="http://svk.elixus.org?SVKTutorial">
|
34
|
+
<note text="re-read" />
|
35
|
+
</paper>
|
36
|
+
<book title="Someone Comes to Town, Someone Leaves Town"
|
37
|
+
author="Cory Doctorow" />
|
38
|
+
<book title="Concurrent Programming in Java" author="Doug Lea">
|
39
|
+
<note>Need Brains</note>
|
40
|
+
</book>
|
41
|
+
</readqueue>
|
42
|
+
EOI
|
43
|
+
|
44
|
+
class XMLMapperTest < Test::Unit::TestCase
|
45
|
+
def testmap
|
46
|
+
d = Document.new( StringIO.new( INPUT ) )
|
47
|
+
assert_equal( "readqueue", d.root.name )
|
48
|
+
mapper = XMLMapper.new
|
49
|
+
o = mapper.map( d.root )
|
50
|
+
assert( o.kind_of?( ElementBackedClass ) )
|
51
|
+
assert( o.kind_of?( ReadQueue ) )
|
52
|
+
assert_equal( 3, o.children['book'].length )
|
53
|
+
assert_equal( 1, o.children['paper'].length )
|
54
|
+
paper = o.children['paper'][0]
|
55
|
+
assert( paper.kind_of?( Paper ) )
|
56
|
+
assert_equal( "paper", paper.class.element_name )
|
57
|
+
assert_equal( "http://svk.elixus.org?SVKTutorial", paper.uri )
|
58
|
+
assert_equal( 1, paper.children['note'].length )
|
59
|
+
note = paper.children['note'][0]
|
60
|
+
assert_equal( "re-read", note.text )
|
61
|
+
b = nil
|
62
|
+
o.children['book'].each do |book|
|
63
|
+
b = book if book.author == "Doug Lea"
|
64
|
+
end
|
65
|
+
assert_equal( "Concurrent Programming in Java", b.title )
|
66
|
+
note = b.children['note'][0]
|
67
|
+
assert( note.text.nil? )
|
68
|
+
assert_equal( "Need Brains", note.text_content )
|
69
|
+
|
70
|
+
# test []
|
71
|
+
assert_equal( 3, o['book'].length )
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: rscm-accurev
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2005-08-
|
6
|
+
version: 0.0.3
|
7
|
+
date: 2005-08-15 00:00:00 -05:00
|
8
8
|
summary: "RSCM::Accurev - RSCM API for Accurev"
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -33,6 +33,7 @@ files:
|
|
33
33
|
- bumprelease.sh
|
34
34
|
- lib
|
35
35
|
- LICENSE
|
36
|
+
- pkg
|
36
37
|
- Rakefile
|
37
38
|
- README
|
38
39
|
- test
|
@@ -42,7 +43,6 @@ files:
|
|
42
43
|
- lib/rscm/accurev.rb
|
43
44
|
- lib/rscm/scm
|
44
45
|
- lib/rscm/scm/accurev
|
45
|
-
- "lib/rscm/scm/accurev/#api.rb#"
|
46
46
|
- lib/rscm/scm/accurev/api.rb
|
47
47
|
- lib/rscm/scm/accurev/command.rb
|
48
48
|
- lib/rscm/scm/accurev/filterio.rb
|
@@ -54,9 +54,14 @@ files:
|
|
54
54
|
- test/t_filterio.rb
|
55
55
|
- test/t_load.rb
|
56
56
|
- test/t_scrubio.rb
|
57
|
+
- test/t_xmlmapper.rb
|
57
58
|
- test/eg/ac-files.xml
|
59
|
+
- test/eg/update-i-nochanges.xml
|
60
|
+
- test/eg/update-i-updates.xml
|
58
61
|
- test/eg/update-newwksp.xml
|
62
|
+
- test/eg/update-nochanges.xml
|
59
63
|
- test/eg/update-stale.xml
|
64
|
+
- test/eg/update-updates.xml
|
60
65
|
test_files: []
|
61
66
|
rdoc_options:
|
62
67
|
- "--line-numbers"
|
@@ -1,226 +0,0 @@
|
|
1
|
-
# -*- ruby -*-
|
2
|
-
require 'rubygems'
|
3
|
-
require 'rscm/base'
|
4
|
-
require 'rscm/path_converter'
|
5
|
-
require 'rexml/document'
|
6
|
-
require 'rscm/scm/accurev/xml'
|
7
|
-
require 'rscm/scm/accurev/filterio'
|
8
|
-
require 'rscm/scm/accurev/command'
|
9
|
-
|
10
|
-
module RSCM
|
11
|
-
module Accurev; end
|
12
|
-
end
|
13
|
-
|
14
|
-
module RSCM::Accurev
|
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/).
|
22
|
-
#
|
23
|
-
# Requires an accurev cli executable on the path, and the correct
|
24
|
-
# environment for ac server/principal/password.
|
25
|
-
#
|
26
|
-
class API < RSCM::Base
|
27
|
-
register self
|
28
|
-
|
29
|
-
ann :description => "Accurev Depot"
|
30
|
-
attr_accessor :depot
|
31
|
-
|
32
|
-
ann :description => "Backing Stream (autodetected)"
|
33
|
-
attr_accessor :backing_stream
|
34
|
-
|
35
|
-
ann :description => "Workspace Stream"
|
36
|
-
attr_accessor :workspace_stream
|
37
|
-
|
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
|
55
|
-
@checkout_dir = checkout_dir
|
56
|
-
@workspace_stream = workspace_stream
|
57
|
-
@backing_stream = nil # will be pulled from files cmd output
|
58
|
-
end
|
59
|
-
|
60
|
-
def name()
|
61
|
-
return "Accurev"
|
62
|
-
end
|
63
|
-
|
64
|
-
# Accurev operations are atomic:
|
65
|
-
def transactional?
|
66
|
-
return true
|
67
|
-
end
|
68
|
-
|
69
|
-
# "Adds +relative_filename+ to the working copy."
|
70
|
-
def add( relative_filename )
|
71
|
-
raise "XXX implement me"
|
72
|
-
end
|
73
|
-
|
74
|
-
def edit( relative_filename )
|
75
|
-
# NOP - not required for ac
|
76
|
-
end
|
77
|
-
|
78
|
-
# "Returns a Revisions object for the period specified ... (inclusive)."
|
79
|
-
def revisions( from_identifier, to_identifier=Time.infinity )
|
80
|
-
raise "XXX implement me"
|
81
|
-
end
|
82
|
-
|
83
|
-
# default impl depends on a correct impl of revisions()
|
84
|
-
# def uptodate?( identifier=nil )
|
85
|
-
#
|
86
|
-
# end
|
87
|
-
|
88
|
-
# def checked_out? - base
|
89
|
-
|
90
|
-
# accurev actually does have triggers, but I haven't implemented that yet
|
91
|
-
def supports_trigger?
|
92
|
-
false
|
93
|
-
end
|
94
|
-
|
95
|
-
# def diff() XXX
|
96
|
-
|
97
|
-
|
98
|
-
# --- ac specific
|
99
|
-
|
100
|
-
def ac_files( relative_path )
|
101
|
-
cmd = Command.instance
|
102
|
-
# there must be a better way to do this yield->yield loopage
|
103
|
-
obj = []
|
104
|
-
cmd.accurev_elements( StatData, "files", relative_path ) do |fd|
|
105
|
-
yield fd if block_given?
|
106
|
-
obj << fd
|
107
|
-
end
|
108
|
-
return obj
|
109
|
-
end
|
110
|
-
|
111
|
-
def ac_keep( files=[], message="" )
|
112
|
-
raise "XXX implement me"
|
113
|
-
end
|
114
|
-
|
115
|
-
def ac_promote( files=[], message="" )
|
116
|
-
raise "XXX implement me"
|
117
|
-
end
|
118
|
-
|
119
|
-
def ac_update( relative_path="." )
|
120
|
-
d = accurev( "update", relative_path )
|
121
|
-
if xxx_error_stale
|
122
|
-
raise StaleWorkspaceError.new( "#{relative_path} is stale -- keep/anchor all changes and re-update" )
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
def ac_purge( files=[] )
|
127
|
-
raise "XXX implement me"
|
128
|
-
end
|
129
|
-
|
130
|
-
def ac_revert( files=[] )
|
131
|
-
raise "XXX implement me"
|
132
|
-
end
|
133
|
-
|
134
|
-
def ac_move( current_file, new_file )
|
135
|
-
raise "XXX implement me"
|
136
|
-
end
|
137
|
-
|
138
|
-
# ac info: shows eg, backing stream
|
139
|
-
# but doesn't support -fx!
|
140
|
-
|
141
|
-
# ac mkws
|
142
|
-
# -b orbitz-host-gt3-0-impl
|
143
|
-
# -w orbitz-host-gt3-0-impl-test2_gfast
|
144
|
-
# -l `pwd`
|
145
|
-
# - does not support fx (argh!@)
|
146
|
-
# - does not pop
|
147
|
-
#
|
148
|
-
|
149
|
-
# diff: /usr/local/bin/acdiff (!) --fx
|
150
|
-
# (after an ac cat on the backed file)
|
151
|
-
# (eg, no in-process diffing ala cvs diff)
|
152
|
-
# lists modified lines in xml
|
153
|
-
|
154
|
-
# checkout():
|
155
|
-
# "Checks out or updates[!] contents from a central SCM
|
156
|
-
# to +checkout_dir+ - a local working copy."
|
157
|
-
#
|
158
|
-
# "The +to_identifier+ parameter may be optionally specified to
|
159
|
-
# obtain files up to a particular time or label."
|
160
|
-
#
|
161
|
-
# For accurev, this:
|
162
|
-
# * checks to see if @checkout_dir exists and appears checked out.
|
163
|
-
# If it's already checked out, this calls update().
|
164
|
-
# * otherwise, this creates a new workspace stream and populates it
|
165
|
-
# at @checkout_dir.
|
166
|
-
#
|
167
|
-
# Unknown: support for +to_identifier+ (esp for update)?
|
168
|
-
#
|
169
|
-
# This method yields files in the workspace and doesn't need to be
|
170
|
-
# overridden.
|
171
|
-
# The checkout_silent() method does the actual work.
|
172
|
-
#
|
173
|
-
# Only yields files, not directories
|
174
|
-
def checkout( to_identifier=Time.infinite )
|
175
|
-
co = PathConverter.nativepath_to_filepath( @checkout_dir )
|
176
|
-
unless File.exists?( co )
|
177
|
-
puts "> creating new workspace..."
|
178
|
-
if @backing_stream.nil?
|
179
|
-
raise "Backing stream must be set"
|
180
|
-
end
|
181
|
-
if @workspace_stream.nil?
|
182
|
-
raise "Workspace stream must be set"
|
183
|
-
end
|
184
|
-
mkws_out = self.accurev_nofx( "mkws",
|
185
|
-
"-b", @backing_stream,
|
186
|
-
"-w", @workspace_stream,
|
187
|
-
"-l", co )
|
188
|
-
# sucks:
|
189
|
-
if ( mkws_out =~ /already exists/ )
|
190
|
-
raise AccurevException.new( mkws_out )
|
191
|
-
end
|
192
|
-
end
|
193
|
-
puts "> Updating workspace.."
|
194
|
-
self.update( to_identifier )
|
195
|
-
end
|
196
|
-
|
197
|
-
def update( to_identifier=Time.infinite )
|
198
|
-
co = PathConverter.nativepath_to_filepath( @checkout_dir )
|
199
|
-
unless File.exists?( co )
|
200
|
-
raise AccurevException.new( "Workspace does not exist!" )
|
201
|
-
end
|
202
|
-
updated = []
|
203
|
-
with_working_dir( co ) do
|
204
|
-
# XXX Command...
|
205
|
-
accurev_elements( UpdateData, "update" ) do |up|
|
206
|
-
yield up.location
|
207
|
-
updated << up.location
|
208
|
-
end
|
209
|
-
end
|
210
|
-
return updated
|
211
|
-
end
|
212
|
-
|
213
|
-
|
214
|
-
# --- internals
|
215
|
-
|
216
|
-
private
|
217
|
-
|
218
|
-
# Takes a status flags line (eg, "(modified)(kept)")
|
219
|
-
# and returns a list of status flags.
|
220
|
-
def map_status( status_line )
|
221
|
-
l = status_line.split( " " ).map {|x| x.trim}
|
222
|
-
end
|
223
|
-
|
224
|
-
end
|
225
|
-
|
226
|
-
end
|