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.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/lib/p4_web_api_client/client/branches.rb +41 -0
  3. data/lib/p4_web_api_client/client/changes.rb +17 -0
  4. data/lib/p4_web_api_client/client/clients.rb +40 -0
  5. data/lib/p4_web_api_client/client/depots.rb +42 -0
  6. data/lib/p4_web_api_client/client/files.rb +30 -0
  7. data/lib/p4_web_api_client/client/groups.rb +41 -0
  8. data/lib/p4_web_api_client/client/jobs.rb +36 -0
  9. data/lib/p4_web_api_client/client/labels.rb +41 -0
  10. data/lib/p4_web_api_client/client/protections.rb +19 -0
  11. data/lib/p4_web_api_client/client/run.rb +38 -0
  12. data/lib/p4_web_api_client/client/servers.rb +38 -0
  13. data/lib/p4_web_api_client/client/streams.rb +38 -0
  14. data/lib/p4_web_api_client/client/triggers.rb +18 -0
  15. data/lib/p4_web_api_client/client/users.rb +38 -0
  16. data/lib/p4_web_api_client/client.rb +86 -0
  17. data/lib/p4_web_api_client/connection.rb +98 -0
  18. data/lib/p4_web_api_client/errors/perforce_problem.rb +25 -0
  19. data/lib/p4_web_api_client/errors/resource_not_found.rb +10 -0
  20. data/lib/p4_web_api_client/errors/server_error.rb +9 -0
  21. data/lib/p4_web_api_client/errors/unauthenticated.rb +11 -0
  22. data/lib/p4_web_api_client/errors.rb +4 -0
  23. data/lib/p4_web_api_client/models/branch.rb +66 -0
  24. data/lib/p4_web_api_client/models/change.rb +71 -0
  25. data/lib/p4_web_api_client/models/client.rb +129 -0
  26. data/lib/p4_web_api_client/models/depot.rb +97 -0
  27. data/lib/p4_web_api_client/models/dir.rb +45 -0
  28. data/lib/p4_web_api_client/models/file.rb +70 -0
  29. data/lib/p4_web_api_client/models/group.rb +102 -0
  30. data/lib/p4_web_api_client/models/label.rb +75 -0
  31. data/lib/p4_web_api_client/models/protections.rb +34 -0
  32. data/lib/p4_web_api_client/models/server.rb +96 -0
  33. data/lib/p4_web_api_client/models/stream.rb +111 -0
  34. data/lib/p4_web_api_client/models/triggers.rb +34 -0
  35. data/lib/p4_web_api_client/models/user.rb +75 -0
  36. data/lib/p4_web_api_client/models.rb +14 -0
  37. data/lib/p4_web_api_client/version.rb +3 -0
  38. data/lib/p4_web_api_client.rb +6 -0
  39. data/spec/branches_spec.rb +63 -0
  40. data/spec/change_spec.rb +16 -0
  41. data/spec/clients_spec.rb +64 -0
  42. data/spec/depots_spec.rb +62 -0
  43. data/spec/files_spec.rb +36 -0
  44. data/spec/groups_spec.rb +63 -0
  45. data/spec/init.base/init_p4d.rb +52 -0
  46. data/spec/jobs_spec.rb +66 -0
  47. data/spec/labels_spec.rb +62 -0
  48. data/spec/lib/test_connections.rb +28 -0
  49. data/spec/protections_spec.rb +31 -0
  50. data/spec/run_input_spec.rb +23 -0
  51. data/spec/run_spec.rb +21 -0
  52. data/spec/servers_spec.rb +64 -0
  53. data/spec/streams_spec.rb +74 -0
  54. data/spec/triggers_spec.rb +22 -0
  55. data/spec/users_spec.rb +78 -0
  56. metadata +285 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 199bda143441561260c895321ab9c1c57d42a4ef
