p4_web_api_client 2014.2.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/p4_web_api_client/client/branches.rb +41 -0
- data/lib/p4_web_api_client/client/changes.rb +17 -0
- data/lib/p4_web_api_client/client/clients.rb +40 -0
- data/lib/p4_web_api_client/client/depots.rb +42 -0
- data/lib/p4_web_api_client/client/files.rb +30 -0
- data/lib/p4_web_api_client/client/groups.rb +41 -0
- data/lib/p4_web_api_client/client/jobs.rb +36 -0
- data/lib/p4_web_api_client/client/labels.rb +41 -0
- data/lib/p4_web_api_client/client/protections.rb +19 -0
- data/lib/p4_web_api_client/client/run.rb +38 -0
- data/lib/p4_web_api_client/client/servers.rb +38 -0
- data/lib/p4_web_api_client/client/streams.rb +38 -0
- data/lib/p4_web_api_client/client/triggers.rb +18 -0
- data/lib/p4_web_api_client/client/users.rb +38 -0
- data/lib/p4_web_api_client/client.rb +86 -0
- data/lib/p4_web_api_client/connection.rb +98 -0
- data/lib/p4_web_api_client/errors/perforce_problem.rb +25 -0
- data/lib/p4_web_api_client/errors/resource_not_found.rb +10 -0
- data/lib/p4_web_api_client/errors/server_error.rb +9 -0
- data/lib/p4_web_api_client/errors/unauthenticated.rb +11 -0
- data/lib/p4_web_api_client/errors.rb +4 -0
- data/lib/p4_web_api_client/models/branch.rb +66 -0
- data/lib/p4_web_api_client/models/change.rb +71 -0
- data/lib/p4_web_api_client/models/client.rb +129 -0
- data/lib/p4_web_api_client/models/depot.rb +97 -0
- data/lib/p4_web_api_client/models/dir.rb +45 -0
- data/lib/p4_web_api_client/models/file.rb +70 -0
- data/lib/p4_web_api_client/models/group.rb +102 -0
- data/lib/p4_web_api_client/models/label.rb +75 -0
- data/lib/p4_web_api_client/models/protections.rb +34 -0
- data/lib/p4_web_api_client/models/server.rb +96 -0
- data/lib/p4_web_api_client/models/stream.rb +111 -0
- data/lib/p4_web_api_client/models/triggers.rb +34 -0
- data/lib/p4_web_api_client/models/user.rb +75 -0
- data/lib/p4_web_api_client/models.rb +14 -0
- data/lib/p4_web_api_client/version.rb +3 -0
- data/lib/p4_web_api_client.rb +6 -0
- data/spec/branches_spec.rb +63 -0
- data/spec/change_spec.rb +16 -0
- data/spec/clients_spec.rb +64 -0
- data/spec/depots_spec.rb +62 -0
- data/spec/files_spec.rb +36 -0
- data/spec/groups_spec.rb +63 -0
- data/spec/init.base/init_p4d.rb +52 -0
- data/spec/jobs_spec.rb +66 -0
- data/spec/labels_spec.rb +62 -0
- data/spec/lib/test_connections.rb +28 -0
- data/spec/protections_spec.rb +31 -0
- data/spec/run_input_spec.rb +23 -0
- data/spec/run_spec.rb +21 -0
- data/spec/servers_spec.rb +64 -0
- data/spec/streams_spec.rb +74 -0
- data/spec/triggers_spec.rb +22 -0
- data/spec/users_spec.rb +78 -0
- metadata +285 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
module P4WebApiClient
|
2
|
+
module Errors
|
3
|
+
# It's likely that many 'unknown server errors' are actually errors from
|
4
|
+
# the Perforce server. This exception allows your client code to inspect
|
5
|
+
# the returned information to **potentially** handle issues the API code
|
6
|
+
# was unable to deal with. This can happen in cases of funky Perforce
|
7
|
+
# server configurations.
|
8
|
+
#
|
9
|
+
# Expect at least one message describing the problem. Each message contains
|
10
|
+
# 3 attributes: 'MessageCode', 'MessageSeverity', and 'MessageText'. You
|
11
|
+
# probably should only use the message code for any error handling logic,
|
12
|
+
# reserving the other fields for diagnostic usage.
|
13
|
+
class PerforceProblem < Exception
|
14
|
+
attr_accessor :messages
|
15
|
+
|
16
|
+
def initialize(messages)
|
17
|
+
@messages = messages
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
"PerforceProblem<@messages:[#{@messages}]>"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module P4WebApiClient
|
2
|
+
module Errors
|
3
|
+
# This is an unlikely exception case, actually. In some cases (not all) if
|
4
|
+
# a resource is to be edited, and it doesn't exist, you may get this error.
|
5
|
+
# But most of the time your code should probably consider this a problem
|
6
|
+
# in your client logic, and likely not handle it directly.
|
7
|
+
class ResourceNotFound < Exception
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module P4WebApiClient
|
2
|
+
module Errors
|
3
|
+
# This is a generic response for generic problems the API doesn't really
|
4
|
+
# receive any other diagnostic issue with. You should *not* trust the
|
5
|
+
# client object after receiving this.
|
6
|
+
class ServerError < Exception
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module P4WebApiClient
|
2
|
+
module Errors
|
3
|
+
# This is just basically the 403 error type, which doesn't have much
|
4
|
+
# diagnostic information. This can happen if your session is invalid
|
5
|
+
# with perforce, you've used an invalid token, etc. Basically, you need
|
6
|
+
# to create a new session and make sure the auth string you're sending over
|
7
|
+
# is correct.
|
8
|
+
class Unauthenticated < Exception
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# Copyright (c) 2014 Perforce Software, Inc. All rights reserved.
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module P4WebApiClient
|
6
|
+
module Models
|
7
|
+
# Models the output of a branch spec in the system.
|
8
|
+
#
|
9
|
+
# See also:
|
10
|
+
# - http://www.perforce.com/perforce/r14.2/manuals/cmdref/p4_branch.html
|
11
|
+
# - http://www.perforce.com/perforce/r14.2/manuals/cmdref/p4_branches.html
|
12
|
+
class Branch
|
13
|
+
# The branch name and primary ID
|
14
|
+
attr_accessor :branch
|
15
|
+
|
16
|
+
# Perforce login of the branch owner, this field is not important unless
|
17
|
+
# `option` is :locked
|
18
|
+
attr_accessor :owner
|
19
|
+
|
20
|
+
# DateTime of the last access to the branch spec
|
21
|
+
attr_accessor :access
|
22
|
+
|
23
|
+
# DateTime when the branch was last changed
|
24
|
+
attr_accessor :update
|
25
|
+
|
26
|
+
# Either :unlocked or :locked
|
27
|
+
attr_accessor :options
|
28
|
+
|
29
|
+
# Short description of the branch's purpose
|
30
|
+
attr_accessor :description
|
31
|
+
|
32
|
+
# Mappings from one set of depot files to another set of files. Each
|
33
|
+
# mapping is a string in the array of mappings, separated by whitespace
|
34
|
+
# (or possibly enquoted with '' characters)
|
35
|
+
attr_accessor :view
|
36
|
+
|
37
|
+
def initialize(obj = {})
|
38
|
+
@branch = obj['Branch'] if obj.key?('Branch')
|
39
|
+
@owner = obj['Owner'] if obj.key?('Owner')
|
40
|
+
@access = Time.at(obj['Access']).to_datetime if obj.key('Access')
|
41
|
+
@update = Time.at(obj['Update']).to_datetime if obj.key('Update')
|
42
|
+
@options = obj['Options'].to_sym if obj.key?('Options')
|
43
|
+
@description = obj['Description'] if obj.key?('Description')
|
44
|
+
@view = obj['View'].map(&:clone) if obj.key?('View')
|
45
|
+
|
46
|
+
# If the user has defined symbols in the Ruby-ish API, then use that
|
47
|
+
# too, but we expect the data to be in the right format.
|
48
|
+
obj.each_key do |key|
|
49
|
+
accessor = "#{key}="
|
50
|
+
send(accessor, obj[key]) if self.respond_to?(accessor)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_internal_hash
|
55
|
+
hash = {
|
56
|
+
Branch: @branch
|
57
|
+
}
|
58
|
+
hash[:Owner] = @owner if @owner
|
59
|
+
hash[:Options] = @options if @options
|
60
|
+
hash[:Description] = @description if @description
|
61
|
+
hash[:View] = @view if @view
|
62
|
+
hash
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# Copyright (c) 2014 Perforce Software, Inc. All rights reserved.
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module P4WebApiClient
|
6
|
+
module Models
|
7
|
+
# Represents typical changelist descriptions
|
8
|
+
#
|
9
|
+
# In the future, this may be used to represent changelist specifications,
|
10
|
+
# but currently only models output of the GET /v1/changes command.
|
11
|
+
#
|
12
|
+
# See also:
|
13
|
+
# - http://www.perforce.com/perforce/r14.2/manuals/cmdref/p4_changes.html
|
14
|
+
# - http://www.perforce.com/perforce/r14.2/manuals/cmdref/p4_change.html
|
15
|
+
class Change
|
16
|
+
# If path information exists, this is a depot path specifier that
|
17
|
+
# indicates what files this changelist affects. (This is not documented.)
|
18
|
+
attr_accessor :path
|
19
|
+
|
20
|
+
# A string ID of the change
|
21
|
+
attr_accessor :change
|
22
|
+
|
23
|
+
# DateTime indicating when the change was created
|
24
|
+
attr_accessor :date
|
25
|
+
|
26
|
+
# String client ID the changelist is associated with
|
27
|
+
attr_accessor :client
|
28
|
+
|
29
|
+
# Perforce login of the person who owns this changelist (a string)
|
30
|
+
attr_accessor :user
|
31
|
+
|
32
|
+
# One of :pending, :shelved, :submitted, or :new. Probably :submitted
|
33
|
+
attr_accessor :status
|
34
|
+
|
35
|
+
# One of :restricted or :public
|
36
|
+
attr_accessor :type
|
37
|
+
|
38
|
+
# Textual string description of changelist. Must be set for changes
|
39
|
+
# who have their `status` set to :submitted
|
40
|
+
attr_accessor :description
|
41
|
+
|
42
|
+
# An array of job IDs fixed by this changelist
|
43
|
+
attr_accessor :jobs
|
44
|
+
|
45
|
+
# An array of file paths being submitted in this changelist
|
46
|
+
attr_accessor :files
|
47
|
+
|
48
|
+
def initialize(obj = {})
|
49
|
+
@path = obj['Path'] if obj.key?('Path')
|
50
|
+
@change = obj['Change'] if obj.key?('Change')
|
51
|
+
@date = Time.at(obj['Date']).to_datetime if obj.key?('Date')
|
52
|
+
@client = obj['Client'] if obj.key?('Client')
|
53
|
+
@user = obj['User'] if obj.key?('User')
|
54
|
+
@status = obj['Status'].to_sym if obj.key?('Status')
|
55
|
+
@type = obj['Type'].to_sym if obj.key?('Type')
|
56
|
+
@description = obj['Description'] if obj.key?('Description')
|
57
|
+
# Create copies of these arrays. It's unlikely they'll change but it's
|
58
|
+
# probably not a good idea to just maintain references to the parent
|
59
|
+
@jobs = obj['Jobs'].map(&:clone) if obj.key?('Jobs')
|
60
|
+
@files = obj['Files'].map(&:clone) if obj.key?('Files')
|
61
|
+
|
62
|
+
# If the user has defined symbols in the Ruby-ish API, then use that
|
63
|
+
# too, but we expect the data to be in the right format.
|
64
|
+
obj.each_key do |key|
|
65
|
+
accessor = "#{key}="
|
66
|
+
send(accessor, obj[key]) if self.respond_to?(accessor)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# Copyright (c) 2014 Perforce Software, Inc. All rights reserved.
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module P4WebApiClient
|
6
|
+
module Models
|
7
|
+
# Models the client spec used to define client workspaces in the Perforce
|
8
|
+
# system.
|
9
|
+
#
|
10
|
+
# See also:
|
11
|
+
# - http://www.perforce.com/perforce/r14.2/manuals/cmdref/p4_client.html
|
12
|
+
# - http://www.perforce.com/perforce/r14.2/manuals/cmdref/p4_clients.html
|
13
|
+
class Client
|
14
|
+
# The client workspace name and primary ID
|
15
|
+
attr_accessor :client
|
16
|
+
|
17
|
+
# Perforce login of the user who owns the workspace
|
18
|
+
attr_accessor :owner
|
19
|
+
|
20
|
+
# DateTime when the workspace was last modified
|
21
|
+
attr_accessor :update
|
22
|
+
|
23
|
+
# DateTime when the workspace was last used
|
24
|
+
attr_accessor :access
|
25
|
+
|
26
|
+
# The name of the workstation this workspace resides. If set, client
|
27
|
+
# operations can *only* be run from this host.
|
28
|
+
attr_accessor :host
|
29
|
+
|
30
|
+
# Textual description of the workspace
|
31
|
+
attr_accessor :description
|
32
|
+
|
33
|
+
# Directory (on the local host) relative to which all files in the `view`
|
34
|
+
# are specified. If you change this setting, you must 'physically'
|
35
|
+
# relocate any files that currently reside there.
|
36
|
+
attr_accessor :root
|
37
|
+
|
38
|
+
# Up to two alternate cleint workspace roots
|
39
|
+
#
|
40
|
+
# This enables users to use the same Perforce client on multiple platforms
|
41
|
+
#
|
42
|
+
# See the command reference for more details:
|
43
|
+
# - http://www.perforce.com/perforce/r14.2/manuals/cmdref/p4_client.html
|
44
|
+
attr_accessor :alt_roots
|
45
|
+
|
46
|
+
# A single string defining a set of switches the change behavior of
|
47
|
+
# different commands on the client.
|
48
|
+
#
|
49
|
+
# See the command reference for more details:
|
50
|
+
# - http://www.perforce.com/perforce/r14.2/manuals/cmdref/p4_client.html
|
51
|
+
attr_accessor :options
|
52
|
+
|
53
|
+
# A single string that governs default behavior of p4 submit on this
|
54
|
+
# client.
|
55
|
+
#
|
56
|
+
# See the command reference for more details:
|
57
|
+
# - http://www.perforce.com/perforce/r14.2/manuals/cmdref/p4_client.html
|
58
|
+
attr_accessor :submit_options
|
59
|
+
|
60
|
+
# Configure CR/LF conversion
|
61
|
+
#
|
62
|
+
# See the command reference for more details:
|
63
|
+
# - http://www.perforce.com/perforce/r14.2/manuals/cmdref/p4_client.html
|
64
|
+
attr_accessor :line_end
|
65
|
+
|
66
|
+
# Associates the workspace with the specified stream.
|
67
|
+
attr_accessor :stream
|
68
|
+
|
69
|
+
# A changelist number that sets a back-in-time view of a stream.
|
70
|
+
attr_accessor :stream_at_change
|
71
|
+
|
72
|
+
# If set, restricts the usage of the workspace to the named server.
|
73
|
+
attr_accessor :server_id
|
74
|
+
|
75
|
+
# Array of strings that specifies the mappings between files in the depot
|
76
|
+
# and files in the workspace.
|
77
|
+
attr_accessor :view
|
78
|
+
|
79
|
+
# Restricts access to depot paths to a particular point in time.
|
80
|
+
attr_accessor :change_view
|
81
|
+
|
82
|
+
def initialize(obj = {})
|
83
|
+
@client = obj['Client'] if obj.key?('Client')
|
84
|
+
@owner = obj['Owner'] if obj.key?('Owner')
|
85
|
+
@access = Time.at(obj['Access']).to_datetime if obj.key?('Access')
|
86
|
+
@update = Time.at(obj['Update']).to_datetime if obj.key?('Update')
|
87
|
+
@host = obj['Host'] if obj.key?('Host')
|
88
|
+
@description = obj['Description'] if obj.key?('Description')
|
89
|
+
@root = obj['Root'] if obj.key?('Root')
|
90
|
+
@alt_roots = obj['AltRoots'].map(&:clone) if obj.key?('AltRoots')
|
91
|
+
@options = obj['Options'] if obj.key?('Options')
|
92
|
+
@submit_options = obj['SubmitOptions'] if obj.key?('SubmitOptions')
|
93
|
+
@line_end = obj['LineEnd'] if obj.key?('LineEnd')
|
94
|
+
@stream = obj['Stream'] if obj.key?('Stream')
|
95
|
+
@stream_at_change = obj['StreamAtChange'] if obj.key?('StreamAtChange')
|
96
|
+
@server_id = obj['ServerID'] if obj.key?('ServerID')
|
97
|
+
@view = obj['View'].map(&:clone) if obj.key?('View')
|
98
|
+
@change_view = obj['ChangeView'].map(&:clone) if obj.key?('ChangeView')
|
99
|
+
|
100
|
+
# If the user has defined symbols in the Ruby-ish API, then use that
|
101
|
+
# too, but we expect the data to be in the right format.
|
102
|
+
obj.each_key do |key|
|
103
|
+
accessor = "#{key}="
|
104
|
+
send(accessor, obj[key]) if self.respond_to?(accessor)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def to_internal_hash
|
109
|
+
hash = {
|
110
|
+
Client: @client
|
111
|
+
}
|
112
|
+
hash[:Owner] = @owner if @owner
|
113
|
+
hash[:Host] = @host if @host
|
114
|
+
hash[:Description] = @description if @description
|
115
|
+
hash[:Root] = @root if @root
|
116
|
+
hash[:AltRoots] = @alt_roots if @alt_roots
|
117
|
+
hash[:Options] = @options if @options
|
118
|
+
hash[:SubmitOptions] = @submit_options if @submit_options
|
119
|
+
hash[:LineEnd] = @line_end if @line_end
|
120
|
+
hash[:Stream] = @stream if @stream
|
121
|
+
hash[:StreamAtChange] = @stream_at_change if @stream_at_change
|
122
|
+
hash[:ServerID] = @server_id if @server_id
|
123
|
+
hash[:View] = @view if @view
|
124
|
+
hash[:ChangeView] = @change_view if @change_view
|
125
|
+
hash
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# Copyright (c) 2014 Perforce Software, Inc. All rights reserved.
|
2
|
+
|
3
|
+
module P4WebApiClient
|
4
|
+
module Models
|
5
|
+
# Model that can be obtained via file browsing (the files command with no
|
6
|
+
# arguments) *or* via the list_depots command.
|
7
|
+
#
|
8
|
+
# This implements a few methods to assist in file browsing, since our
|
9
|
+
# underlying data is actually quite inconsistent. These methods are shared
|
10
|
+
# between Dir, and File:
|
11
|
+
#
|
12
|
+
# * name - The name without any parent specifier
|
13
|
+
# * depot_path - The typical '//depot/dir1/file' style path specifier
|
14
|
+
# * browsable? - Can you list children of this path?
|
15
|
+
#
|
16
|
+
# For more details on the output fields, see
|
17
|
+
# http://www.perforce.com/perforce/r14.2/manuals/cmdref/p4_depot.html
|
18
|
+
class Depot
|
19
|
+
# The depot name
|
20
|
+
attr_accessor :depot
|
21
|
+
|
22
|
+
# DateTime associated with the depot
|
23
|
+
attr_accessor :date
|
24
|
+
|
25
|
+
# :local, :remote, :spec, :stream, :unload, or :archive
|
26
|
+
attr_accessor :type
|
27
|
+
|
28
|
+
# If type is :remote, this is likely the P4PORT address of the remote
|
29
|
+
# server. May not be set in all cases.
|
30
|
+
attr_accessor :address
|
31
|
+
|
32
|
+
# If type is :local, :spec, or :archive, this points to the relative
|
33
|
+
# location of the depot subdirectory. See command reference for more
|
34
|
+
# details
|
35
|
+
attr_accessor :map
|
36
|
+
|
37
|
+
# Short description of the depot's purpose. Optional
|
38
|
+
attr_accessor :description
|
39
|
+
|
40
|
+
# The user who owns the depot.
|
41
|
+
attr_accessor :owner
|
42
|
+
|
43
|
+
# If type is :spec, this holds an optional suffix for generated paths
|
44
|
+
# to objects in the spec depot. See command reference for more details.
|
45
|
+
attr_accessor :suffix
|
46
|
+
|
47
|
+
# When type is :spec, an optional description of what specs should be
|
48
|
+
# saved. See command reference for more details.
|
49
|
+
attr_accessor :spec_map
|
50
|
+
|
51
|
+
def initialize(obj = {})
|
52
|
+
@depot = obj['Depot'] if obj.key?('Depot')
|
53
|
+
@date = Time.at(obj['Date']).to_datetime if obj.key?('Date')
|
54
|
+
@type = obj['Type'].to_sym if obj.key?('Type')
|
55
|
+
@address = obj['Address'] if obj.key?('Address')
|
56
|
+
@map = obj['Map'] if obj.key?('Map')
|
57
|
+
@description = obj['Description'] if obj.key?('Description')
|
58
|
+
@owner = obj['Owner'] if obj.key?('Owner')
|
59
|
+
@suffix = obj['Suffix'] if obj.key?('Suffix')
|
60
|
+
@spec_map = obj['SpecMap'] if obj.key?('SpecMap')
|
61
|
+
|
62
|
+
# If the user has defined symbols in the Ruby-ish API, then use that
|
63
|
+
# too, but we expect the data to be in the right format.
|
64
|
+
obj.each_key do |key|
|
65
|
+
accessor = "#{key}="
|
66
|
+
send(accessor, obj[key]) if self.respond_to?(accessor)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def name
|
71
|
+
depot
|
72
|
+
end
|
73
|
+
|
74
|
+
def depot_path
|
75
|
+
"//#{depot}"
|
76
|
+
end
|
77
|
+
|
78
|
+
# You should always be able to list files and dirs of a depot (I think),
|
79
|
+
# you just might not get any results.
|
80
|
+
def browsable?
|
81
|
+
true
|
82
|
+
end
|
83
|
+
|
84
|
+
def to_internal_hash
|
85
|
+
hash = {
|
86
|
+
Depot: @depot
|
87
|
+
}
|
88
|
+
hash[:Type] = @type if @type
|
89
|
+
hash[:Address] = @address if @address
|
90
|
+
hash[:Map] = @map if @map
|
91
|
+
hash[:Description] = @description if @description
|
92
|
+
hash[:Owner] = @owner if @owner
|
93
|
+
hash
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Copyright (c) 2014 Perforce Software, Inc. All rights reserved.
|
2
|
+
|
3
|
+
module P4WebApiClient
|
4
|
+
module Models
|
5
|
+
# Model that can be obtained during file browsing - represents directories
|
6
|
+
# in the system.
|
7
|
+
#
|
8
|
+
# This implements a few methods to assist in file browsing, since our
|
9
|
+
# underlying data is actually quite inconsistent. These methods are shared
|
10
|
+
# between Depot, Dir, and File:
|
11
|
+
#
|
12
|
+
# * name - The name without any parent specifier
|
13
|
+
# * depot_path - The typical '//depot/dir1/file' style path specifier
|
14
|
+
# * browsable? - Can you list children of this path?
|
15
|
+
#
|
16
|
+
# For more information, also see http://www.perforce.com/perforce/r14.2/manuals/cmdref/p4_dirs.html
|
17
|
+
class Dir
|
18
|
+
# The depot path to this particular directory
|
19
|
+
attr_accessor :dir
|
20
|
+
|
21
|
+
def initialize(obj = {})
|
22
|
+
@dir = obj['Dir'] if obj.key?('Dir')
|
23
|
+
|
24
|
+
# If the user has defined symbols in the Ruby-ish API, then use that
|
25
|
+
# too, but we expect the data to be in the right format.
|
26
|
+
obj.each_key do |key|
|
27
|
+
accessor = "#{key}="
|
28
|
+
send(accessor, obj[key]) if self.respond_to?(accessor)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def name
|
33
|
+
dir.split('/').last
|
34
|
+
end
|
35
|
+
|
36
|
+
def depot_path
|
37
|
+
dir
|
38
|
+
end
|
39
|
+
|
40
|
+
def browsable?
|
41
|
+
true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# Copyright (c) 2014 Perforce Software, Inc. All rights reserved.
|
2
|
+
|
3
|
+
module P4WebApiClient
|
4
|
+
module Models
|
5
|
+
# Model that can be obtained during file browsing - represents head
|
6
|
+
# revisions of active files in the system.
|
7
|
+
#
|
8
|
+
# This implements a few methods to assist in file browsing, since our
|
9
|
+
# underlying data is actually quite inconsistent. These methods are shared
|
10
|
+
# between Depot, Dir, and File:
|
11
|
+
#
|
12
|
+
# * name - The name without any parent specifier
|
13
|
+
# * depot_path - The typical '//depot/dir1/file' style path specifier
|
14
|
+
# * browsable? - Can you list children of this path?
|
15
|
+
#
|
16
|
+
# For more information, also see http://www.perforce.com/perforce/r14.2/manuals/cmdref/p4_files.html
|
17
|
+
class File
|
18
|
+
# The depot path of the file
|
19
|
+
attr_accessor :depot_file
|
20
|
+
|
21
|
+
# Revision number of the file
|
22
|
+
attr_accessor :revision
|
23
|
+
|
24
|
+
# Changelist id that created this file revision - should be a string
|
25
|
+
attr_accessor :change
|
26
|
+
|
27
|
+
# Action taken at the head, one of :add, :edit, :delete, :branch,
|
28
|
+
# :move_add, :move_delete, :integrate, :import, :purge, or :archive
|
29
|
+
attr_accessor :action
|
30
|
+
|
31
|
+
# File type - one of :text, :binary, :symlink, :apple, :resource,
|
32
|
+
# :unicode, :utf16
|
33
|
+
#
|
34
|
+
# See http://www.perforce.com/perforce/r14.2/manuals/cmdref/file.types.html
|
35
|
+
attr_accessor :type
|
36
|
+
|
37
|
+
# DateTime of when the file revision was created
|
38
|
+
attr_accessor :date
|
39
|
+
|
40
|
+
def initialize(obj = {})
|
41
|
+
@depot_file = obj['DepotFile'] if obj.key?('DepotFile')
|
42
|
+
@revision = obj['Revision'].to_i if obj.key?('Revision')
|
43
|
+
@change = obj['Change'] if obj.key?('Change')
|
44
|
+
@action = obj['Action'].gsub(/\//, '_').to_sym if obj.key?('Action')
|
45
|
+
@type = obj['Type'].to_sym if obj.key?('Type')
|
46
|
+
@date = Time.at(obj['Date']).to_datetime if obj.key?('Date')
|
47
|
+
|
48
|
+
# If the user has defined symbols in the Ruby-ish API, then use that
|
49
|
+
# too, but we expect the data to be in the right format.
|
50
|
+
obj.each_key do |key|
|
51
|
+
accessor = "#{key}="
|
52
|
+
send(accessor, obj[key]) if self.respond_to?(accessor)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Synonym of depot_file, used for consistency between Depot, Dir, and File
|
57
|
+
def depot_path
|
58
|
+
depot_file
|
59
|
+
end
|
60
|
+
|
61
|
+
def browsable?
|
62
|
+
false
|
63
|
+
end
|
64
|
+
|
65
|
+
def name
|
66
|
+
depot_file.split('/').last
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# Copyright (c) 2014 Perforce Software, Inc. All rights reserved.
|
2
|
+
|
3
|
+
module P4WebApiClient
|
4
|
+
module Models
|
5
|
+
# Models the output of the group spec.
|
6
|
+
#
|
7
|
+
# See also:
|
8
|
+
# - http://www.perforce.com/perforce/r14.2/manuals/cmdref/p4_group.html
|
9
|
+
# - http://www.perforce.com/perforce/r14.2/manuals/cmdref/p4_groups.html
|
10
|
+
class Group
|
11
|
+
# The name and primary ID of the group
|
12
|
+
attr_accessor :group
|
13
|
+
|
14
|
+
# The maximum number of results that members of this group can acccess
|
15
|
+
# from the service from a single command
|
16
|
+
attr_accessor :max_results
|
17
|
+
|
18
|
+
# The maximum number of rows that members of this group can scan from the
|
19
|
+
# service from a single command.
|
20
|
+
attr_accessor :max_scan_rows
|
21
|
+
|
22
|
+
# The maximum length of time (in milliseconds) that any one operation can
|
23
|
+
# lock any database table when scanning data.
|
24
|
+
attr_accessor :max_lock_time
|
25
|
+
|
26
|
+
# The duration (in sections) of the validity of a session ticket created
|
27
|
+
# by
|
28
|
+
attr_accessor :timeout
|
29
|
+
|
30
|
+
# The length of time (in seconds) for which passwords for users in this
|
31
|
+
# group remain valid. To disable password aging, use a value of unset.
|
32
|
+
attr_accessor :password_timeout
|
33
|
+
|
34
|
+
# An array of the Perforce usernames of the group members.
|
35
|
+
attr_accessor :users
|
36
|
+
|
37
|
+
# Array of names of other Perforce groups
|
38
|
+
attr_accessor :subgroups
|
39
|
+
|
40
|
+
# Array of names of other Perforce users, that are allowed to admin this
|
41
|
+
# group. This is independent of group membership. A group owner should
|
42
|
+
# also be a part of the users group if they are intended to take part
|
43
|
+
# in the group
|
44
|
+
attr_accessor :owners
|
45
|
+
|
46
|
+
def initialize(obj = {})
|
47
|
+
@group = obj['Group'] if obj.key?('Group')
|
48
|
+
|
49
|
+
@max_results = obj['MaxResults'].to_i if obj.key?('MaxResults') &&
|
50
|
+
obj['MaxResults'] != 'unset'
|
51
|
+
@max_results = nil if @max_results == 0
|
52
|
+
|
53
|
+
@max_scan_rows = obj['MaxScanRows'].to_i \
|
54
|
+
if obj.key?('MaxScanRows') && obj['MaxScanRows'] != 'unset'
|
55
|
+
@max_scan_rows = nil if @max_scan_rows == 0
|
56
|
+
|
57
|
+
@max_lock_time = obj['MaxLockTime'].to_i \
|
58
|
+
if obj.key?('MaxLockTime') && obj['MaxLockTime'] != 'unset'
|
59
|
+
@max_lock_time = nil if @max_lock_time == 0
|
60
|
+
|
61
|
+
@timeout = obj['Timeout'].to_i \
|
62
|
+
if obj.key?('Timeout') && obj['Timeout'] != 'unset'
|
63
|
+
@timeout = nil if @timeout == 0
|
64
|
+
|
65
|
+
@password_timeout = obj['PasswordTimeout'].to_i \
|
66
|
+
if obj.key?('PasswordTimeout') && obj['PasswordTimeout'] != 'unset'
|
67
|
+
@password_timeout = nil if @password_timeout == 0
|
68
|
+
|
69
|
+
@users = obj['Users'].map(&:clone) if obj.key?('Users')
|
70
|
+
@users = [] unless @users
|
71
|
+
@subgroups = obj['Subgroups'].map(&:clone) if obj.key?('Subgroups')
|
72
|
+
@subgroups = [] unless @subgroups
|
73
|
+
@owners = obj['Owners'].map(&:clone) if obj.key?('Owners')
|
74
|
+
@owners = [] unless @owners
|
75
|
+
|
76
|
+
# If the user has defined symbols in the Ruby-ish API, then use that
|
77
|
+
# too, but we expect the data to be in the right format.
|
78
|
+
obj.each_key do |key|
|
79
|
+
accessor = "#{key}="
|
80
|
+
send(accessor, obj[key]) if self.respond_to?(accessor)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def to_internal_hash
|
85
|
+
hash = {
|
86
|
+
Group: @group
|
87
|
+
}
|
88
|
+
|
89
|
+
hash[:MaxResults] = @max_results.to_s if @max_results
|
90
|
+
hash[:MaxScanRows] = @max_scan_rows.to_s if @max_scan_rows
|
91
|
+
hash[:MaxLockTime] = @max_lock_time.to_s if @max_lock_time
|
92
|
+
hash[:Timeout] = @timeout if @timeout
|
93
|
+
hash[:PasswordTimeout] = @password_timeout if @password_timeout
|
94
|
+
hash[:Users] = @users if @users
|
95
|
+
hash[:Subgroups] = @subgroups if @subgroups
|
96
|
+
hash[:Owners] = @owners if @owners
|
97
|
+
|
98
|
+
hash
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|