P4Ruby-mingwx86 2014.1

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.
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: []