P4Ruby-mingwx86 2014.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/P4.rb +589 -0
  2. data/lib/P4.so +0 -0
  3. metadata +47 -0
@@ -0,0 +1,589 @@
1
+ #*******************************************************************************
2
+ # Copyright (c) 2001-2008, Perforce Software, Inc. All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+ #
7
+ # 1. Redistributions of source code must retain the above copyright
8
+ # notice, this list of conditions and the following disclaimer.
9
+ #
10
+ # 2. Redistributions in binary form must reproduce the above copyright
11
+ # notice, this list of conditions and the following disclaimer in the
12
+ # documentation and/or other materials provided with the distribution.
13
+ #
14
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
+ # ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY
18
+ # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21
+ # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
+ #*******************************************************************************
25
+
26
+ #*******************************************************************************
27
+ #* Ruby interface to the Perforce SCM System
28
+ #*******************************************************************************
29
+
30
+
31
+ #*******************************************************************************
32
+ #* P4 class
33
+ #*******************************************************************************
34
+
35
+ #
36
+ # Get the bulk of the definition of the P4 class from the API interface
37
+ #
38
+ require "P4.so"
39
+
40
+ #
41
+ # Add the extra's written purely in ruby.
42
+ #
43
+ class P4
44
+
45
+ #
46
+ # Named constants for the exception levels. Note they are cumulative,
47
+ # so RAISE_ALL includes RAISE_ERRORS (as you'd expect).
48
+ #
49
+ RAISE_NONE = 0
50
+ RAISE_ERRORS = 1
51
+ RAISE_ALL = 2
52
+
53
+ #
54
+ # Named values for merge actions. Values taken from clientmerge.h in
55
+ # the Perforce API
56
+ #
57
+ MERGE_SKIP = 1
58
+ MERGE_ACCEPT_MERGED = 2
59
+ MERGE_ACCEPT_EDIT = 3
60
+ MERGE_ACCEPT_THEIRS = 4
61
+ MERGE_ACCEPT_YOURS = 5
62
+
63
+ # Named values for generic error codes returned by
64
+ # P4::Message#generic
65
+
66
+
67
+ EV_NONE = 0 # misc
68
+
69
+ # The fault of the user
70
+
71
+ EV_USAGE = 0x01 # request not consistent with dox
72
+ EV_UNKNOWN = 0x02 # using unknown entity
73
+ EV_CONTEXT = 0x03 # using entity in wrong context
74
+ EV_ILLEGAL = 0x04 # trying to do something you can't
75
+ EV_NOTYET = 0x05 # something must be corrected first
76
+ EV_PROTECT = 0x06 # protections prevented operation
77
+
78
+ # No fault at all
79
+
80
+ EV_EMPTY = 0x11 # action returned empty results
81
+
82
+ # not the fault of the user
83
+
84
+ EV_FAULT = 0x21 # inexplicable program fault
85
+ EV_CLIENT = 0x22 # client side program errors
86
+ EV_ADMIN = 0x23 # server administrative action required
87
+ EV_CONFIG = 0x24 # client configuration inadequate
88
+ EV_UPGRADE = 0x25 # client or server too old to interact
89
+ EV_COMM = 0x26 # communications error
90
+ EV_TOOBIG = 0x27 # not even Perforce can handle this much
91
+
92
+ # Named values for error severities returned by
93
+ # P4::Message#severity
94
+ E_EMPTY = 0 # nothing yet
95
+ E_INFO = 1 # something good happened
96
+ E_WARN = 2 # something not good happened
97
+ E_FAILED = 3 # user did something wrong
98
+ E_FATAL = 4 # system broken -- nothing can continue
99
+
100
+ # OutputHandler return values constants
101
+
102
+ REPORT = 0
103
+ HANDLED = 1
104
+ CANCEL = 2
105
+
106
+ def method_missing( m, *a )
107
+
108
+ # Generic run_* methods
109
+ if ( m.to_s =~ /^run_(.*)/ )
110
+ return self.run( $1, a )
111
+
112
+ # Generic fetch_* methods
113
+ elsif ( m.to_s =~ /^fetch_(.*)/ )
114
+ return self.run( $1, "-o", a ).shift
115
+
116
+ # Generic save_* methods
117
+ elsif ( m.to_s =~ /^save_(.*)/ )
118
+ if ( a.length == 0 )
119
+ raise( P4Exception, "Method P4##{m.to_s} requires an argument", caller)
120
+ end
121
+ self.input = a.shift
122
+ return self.run( $1, "-i", a )
123
+
124
+ # Generic delete_* methods
125
+ elsif ( m.to_s =~ /^delete_(.*)/ )
126
+ if ( a.length == 0 )
127
+ raise( P4Exception, "Method P4##{m.to_s} requires an argument", caller)
128
+ end
129
+ return self.run( $1, "-d", a )
130
+
131
+ # Generic parse_* methods
132
+ elsif ( m.to_s == "parse_forms" )
133
+ raise( NoMethodError, "undefined method 'P4#parse_forms'", caller )
134
+ elsif ( m.to_s =~ /^parse_(.*)/ )
135
+ if ( a.length != 1 )
136
+ raise( P4Exception, "Method P4##{m.to_s} requires an argument", caller)
137
+ end
138
+ return self.parse_spec( $1, a.shift )
139
+
140
+ # Generic format_* methods
141
+ elsif ( m.to_s =~ /^format_(.*)/ )
142
+ if ( a.length != 1 )
143
+ raise( P4Exception, "Method P4##{m.to_s} requires an argument", caller)
144
+ end
145
+ return self.format_spec( $1, a.shift )
146
+
147
+ # That's all folks!
148
+ else
149
+ raise NameError, "No such method #{m.to_s} in class P4", caller
150
+ end
151
+ end
152
+
153
+ #
154
+ # Simple interface for submitting. If any argument is a Hash, (or subclass
155
+ # thereof - like P4::Spec), then it will be assumed to contain the change
156
+ # form. All other arguments are passed on to the server unchanged.
157
+ #
158
+ def run_submit( *args )
159
+ form = nil
160
+ nargs = args.flatten.collect do
161
+ |a|
162
+ if( a.kind_of?( Hash ) )
163
+ form = a
164
+ nil
165
+ else
166
+ a
167
+ end
168
+ end.compact
169
+
170
+ if( form )
171
+ self.input = form
172
+ nargs.push( "-i" )
173
+ end
174
+ return self.run( "submit", nargs )
175
+ end
176
+
177
+ #
178
+ # Simple interface for shelving. Same rules as for submit apply
179
+
180
+ def run_shelve( *args )
181
+ form = nil
182
+ nargs = args.flatten.collect do
183
+ |a|
184
+ if( a.kind_of?( Hash ) )
185
+ form = a
186
+ nil
187
+ else
188
+ a
189
+ end
190
+ end.compact
191
+
192
+ if( form )
193
+ self.input = form
194
+ nargs.push( "-i" )
195
+ end
196
+ return self.run( "shelve", nargs )
197
+ end
198
+
199
+ def delete_shelve( *args )
200
+ if( ! args.include?( "-c" ) )
201
+ args.unshift( "-c")
202
+ end
203
+ return self.run( "shelve", "-d", args)
204
+ end
205
+
206
+ #
207
+ # Simple interface for using "p4 login"
208
+ #
209
+ def run_login( *args )
210
+ self.input = self.password
211
+ return self.run( "login", args )
212
+ end
213
+
214
+ def run_resolve( *args )
215
+ if( block_given? )
216
+ self.run( "resolve", args ) do
217
+ |default|
218
+ yield( default )
219
+ end
220
+ else
221
+ self.run( "resolve", args )
222
+ end
223
+ end
224
+
225
+ #
226
+ # Interface for changing the user's password. Supply the old password
227
+ # and the new one.
228
+ #
229
+ def run_password( oldpass, newpass )
230
+ if( oldpass && oldpass.length > 0 )
231
+ self.input = [ oldpass, newpass, newpass ]
232
+ else
233
+ self.input = [ newpass, newpass ]
234
+ end
235
+ self.run( "password" )
236
+ end
237
+
238
+ #
239
+ # The following methods convert the standard output of some common
240
+ # Perforce commands into more structured form to make using the
241
+ # data easier.
242
+ #
243
+ # (Currently only run_filelog is defined. More to follow)
244
+
245
+
246
+ #
247
+ # run_filelog: convert "p4 filelog" responses into objects with useful
248
+ # methods
249
+ #
250
+ # Requires tagged output to be of any real use. If tagged output it not
251
+ # enabled then you just get the raw data back
252
+ #
253
+ def run_filelog( *args )
254
+ raw = self.run( 'filelog', args.flatten )
255
+ raw.collect do
256
+ |h|
257
+ if ( ! h.kind_of?( Hash ) )
258
+ h
259
+ else
260
+ df = P4::DepotFile.new( h[ "depotFile" ] )
261
+ h[ "rev" ].each_index do
262
+ |n|
263
+
264
+ # If rev is nil, there's nothing here for us
265
+ next unless h[ "rev" ][ n ]
266
+
267
+ # Create a new revision of this file ready for populating
268
+ r = df.new_revision
269
+
270
+ h.each do
271
+ |key,value|
272
+ next unless( value.kind_of?( Array ) )
273
+ next unless value[ n ]
274
+ next if( value[ n ].kind_of?( Array ) )
275
+ # If the field is the revision time, convert it to a Time object
276
+ value[ n ] = Time.at( value[ n ].to_i ) if key == "time"
277
+ r.set_attribute( key, value[ n ] )
278
+ end
279
+
280
+ # Now if there are any integration records for this revision,
281
+ # add them in too
282
+ next unless ( h[ "how" ] )
283
+ next unless ( h[ "how" ][ n ] )
284
+
285
+ h[ "how" ][ n ].each_index do
286
+ |m|
287
+ how = h[ "how" ][ n ][ m ]
288
+ file = h[ "file" ][ n ][ m ]
289
+ srev = h[ "srev" ][ n ][ m ]
290
+ erev = h[ "erev" ][ n ][ m ]
291
+ srev.gsub!( /^#/, "" )
292
+ erev.gsub!( /^#/, "" )
293
+ srev = ( srev == "none" ? 0 : srev.to_i )
294
+ erev = ( erev == "none" ? 0 : erev.to_i )
295
+
296
+ r.integration( how, file, srev, erev )
297
+ end
298
+ end
299
+ df
300
+ end
301
+ end
302
+ end
303
+
304
+ #
305
+ # Allow the user to run commands at a temporarily altered exception level.
306
+ # Pass the new exception level desired, and a block to be executed at that
307
+ # level.
308
+ #
309
+ def at_exception_level( level )
310
+ return self unless block_given?
311
+ old_level = self.exception_level
312
+ self.exception_level = level
313
+ begin
314
+ yield( self )
315
+ ensure
316
+ self.exception_level = old_level
317
+ end
318
+ self
319
+ end
320
+
321
+ #
322
+ # Allow users to run commands using a specified handler.
323
+ # Pass a handler and the block that will be executed using this handler
324
+ # The handler will be reset to its previous value at the end of this block
325
+ #
326
+ def with_handler( handler )
327
+ return self unless block_given?
328
+ old_handler = self.handler
329
+ self.handler = handler
330
+ begin
331
+ yield( self )
332
+ ensure
333
+ self.handler = old_handler
334
+ end
335
+ self
336
+ end
337
+
338
+ #
339
+ # Show some handy information when using irb
340
+ #
341
+ def inspect
342
+ sprintf( 'P4: [%s] %s@%s (%s)',
343
+ self.port, self.user, self.client,
344
+ self.connected? ? 'connected' : 'not connected' )
345
+ end
346
+
347
+ #*****************************************************************************
348
+ # The P4::Spec class holds the fields in a Perforce spec
349
+ #*****************************************************************************
350
+ class Spec < Hash
351
+ def initialize( fieldmap = nil )
352
+ @fields = fieldmap
353
+ end
354
+
355
+ #
356
+ # Override the default assignment method. This implementation
357
+ # ensures that any fields defined are valid ones for this type of
358
+ # spec.
359
+ #
360
+ def []=( key, value )
361
+ if( self.has_key?( key ) || @fields == nil )
362
+ super( key, value )
363
+ elsif( @fields.has_key?( key.downcase ) )
364
+ super( @fields[ key.downcase ], value )
365
+ else
366
+ raise( P4Exception, "Invalid field: #{key}" )
367
+ end
368
+ end
369
+
370
+ #
371
+ # Return the list of the fields that are permitted in this spec
372
+ #
373
+ def permitted_fields
374
+ @fields.values
375
+ end
376
+
377
+ #
378
+ # Implement accessor methods for the fields in the spec. The accessor
379
+ # methods are all prefixed with '_' to avoid conflicts with the Hash
380
+ # class' namespace. This is a little ugly, but we gain a lot by
381
+ # subclassing Hash so it's worth it.
382
+ #
383
+ def method_missing( m, *a )
384
+ k = m.to_s.downcase
385
+
386
+ # Check if we're being asked for 'to_ary'. If so, raise 'NoMethodError'.
387
+ return :to_ary ? raise( NoMethodError ) : super if ( k == "to_ary" )
388
+
389
+ if( k[ 0..0 ] != "_" )
390
+ raise( RuntimeError,
391
+ "undefined method `#{m.to_s}' for object of " +
392
+ "class #{self.class.to_s}" )
393
+ end
394
+ k = k[ 1..-1 ]
395
+
396
+ if( k =~ /(.*)=$/ )
397
+ if( a.length() == 0 )
398
+ raise( P4Exception, "Method P4##{m} requires an argument" );
399
+ end
400
+
401
+ k = $1
402
+ if( @fields == nil || @fields.has_key?( k ) )
403
+ return self[ @fields[ k ] ] = a.shift
404
+ end
405
+ elsif( self.has_key?( m.to_s ) )
406
+ return self[ m.to_s ]
407
+ elsif( @fields.has_key?( k ) )
408
+ return self[ @fields[ k ] ]
409
+ end
410
+ raise( P4Exception, "Invalid field: #{$1}" )
411
+ end
412
+ end
413
+
414
+ #*****************************************************************************
415
+ #* P4::MergeInfo class
416
+ #*****************************************************************************
417
+
418
+ class MergeInfo
419
+
420
+ def initialize( base, yours, theirs, merged, hint )
421
+ @base = base
422
+ @yours = yours
423
+ @theirs = theirs
424
+ @merged = merged
425
+ @hint = hint
426
+ end
427
+
428
+ attr_reader :base, :yours, :theirs, :merged, :hint
429
+ end
430
+
431
+ #*****************************************************************************
432
+ # P4::Integration class
433
+ # P4::Integration objects hold details about the integrations that have
434
+ # been performed on a particular revision. Used primarily with the
435
+ # P4::Revision class
436
+ #*****************************************************************************
437
+ class Integration
438
+ def initialize( how, file, srev, erev )
439
+ @how = how
440
+ @file = file
441
+ @srev = srev
442
+ @erev = erev
443
+ end
444
+
445
+ attr_reader :how, :file, :srev, :erev
446
+ end
447
+
448
+ #*****************************************************************************
449
+ # P4::Revision class
450
+ # Each P4::Revision object holds details about a particular revision
451
+ # of a file. It may also contain the history of any integrations
452
+ # to/from the file
453
+ #*****************************************************************************
454
+
455
+ class Revision
456
+ def initialize( depotFile )
457
+ @depot_file = depotFile
458
+ @integrations = Array.new
459
+ @attributes = Hash.new
460
+ end
461
+
462
+ attr_reader :depot_file
463
+ attr_accessor :integrations
464
+
465
+ def integration( how, file, srev, erev )
466
+ rec = P4::Integration.new( how, file, srev, erev )
467
+ @integrations.push( rec )
468
+ return rec
469
+ end
470
+
471
+ def each_integration
472
+ @integrations.each { |i| yield( i ) }
473
+ end
474
+
475
+ def set_attribute( name, value )
476
+ name = name.downcase
477
+ if( value =~ /^\d+$/ )
478
+ @attributes[ name ] = value.to_i
479
+ else
480
+ @attributes[ name ] = value
481
+ end
482
+ end
483
+
484
+ # Define #type and #type= explicitly as they clash with the
485
+ # deprecated Object#type. As it is deprecated, this clash should
486
+ # disappear in time.
487
+ def type
488
+ @attributes[ 'type' ]
489
+ end
490
+
491
+ def type=( t )
492
+ @attributes[ 'type' ] = t
493
+ end
494
+
495
+ #
496
+ # Generic getters and setters for revision attributes.
497
+ #
498
+ def method_missing( m, *a )
499
+ k = m.to_s.downcase
500
+ if( k =~ /(.*)=$/ )
501
+ if( a.length() == 0 )
502
+ raise( P4Exception, "Method P4##{m} requires an argument" );
503
+ end
504
+ k = $1
505
+ @attributes[ k ] = a.shift
506
+ else
507
+ @attributes[ k ]
508
+ end
509
+ end
510
+ end
511
+
512
+ #*****************************************************************************
513
+ # P4::DepotFile class.
514
+ # Each DepotFile entry contains details about one depot file.
515
+ #*****************************************************************************
516
+ class DepotFile
517
+ def initialize( name )
518
+ @depot_file = name
519
+ @revisions = Array.new
520
+ @headAction = @head_type = @head_time = @head_rev = @head_change = nil
521
+ end
522
+
523
+ attr_reader :depot_file, :revisions
524
+ attr_accessor :head_action, :head_type, :head_time, :head_rev, :head_change
525
+
526
+ def new_revision
527
+ r = P4::Revision.new( @depot_file )
528
+ @revisions.push( r )
529
+ return r
530
+ end
531
+
532
+ def each_revision
533
+ @revisions.each { |r| yield( r ) }
534
+ end
535
+ end
536
+
537
+ #*****************************************************************************
538
+ # P4::OutputHandler class.
539
+ # Base class for all Handler classes that can be passed to P4::handler.
540
+ #*****************************************************************************
541
+ class OutputHandler
542
+ def outputStat(stat)
543
+ REPORT
544
+ end
545
+
546
+ def outputInfo(info)
547
+ REPORT
548
+ end
549
+
550
+ def outputText(text)
551
+ REPORT
552
+ end
553
+
554
+ def outputBinary(binary)
555
+ REPORT
556
+ end
557
+
558
+ def outputMessage(message)
559
+ REPORT
560
+ end
561
+ end
562
+
563
+ class ReportHandler < OutputHandler
564
+ def outputStat(stat)
565
+ p "stat:", stat
566
+ HANDLED
567
+ end
568
+
569
+ def outputInfo(info)
570
+ p "info:", info
571
+ HANDLED
572
+ end
573
+
574
+ def outputText(text)
575
+ p "text:", text
576
+ HANDLED
577
+ end
578
+
579
+ def outputBinary(binary)
580
+ p "binary:", binary
581
+ HANDLED
582
+ end
583
+
584
+ def outputMessage(message)
585
+ p "message:", message
586
+ HANDLED
587
+ end
588
+ end
589
+ end # class P4
Binary file
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: P4Ruby-mingwx86
3
+ version: !ruby/object:Gem::Version
4
+ version: '2014.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Norbert Csibra
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-04-15 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: ! "Built with Perforce API 2014.1(mingwx86), P4Ruby 2012.1 and Ruby 1.9.3.\n
15
+ \ Platform: Windows x86.\n "
16
+ email: napispam@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/P4.rb
22
+ - lib/P4.so
23
+ homepage: https://github.com/ncsibra/p4ruby
24
+ licenses: []
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ! '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 1.8.23
44
+ signing_key:
45
+ specification_version: 3
46
+ summary: Ruby interface for Perforce API
47
+ test_files: []