rscm-accurev 0.0.2 → 0.0.3
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.
- 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
|