4
+ data.tar.gz: 30f094cc9402abdbc2b60707b4f16f03db187c57
5
+ SHA512:
6
+ metadata.gz: d91a36aad1d32dc268db168db220f0d5951cc3aabc28d53fe6b3ed6789c1c0ea30e9d07717bc458191df98870f9788dfa9d2b08e93b096ccc2335ee4e9bdc280
7
+ data.tar.gz: 3500061dd4dd4084729653a53ad1a4bc269dec65d2761727d110691f6673e5860a256d0e3ad80a5da736d4e83025949c340ba5ae156e5eb1c379374edd3dc1cf
@@ -0,0 +1,41 @@
1
+ require 'open-uri'
2
+ require 'p4_web_api_client/models/branch'
3
+
4
+ module P4WebApiClient
5
+ class Client
6
+ # Array of Branch objects stored in the system. Not all fields will be
7
+ # filled out (e.g., view).
8
+ def branches
9
+ arr = execute_method_no_body(:get, '/branches')
10
+ arr.map { |a| Models::Branch.new(a) }
11
+ end
12
+
13
+ # Returns the branch instance indicated by the branch name (or model)
14
+ def branch(branch)
15
+ branch = branch.branch if branch.is_a?(Models::Branch)
16
+ obj = execute_method_with_body(:get, "branches/#{URI.encode(branch)}")
17
+ Models::Branch.new(obj)
18
+ end
19
+
20
+ # Creates a new branch in the system.
21
+ def create_branch(branch)
22
+ branch = Models::Branch.new(branch) unless branch.is_a?(Models::Branch)
23
+ execute_method_with_body(:post, '/branches', branch.to_internal_hash)
24
+ true
25
+ end
26
+
27
+ # Updates the branch specification.
28
+ def update_branch(branch)
29
+ execute_method_with_body(:put, "/branches/#{URI.encode(branch.branch)}",
30
+ branch.to_internal_hash)
31
+ true
32
+ end
33
+
34
+ # Deletes the branch specification in the system.
35
+ def delete_branch(branch)
36
+ branch = branch.branch if branch.is_a?(Models::Branch)
37
+ execute_method_no_body(:delete, "branches/#{URI.encode(branch)}")
38
+ true
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,17 @@
1
+ require 'p4_web_api_client/models/change'
2
+
3
+ module P4WebApiClient
4
+ class Client
5
+ # List changelists in the system
6
+ #
7
+ # options:
8
+ # - :max: cap the number of results
9
+ # - :status: :pending, :submitted, or :shelved (see Change)
10
+ # - :user: The perforce login to check out
11
+ # - :files: Depot path pattern to restrict changes to
12
+ def changes(options = nil)
13
+ arr = execute_method_no_body(:get, '/changes', options)
14
+ arr.map { |obj| Models::Change.new(obj) }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,40 @@
1
+ require 'p4_web_api_client/models/client'
2
+
3
+ module P4WebApiClient
4
+ class Client
5
+ # Array of Client objects stored in the system. Not all fields will be
6
+ # filled out (e.g., view).
7
+ def clients
8
+ arr = execute_method_no_body(:get, '/clients')
9
+ arr.map { |a| Models::Client.new(a) }
10
+ end
11
+
12
+ # Returns the client instance indicated by the client name or model
13
+ def client(client)
14
+ client = client.client if client.is_a?(Models::Client)
15
+ obj = execute_method_no_body(:get, "/clients/#{URI.encode(client)}")
16
+ Models::Client.new(obj)
17
+ end
18
+
19
+ # Creates a new client in the system.
20
+ def create_client(client)
21
+ client = Models::Client.new(client) unless client.is_a?(Models::Client)
22
+ execute_method_with_body(:post, '/clients', client.to_internal_hash)
23
+ true
24
+ end
25
+
26
+ # Updates the client specification.
27
+ def update_client(client)
28
+ execute_method_with_body(:put, "/clients/#{URI.encode(client.client)}",
29
+ client.to_internal_hash)
30
+ true
31
+ end
32
+
33
+ # Deletes the client specification in the system.
34
+ def delete_client(client)
35
+ client = client.client if client.is_a?(Models::Client)
36
+ execute_method_no_body(:delete, "/clients/#{URI.encode(client)}")
37
+ true
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,42 @@
1
+
2
+ require 'open-uri'
3
+ require 'p4_web_api_client/models/depot'
4
+
5
+ module P4WebApiClient
6
+ class Client
7
+ # Array of Depot objects stored in the system. Not all fields will be
8
+ # filled out (e.g., view).
9
+ def depots
10
+ arr = execute_method_no_body(:get, '/depots')
11
+ arr.map { |a| Models::Depot.new(a) }
12
+ end
13
+
14
+ # Returns the depot instance indicated by the depot name (or depot object)
15
+ def depot(depot)
16
+ depot = depot.depot if depot.is_a?(Models::Depot)
17
+ obj = execute_method_no_body(:get, "/depots/#{URI.encode(depot)}")
18
+ Models::Depot.new(obj)
19
+ end
20
+
21
+ # Creates a new depot in the system.
22
+ def create_depot(depot)
23
+ depot = Models::Depot.new(depot) unless depot.is_a?(Models::Depot)
24
+ execute_method_with_body(:post, '/depots', depot.to_internal_hash)
25
+ true
26
+ end
27
+
28
+ # Updates the depot specification.
29
+ def update_depot(depot)
30
+ execute_method_with_body(:put, "/depots/#{URI.encode(depot.depot)}",
31
+ depot.to_internal_hash)
32
+ true
33
+ end
34
+
35
+ # Deletes the depot specification in the system.
36
+ def delete_depot(depot)
37
+ depot = depot.depot if depot.is_a?(Models::Depot)
38
+ execute_method_no_body(:delete, "/depots/#{URI.encode(depot)}")
39
+ true
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,30 @@
1
+ require 'open-uri'
2
+ require 'p4_web_api_client/models/dir'
3
+ require 'p4_web_api_client/models/depot'
4
+ require 'p4_web_api_client/models/file'
5
+
6
+ module P4WebApiClient
7
+ class Client
8
+ # General file browsing method.
9
+ #
10
+ # The `path` parameter should be a directory location, starting with a
11
+ # depot location, e.g., `my_depot/dir1`.
12
+ #
13
+ # When path is empty, will return the list of depots.
14
+ def files(path = '')
15
+ unless path.empty?
16
+ path = path.split('/').map { |p| URI.encode(p) }.join('/')
17
+ end
18
+ arr = execute_method_no_body(:get, "/files/#{path}")
19
+ arr.map do |obj|
20
+ if obj.key?('DepotFile')
21
+ Models::File.new(obj)
22
+ elsif obj.key?('Dir')
23
+ Models::Dir.new(obj)
24
+ elsif obj.key?('Depot')
25
+ Models::Depot.new(obj)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,41 @@
1
+ require 'open-uri'
2
+ require 'p4_web_api_client/models/group'
3
+
4
+ module P4WebApiClient
5
+ class Client
6
+ # Array of Group objects stored in the system. Not all fields will be
7
+ # filled out (e.g., view).
8
+ def groups
9
+ arr = execute_method_no_body(:get, '/groups')
10
+ arr.map { |x| Models::Group.new(x) }
11
+ end
12
+
13
+ # Returns the group instance indicated by the group name (or group object)
14
+ def group(group)
15
+ group = group.group if group.is_a?(Models::Group)
16
+ obj = execute_method_no_body(:get, "/groups/#{URI.encode(group)}")
17
+ Models::Group.new(obj)
18
+ end
19
+
20
+ # Creates a new group in the system.
21
+ def create_group(group)
22
+ group = Models::Group.new(group) unless group.is_a?(Models::Group)
23
+ execute_method_with_body(:post, '/groups', group.to_internal_hash)
24
+ true
25
+ end
26
+
27
+ # Updates the group specification.
28
+ def update_group(group)
29
+ execute_method_with_body(:put, "/groups/#{URI.encode(group.group)}",
30
+ group.to_internal_hash)
31
+ true
32
+ end
33
+
34
+ # Deletes the group specification in the system.
35
+ def delete_group(group)
36
+ group = group.group if group.is_a?(Models::Group)
37
+ execute_method_no_body(:delete, "/groups/#{URI.encode(group)}")
38
+ true
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,36 @@
1
+ require 'open-uri'
2
+
3
+ module P4WebApiClient
4
+ class Client
5
+ def jobs
6
+ execute_method_no_body(:get, '/jobs')
7
+ end
8
+
9
+ # Returns the array of jobs in the system. Each job model is simply a hash
10
+ # of string -> string values, since each system can very likely adjust
11
+ # job output.
12
+ def job(job_id)
13
+ execute_method_no_body(:get, "/jobs/#{URI.encode(job_id)}")
14
+ end
15
+
16
+ # Creates a new job in the system.
17
+ def create_job(job)
18
+ job['Job'] = 'new' unless job.key?('Job')
19
+ job['Status'] = 'open' unless job.key?('Status')
20
+ execute_method_with_body(:post, '/jobs', job)
21
+ true
22
+ end
23
+
24
+ # Updates the job specification.
25
+ def update_job(job)
26
+ execute_method_with_body(:put, "/jobs/#{URI.encode(job['Job'])}", job)
27
+ true
28
+ end
29
+
30
+ # Deletes the job specification in the system.
31
+ def delete_job(job_id)
32
+ execute_method_no_body(:delete, "/jobs/#{URI.encode(job_id)}")
33
+ true
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,41 @@
1
+ require 'open-uri'
2
+ require 'p4_web_api_client/models/label'
3
+
4
+ module P4WebApiClient
5
+ class Client
6
+ # Array of Label objects stored in the system. Not all fields will be
7
+ # filled out (e.g., view).
8
+ def labels
9
+ arr = execute_method_no_body(:get, '/labels')
10
+ arr.map { |a| Models::Label.new(a) }
11
+ end
12
+
13
+ # Returns the label instance indicated by the label name (or label object)
14
+ def label(label)
15
+ label = label.label if label.is_a?(Models::Label)
16
+ obj = execute_method_no_body(:get, "/labels/#{URI.encode(label)}")
17
+ Models::Label.new(obj)
18
+ end
19
+
20
+ # Creates a new label in the system.
21
+ def create_label(label)
22
+ label = Models::Label.new(label) unless label.is_a?(Models::Label)
23
+ execute_method_with_body(:post, '/labels', label.to_internal_hash)
24
+ true
25
+ end
26
+
27
+ # Updates the label specification.
28
+ def update_label(label)
29
+ execute_method_with_body(:put, "/labels/#{URI.encode(label.label)}",
30
+ label.to_internal_hash)
31
+ true
32
+ end
33
+
34
+ # Deletes the label specification in the system.
35
+ def delete_label(label)
36
+ label = label.label if label.is_a?(Models::Label)
37
+ execute_method_no_body(:delete, "/labels/#{URI.encode(label)}")
38
+ true
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,19 @@
1
+ require 'p4_web_api_client/models/protections'
2
+
3
+ module P4WebApiClient
4
+ class Client
5
+ # Fetch all protections in the system. Returns a single Protections
6
+ # instance.
7
+ def protections
8
+ obj = execute_method_no_body(:get, '/protections')
9
+ Models::Protections.new(obj)
10
+ end
11
+
12
+ # Updates the protections table based on the Protections instance passed in
13
+ def update_protections(protections)
14
+ execute_method_with_body(:put, '/protections',
15
+ protections.to_internal_hash)
16
+ true
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,38 @@
1
+ require 'json'
2
+
3
+ module P4WebApiClient
4
+ class Client
5
+ # Generic run command.
6
+ #
7
+ # First argument should always be the command, followed by command line
8
+ # arguments.
9
+ #
10
+ # Expect to always have an array of hashes as output.
11
+ def run(cmd, args = [])
12
+ params = arg_params(args)
13
+ params[:cmd] = cmd
14
+ execute_method_no_body(:get, '/run', params)
15
+ end
16
+
17
+ # Generic run command with and input body.
18
+ #
19
+ # The first argument is the general command, followed by the input data,
20
+ # then followed by additional command line arguments.
21
+ #
22
+ # Expect the output to always be an array of hashes.
23
+ def run_input(cmd, input, args = [])
24
+ params = arg_params(args)
25
+ params[:cmd] = cmd
26
+ execute_method_with_body(:post, '/run', params, input)
27
+ end
28
+
29
+ # Creates a hash and creates keys 'arg1', 'arg2', etc that points to
30
+ # the values in the arg_values array. This is basically only used by
31
+ # the run methods
32
+ def arg_params(arg_values)
33
+ params = {}
34
+ arg_values.each_index { |ii| params["arg#{ii + 1}"] = arg_values[ii] }
35
+ params
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ require 'open-uri'
2
+ require 'p4_web_api_client/models/server'
3
+
4
+ module P4WebApiClient
5
+ class Client
6
+ # Returns an array of Server objects representing people in the system.
7
+ def servers
8
+ arr = execute_method_no_body(:get, '/servers')
9
+ arr.map { |obj| Models::Server.new(obj) }
10
+ end
11
+
12
+ # Returns a P4WebApiClient::Models::Server for the login
13
+ def server(server)
14
+ server = server.server_id if server.is_a?(Models::Server)
15
+ obj = execute_method_no_body(:get, "/servers/#{URI.encode(server)}")
16
+ Models::Server.new(obj)
17
+ end
18
+
19
+ # Creates a new server in the system based on the Server instance
20
+ def create_server(server)
21
+ server = Models::Server.new(server) unless server.is_a?(Models::Server)
22
+ execute_method_with_body(:post, '/servers', server.to_internal_hash)
23
+ true
24
+ end
25
+
26
+ def update_server(server)
27
+ execute_method_with_body(:put, "/servers/#{URI.encode(server.server_id)}",
28
+ server.to_internal_hash)
29
+ true
30
+ end
31
+
32
+ def delete_server(server)
33
+ server = server.server_id if server.is_a?(Models::Server)
34
+ execute_method_no_body(:delete, "/servers/#{URI.encode(server)}")
35
+ true
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ require 'open-uri'
2
+ require 'p4_web_api_client/models/stream'
3
+
4
+ module P4WebApiClient
5
+ class Client
6
+ # Returns an array of Stream objects representing people in the system.
7
+ def streams
8
+ arr = execute_method_no_body(:get, '/streams')
9
+ arr.map { |obj| Models::Stream.new(obj) }
10
+ end
11
+
12
+ # Returns a P4WebApiClient::Models::Stream for the login
13
+ def stream(stream)
14
+ stream = stream.stream_id if stream.is_a?(Models::Stream)
15
+ obj = execute_method_no_body(:get, "/streams/#{URI.encode(stream)}")
16
+ Models::Stream.new(obj)
17
+ end
18
+
19
+ # Creates a new stream in the system based on the Stream instance
20
+ def create_stream(stream)
21
+ stream = Models::Stream.new(stream) unless stream.is_a?(Models::Stream)
22
+ execute_method_with_body(:post, '/streams', stream.to_internal_hash)
23
+ true
24
+ end
25
+
26
+ def update_stream(stream)
27
+ execute_method_with_body(:put, "/streams/#{URI.encode(stream.stream)}",
28
+ stream.to_internal_hash)
29
+ true
30
+ end
31
+
32
+ def delete_stream(stream)
33
+ stream = stream.stream_id if stream.is_a?(Models::Stream)
34
+ execute_method_no_body(:delete, "/streams/#{URI.encode(stream)}")
35
+ true
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,18 @@
1
+ require 'p4_web_api_client/models/triggers'
2
+
3
+ module P4WebApiClient
4
+ class Client
5
+ # Returns a single Triggers object representing the entire triggers table
6
+ # of the system. (See Triggers model for more details.)
7
+ def triggers
8
+ obj = execute_method_no_body(:get, '/triggers')
9
+ Models::Triggers.new(obj)
10
+ end
11
+
12
+ # Update the triggers table using the Triggers model instance
13
+ def update_triggers(triggers)
14
+ execute_method_with_body(:put, '/triggers', triggers.to_internal_hash)
15
+ true
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,38 @@
1
+ require 'open-uri'
2
+ require 'p4_web_api_client/models/user'
3
+
4
+ module P4WebApiClient
5
+ class Client
6
+ # Returns an array of User objects representing people in the system.
7
+ def users
8
+ arr = execute_method_no_body(:get, '/users')
9
+ arr.map { |obj| Models::User.new(obj) }
10
+ end
11
+
12
+ # Returns a P4WebApiClient::Models::User for the login
13
+ def user(user)
14
+ user = user.user if user.is_a?(Models::User)
15
+ obj = execute_method_no_body(:get, "/users/#{URI.encode(user)}")
16
+ Models::User.new(obj)
17
+ end
18
+
19
+ # Creates a new user in the system based on the User instance
20
+ def create_user(user)
21
+ user = Models::User.new(user) unless user.is_a?(Models::User)
22
+ execute_method_with_body(:post, '/users', user.to_internal_hash)
23
+ true
24
+ end
25
+
26
+ def update_user(user)
27
+ execute_method_with_body(:put, "/users/#{URI.encode(user.user)}",
28
+ user.to_internal_hash)
29
+ true
30
+ end
31
+
32
+ def delete_user(user)
33
+ user = user.user if user.is_a?(Models::User)
34
+ execute_method_no_body(:delete, "/users/#{URI.encode(user)}")
35
+ true
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,86 @@
1
+
2
+ require 'json'
3
+ require 'open-uri'
4
+ require 'p4_web_api_client/version'
5
+ require 'p4_web_api_client/errors'
6
+ require 'p4_web_api_client/models'
7
+
8
+ module P4WebApiClient
9
+ # Each client instance represents a single 'session' against the P4 Web API.
10
+ #
11
+ # Access the client object like a typical I/O object - use open().
12
+ #
13
+ # Most methods assert that the response is OK. When not OK, we throw an
14
+ # exception. See P4WebApiClient::Errors for the different exception classes.
15
+ #
16
+ # Many methods return 'model' objects that are basically 'dumb old objects',
17
+ # i.e., editing models will not make edits to the Perforce system. All
18
+ # modifying methods lie within this Client object, which typically binds to
19
+ # a single RPC call.
20
+ #
21
+ # TODO: URL to online documentation
22
+ class Client
23
+ # This is an instance of P4WebApiClient::Connection
24
+ attr_accessor :connection
25
+
26
+ # The host_url is just the method and host, e.g., http://example.com/
27
+ #
28
+ # The P4 Web API context should be set if you don't access URLs like
29
+ # POST http://example.com/p4/v1/sessions.
30
+ #
31
+ # Any client created via Client.new should take care to call close().
32
+ #
33
+ def initialize(connection)
34
+ @connection = connection
35
+ end
36
+
37
+ def close
38
+ connection.run_method_no_body(:delete,
39
+ "/sessions/#{connection.session_token}")
40
+ end
41
+
42
+ # Provides standard I/O style interface, where when called in a block,
43
+ # will automatically close() the client when done. Otherwise, your code
44
+ # should call client.close() manually.
45
+ def self.open(connection)
46
+ client = Client.new(connection)
47
+
48
+ if block_given?
49
+ yield client
50
+ else
51
+ return client
52
+ end
53
+ ensure
54
+ client.close if block_given? && client
55
+ end
56
+
57
+ private
58
+
59
+ def execute_method_no_body(method, path, params = nil)
60
+ response = connection.run_method_no_body(method, path, params)
61
+ JSON.parse(response.body) if response.body && !response.body.empty?
62
+ end
63
+
64
+ def execute_method_with_body(method, path, params = nil, body = nil)
65
+ response = connection.run_method_with_body(method, path, params, body)
66
+ JSON.parse(response.body) if response.body && !response.body.empty?
67
+ end
68
+ end
69
+ end
70
+
71
+ # The Client class has quite a few methods that deal with the different models
72
+ # occasionally in subtly different ways.
73
+ require 'p4_web_api_client/client/branches'
74
+ require 'p4_web_api_client/client/changes'
75
+ require 'p4_web_api_client/client/clients'
76
+ require 'p4_web_api_client/client/depots'
77
+ require 'p4_web_api_client/client/files'
78
+ require 'p4_web_api_client/client/groups'
79
+ require 'p4_web_api_client/client/jobs'
80
+ require 'p4_web_api_client/client/labels'
81
+ require 'p4_web_api_client/client/protections'
82
+ require 'p4_web_api_client/client/run'
83
+ require 'p4_web_api_client/client/servers'
84
+ require 'p4_web_api_client/client/streams'
85
+ require 'p4_web_api_client/client/triggers'
86
+ require 'p4_web_api_client/client/users'
@@ -0,0 +1,98 @@
1
+
2
+ require 'faraday'
3
+ require 'faraday_middleware'
4
+
5
+ module P4WebApiClient
6
+ # Adds common configuration to the Faraday connection, like, the host name,
7
+ # version, and context prefixes.
8
+ class Connection
9
+ attr_accessor :login, :prefix, :session_token
10
+
11
+ # See the options for Faraday.new, plus, the following fields:
12
+ # - :login
13
+ # - :password
14
+ # - :prefix - defaults to '/v1'
15
+ def initialize(options = {})
16
+ local_opts = [:login, :password, :prefix]
17
+ conn_options = options.select { |k| !local_opts.include?(k) }
18
+
19
+ @conn = Faraday.new(conn_options)
20
+
21
+ @session_token = nil
22
+ @login = options[:login]
23
+ @prefix = options.key?(:prefix) ? options[:prefix] : '/v1'
24
+
25
+ # When we're not initialized with a password, we may be on a insecure
26
+ # server, so don't even log in.
27
+ if options[:password] && !Connection.p4_ticket?(options[:password])
28
+ response = @conn.post(path_for('/sessions'),
29
+ login: @login,
30
+ password: options[:password])
31
+ assert_ok(response)
32
+
33
+ @session_token = response.body
34
+ else
35
+ # When the password looks like a p4 ticket (or maybe it's empty),
36
+ # we don't generate the session token
37
+ @session_token = options[:password] || ''
38
+ end
39
+ @conn.basic_auth(login, session_token)
40
+ end
41
+
42
+ def self.p4_ticket?(str)
43
+ /^[a-zA-Z0-9]{32,}$/.match(str) != nil
44
+ end
45
+
46
+ def run_method_no_body(method, path, params = nil)
47
+ path = path_for(path)
48
+
49
+ response = @conn.send(method, path, params)
50
+ assert_ok(response)
51
+ response
52
+ end
53
+
54
+ def run_method_with_body(method, path, params = nil, body = nil)
55
+ if !body && params
56
+ body = params
57
+ params = nil
58
+ end
59
+
60
+ path = path_for(path)
61
+
62
+ if params
63
+ params_hash = Faraday::Utils::ParamsHash.new
64
+ params_hash.merge!(params)
65
+ path += "?#{params_hash.to_query}"
66
+ end
67
+
68
+ response = @conn.send(method, path, body)
69
+ assert_ok(response)
70
+ response
71
+ end
72
+
73
+ # Basically just prepends the prefix to our subpath, typically, '/p4'.
74
+ def path_for(subpath)
75
+ if @prefix.empty?
76
+ subpath
77
+ else
78
+ File.join(@prefix, subpath)
79
+ end
80
+ end
81
+
82
+ # Raises an error when the response is not 200. Some errors may have
83
+ # diagnostic information in the response body, so we pass that on as well
84
+ def assert_ok(response)
85
+ return unless response.status >= 400
86
+ if response.status == 403
87
+ fail Errors::Unauthenticated.new, 'Illegal login or password'
88
+ elsif response.status == 404
89
+ fail Errors::ResourceNotFound.new, 'Required resource not found'
90
+ elsif response.status == 500 && response.body
91
+ fail Errors::PerforceProblem.new(JSON.parse(response.body)),
92
+ 'Unknown issue from the Perforce server'
93
+ else
94
+ fail Errors::ServerError.new, 'Unknown problem'
95
+ end
96
+ end
97
+ end
98
+ end