p4_web_api_client 2014.2.0.pre1

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 (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