Class: HelixWebServicesClient

Inherits:
Object
  • Object
show all
Defined in:
lib/helix_web_services_client.rb,
lib/helix_web_services_client/jobs.rb,
lib/helix_web_services_client/login.rb,
lib/helix_web_services_client/files.rb,
lib/helix_web_services_client/users.rb,
lib/helix_web_services_client/config.rb,
lib/helix_web_services_client/depots.rb,
lib/helix_web_services_client/labels.rb,
lib/helix_web_services_client/groups.rb,
lib/helix_web_services_client/changes.rb,
lib/helix_web_services_client/servers.rb,
lib/helix_web_services_client/streams.rb,
lib/helix_web_services_client/version.rb,
lib/helix_web_services_client/clients.rb,
lib/helix_web_services_client/branches.rb,
lib/helix_web_services_client/projects.rb,
lib/helix_web_services_client/commands.rb,
lib/helix_web_services_client/triggers.rb,
lib/helix_web_services_client/counters.rb,
lib/helix_web_services_client/helix_sync.rb,
lib/helix_web_services_client/protections.rb,
lib/helix_web_services_client/git_fusion_keys.rb,
lib/helix_web_services_client/git_fusion_repo.rb

Overview

The client object handles authenticating and making calls to Helix Web Services.

See our user guide online at: swarm.workshop.perforce.com/projects/perforce-software-helix-web-services/view/main/build/doc/p4ws.html#ruby_client_sdk_overview

Constant Summary

INITIALIZE_LOCAL_OPTIONS =

Some values to initialize are only used by this class, and are not passed on to the Faraday initializer

[:user, :password, :ticket, :prefix, :api_level, :settings, :debug]
VERSION =
'2015.1.0.pre1'

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (HelixWebServicesClient) initialize(options)

Client initialization can handle ensuring a valid security token to the server.

Any client created via new should take care to call close().

Available Options

These options are used to configure the underlying Faraday connection:

  • :url - String base URL.

  • :params - Hash of URI query unencoded key/value pairs.

  • :header - Hash of unencoded HTTP header key/value pairs.

  • :request - Hash of request options.

  • :ssl - Hash of SSL options.

  • :proxy - Hash of Proxy options.

These options are specific to Helix Web Services:

  • :user - The Helix Versioning Engine login

  • :password - If set, we will generate a ticket using this password during initialization

  • :ticket - If not nil, we will use this ticket as our authentication password

  • :debug - Add response logging if set to true

Parameters:

  • options (Hash)

    See the section available options above



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/helix_web_services_client.rb', line 56

def initialize(options)
  @api_level = options.key?(:api_level) ? options[:api_level] : '78'

  # Filter out options we pass to Faraday
  faraday_options = options.select { |k| !INITIALIZE_LOCAL_OPTIONS.include?(k) }

  @conn = Faraday.new(faraday_options) do |conn|
    conn.request :multipart
    conn.request :url_encoded
    conn.response :logger if options[:debug]
    conn.adapter :net_http
  end

  @conn.headers['Accept'] = 'application/json'

  if options.key?(:url)
    url = URI(options[:url])
    @prefix = url.path ? url.path : ''
  end

  @user = options[:user] if options.key?(:user)

  @ticket = options[:ticket] if options.key?(:ticket)

  if options.key?(:settings)
    options[:settings].each do |key, value|
      add_setting(key, value)
    end
  end

  if options.key?(:password) and @user
    response = @conn.post(path_for('/projects/v1/login'),
                          user: user, password: options[:password])
    assert_ok(response)
    @ticket = JSON.parse(response.body)['ticket']
  end

  set_auth(user, ticket) unless ticket.nil?
end

Instance Attribute Details

- (Object) api_level

The API level to use. Defaults to 78 (2015.1)



26
27
28
# File 'lib/helix_web_services_client.rb', line 26

def api_level
  @api_level
end

- (Object) prefix

Typically, Helix Web Services is mounted under /hws behind a reverse proxy. If a path is specified in the originating URL, we save the prefix here, and preprend it to every request.



23
24
25
# File 'lib/helix_web_services_client.rb', line 23

def prefix
  @prefix
end

- (Object) ticket

Upon successful login, we store the P4 ticket return value here.



18
19
20
# File 'lib/helix_web_services_client.rb', line 18

def ticket
  @ticket
end

- (Object) user

The Helix Versioning Engine login



15
16
17
# File 'lib/helix_web_services_client.rb', line 15

def user
  @user
end

Class Method Details

+ (Object) open(connection)

Provides standard I/O style interface, where when called in a block, will automatically close() the client when done. Otherwise, your code should call client.close() manually.



121
122
123
124
125
126
127
128
129
130
131
# File 'lib/helix_web_services_client.rb', line 121

def self.open(connection)
  client = Client.new(connection)

  if block_given?
    yield client
  else
    return client
  end
ensure
  client.close if block_given? && client
end

Instance Method Details

- (Object) add_key(user, key_name, key)

Add a key for a specified user. It will try to add a new SSH key for specified user under a specific name. It will fail if the same key belongs to a different user, if the same key is under a different name and if there is already a key under the specified name. In case key with the same content is present for specified user under the same name - it will skip re-submission.

Parameters:

  • user (String)

    Username to assign SSH key to

  • key_name (String)

    File name to save the key under

  • key (String)

    Content of SSH key



27
28
29
30
# File 'lib/helix_web_services_client/git_fusion_keys.rb', line 27

def add_key(user, key_name, key)
  path = "/git-fusion/v1/users/#{user}/keys/#{key_name}"
  execute_method_with_body(:put, path, {'key' => key})
end

- (Object) add_setting(key, value)

Set an override for all requests.

See “configuration” in HWS documentation.

This will automatically add the right prefix for overriding an HWS setting.

Parameters:

  • key (String)

    The setting value as indicated in documentation, e.g., P4PORT

  • value (String)

    The value to set



107
108
109
110
111
# File 'lib/helix_web_services_client.rb', line 107

def add_setting(key, value)
  # Note: Rack will automatically convert all hyphens to underscores...
  # but Nginx will (by default) block all underscores. Find a happy middle.
  @conn.headers["X-Perforce-Helix-Web-Services-#{key.gsub('_', '-')}"] = value
end

- (Object) arg_params(arg_values)

Creates a hash and creates keys 'arg1', 'arg2', etc that points to the values in the arg_values array. This is basically only used by the run methods



45
46
47
48
49
# File 'lib/helix_web_services_client/commands.rb', line 45

def arg_params(arg_values)
  params = {}
  arg_values.each_index { |ii| params["arg#{ii + 1}"] = arg_values[ii] }
  params
end

- (Object) assert_ok(response)

Raises an error when the response is not 200. Some errors may have diagnostic information in the response body, so we pass that on as well



210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/helix_web_services_client.rb', line 210

def assert_ok(response)
  return unless response.status >= 400
  if response.status == 400
    begin
      messages = JSON.parse(response.body)
    rescue Exception
      messages = response.body
    end
    fail Errors::BadRequest.new(messages)
  elsif response.status == 403
    fail Errors::Unauthenticated.new, 'Illegal login or password'
  elsif response.status == 404
    fail Errors::ResourceNotFound.new, 'Required resource not found'
  elsif response.status == 500 && response.body
    messages = nil
    begin
      messages = JSON.parse(response.body)
    rescue Exception => e
      messages = response.body
    end
    fail Errors::PerforceProblem.new(messages),
         'Unknown issue from the Perforce server'
  else
    fail Errors::ServerError.new, "Unknown problem. Response code: #{response.status}"
  end
end

- (Object) branch(branch)

Returns the branch instance indicated by the branch name (or model)



14
15
16
17
18
# File 'lib/helix_web_services_client/branches.rb', line 14

def branch(branch)
  branch = OpenModel.new(branch).branch unless branch.is_a?(String)
  obj = execute_method_with_body(:get, hve_path("branches/#{URI.encode(branch)}"))
  OpenModel.new(obj)
end

- (Object) branches

Array of Branch objects stored in the system. Not all fields will be filled out (e.g., view).



8
9
10
11
# File 'lib/helix_web_services_client/branches.rb', line 8

def branches
  arr = execute_method_no_body(:get, hve_path('branches'))
  arr.map { |a| OpenModel.new(a) }
end

- (Object) change(change)

Returns the Change indicated by the change number or model.

If there are files submitted with the change, the change.files field should be filled out.



21
22
23
24
25
# File 'lib/helix_web_services_client/changes.rb', line 21

def change(change)
  change_id = change.is_a?(OpenModel) ? change.change : change
  arr = execute_method_no_body(:get, hve_path("changes/#{change_id}"))
  OpenModel.new(arr.first)
end

- (Object) changes(options = nil)

List changelists in the system

options: - :max - cap the number of results - :status - :pending, :submitted, or :shelved (see Change) - :user - The perforce login to check out - :files - Depot path pattern to restrict changes to



12
13
14
15
# File 'lib/helix_web_services_client/changes.rb', line 12

def changes(options = nil)
  arr = execute_method_no_body(:get, hve_path('changes'), options)
  arr.map { |obj| OpenModel.new(obj) }
end

- (Object) client(client)

Returns the client instance indicated by the client name or model



12
13
14
15
16
# File 'lib/helix_web_services_client/clients.rb', line 12

def client(client)
  client = OpenModel.new(client).client unless client.is_a?(String)
  obj = execute_method_no_body(:get, hve_path("clients/#{URI.encode(client)}"))
  OpenModel.new(obj)
end

- (Object) clients

Array of Client objects stored in the system. Not all fields will be filled out (e.g., view).



6
7
8
9
# File 'lib/helix_web_services_client/clients.rb', line 6

def clients
  arr = execute_method_no_body(:get, hve_path('clients'))
  arr.map { |a| OpenModel.new(a) }
end

- (Object) close



96
97
# File 'lib/helix_web_services_client.rb', line 96

def close
end

- (OpenModel) command(cmd, *args)

Execute a Perforce command.

First argument should always be the command, followed by command line arguments.

Expect to always have an array of hashes as output.

Not all commands are allowed, since the command will be executed on the web server. In general, if your command requires a client workspace, it will likely fail, or be blocked.

Returns:

  • (OpenModel)

    wraps the output in an OpenModel instance



18
19
20
21
22
# File 'lib/helix_web_services_client/commands.rb', line 18

def command(cmd, *args)
  params = arg_params(args)
  arr = execute_method_no_body(:get, hve_path("commands/#{URI.encode(cmd)}"), params)
  arr.map { |a| OpenModel.new(a) } if arr.is_a?(Array)
end

- (Object) command_with_input(cmd, input, *args)

Generic run command with and input body.

The first argument is the general command, followed by the input data, then followed by additional command line arguments.

Expect the output to always be an array of hashes.

Not all commands are allowed, since the command will be executed on the web server. In general, if your command requires a client workspace, it will likely fail, or be blocked.



34
35
36
37
38
39
40
# File 'lib/helix_web_services_client/commands.rb', line 34

def command_with_input(cmd, input, *args)
  params = arg_params(args)
  params[:cmd] = cmd
  path = hve_path("commands/#{URI.encode(cmd)}")
  arr = execute_method_with_body(:post, path, params, input)
  arr.map { |a| OpenModel.new(a) } if arr.nil? == false and arr.is_a?(Array)
end

- (Object) commit_change(change)

Submits the shelved changelist.

This changelist should be pending, with no open files, and list of shelved changes. If you require resolves, this method will fail.

Parameters:

  • change (String)

    The changelist number



61
62
63
64
# File 'lib/helix_web_services_client/changes.rb', line 61

def commit_change(change)
  change_id = change.is_a?(OpenModel) ? change.change : URI.encode(change)
  execute_method_no_body(:post, hve_path("changes/#{change_id}"))
end

- (Object) counter(counter)

Return the counter hash for a particular counter key.

Parameters:

  • counter (String)

    The counter ID



14
15
16
17
# File 'lib/helix_web_services_client/counters.rb', line 14

def counter(counter)
  obj = execute_method_no_body(:get, hve_path("counters/#{URI.encode(counter)}"))
  OpenModel.new(obj)
end

- (Object) counters

List all counters in the system. Each counter typically has a counter and value attribute.



6
7
8
9
# File 'lib/helix_web_services_client/counters.rb', line 6

def counters
  arr = execute_method_no_body(:get, hve_path('counters'))
  arr.map { |a| OpenModel.new(a) }
end

- (Object) create_branch(branch)

Creates a new branch in the system.



21
22
23
24
# File 'lib/helix_web_services_client/branches.rb', line 21

def create_branch(branch)
  execute_method_with_body(:post, hve_path('branches'), branch)
  true
end

- (Object) create_change(change)

Creates a new changelist, that can be used for a few different tasks.

The change should be a hash with the following top-level keys:

  • Description: The change description (optional)

  • Files: An array of Hashes

Each hash in the Files array can contain these keys:

  • DepotFile: The depot path

  • Action: One of 'upload', 'move', or 'branch'

  • FromDepotFile: if action is 'move' or 'branch', the source file

  • Content: Base64-encoded file content for 'upload' actions

  • RequireVersion: Optional value for 'upload' actions, if set, will fail the upload if the current file version is not this version.

Parameters:

  • change (Hash)

    See method description



50
51
52
53
# File 'lib/helix_web_services_client/changes.rb', line 50

def create_change(change)
  change = OpenModel.new(change) unless change.is_a?(OpenModel)
  execute_method_with_body(:post, hve_path('changes'), nil, change.marshal_dump)
end

- (Object) create_client(client)

Creates a new client in the system.



19
20
21
22
23
# File 'lib/helix_web_services_client/clients.rb', line 19

def create_client(client)
  client = OpenModel.new(client) unless client.is_a?(OpenModel)
  execute_method_with_body(:post, hve_path('clients'), client.marshal_dump)
  true
end

- (Object) create_depot(depot)

Creates a new depot in the system.



20
21
22
23
# File 'lib/helix_web_services_client/depots.rb', line 20

def create_depot(depot)
  depot = OpenModel.new(depot) unless depot.is_a?(OpenModel)
  execute_method_with_body(:post, hve_path('depots'), depot.marshal_dump)
end

- (Object) create_group(group)

Creates a new group in the system.



20
21
22
23
# File 'lib/helix_web_services_client/groups.rb', line 20

def create_group(group)
  group = OpenModel.new(group) unless group.is_a?(OpenModel)
  execute_method_with_body(:post, hve_path('groups'), group.marshal_dump)
end

- (Object) create_helix_sync_device_client(project_id, device, root)

Create a new client workspace specification for a Helix Sync project.

Returns a simple object with a 'client' property.



8
9
10
11
12
13
14
15
# File 'lib/helix_web_services_client/helix_sync.rb', line 8

def create_helix_sync_device_client(project_id, device, root)
  data = {
      device: device,
      root: root
  }
  obj = execute_method_with_body(:post, "/helix-sync/v1/#{URI.encode(project_id)}/clients/device", nil, data)
  OpenModel.new(obj)
end

- (Object) create_helix_sync_shelf_client(project_id)



17
18
19
20
# File 'lib/helix_web_services_client/helix_sync.rb', line 17

def create_helix_sync_shelf_client(project_id)
  obj = execute_method_no_body(:post, "/helix-sync/v1/#{URI.encode(project_id)}/clients/shelf")
  OpenModel.new(obj)
end

- (Object) create_job(job)

Creates a new job in the system.



19
20
21
22
23
24
25
# File 'lib/helix_web_services_client/jobs.rb', line 19

def create_job(job)
  job = OpenModel.new(job) unless job.is_a?(OpenModel)
  job.Job = 'new' unless job.job
  job.Status = 'open' unless job.status
  execute_method_with_body(:post, hve_path('jobs'),
                           job.marshal_dump)
end

- (Object) create_label(label)

Creates a new label in the system.



20
21
22
23
# File 'lib/helix_web_services_client/labels.rb', line 20

def create_label(label)
  label = OpenModel.new(label) unless label.is_a?(OpenModel)
  execute_method_with_body(:post, hve_path('labels'), label.marshal_dump)
end

- (Object) create_server(server)

Creates a new server in the system based on the Server instance



19
20
21
22
# File 'lib/helix_web_services_client/servers.rb', line 19

def create_server(server)
  server = OpenModel.new(server) unless server.is_a?(OpenModel)
  execute_method_with_body(:post, hve_path('servers'), server.marshal_dump)
end

- (Object) create_stream(stream)

Creates a new stream in the system based on the Stream instance



21
22
23
24
# File 'lib/helix_web_services_client/streams.rb', line 21

def create_stream(stream)
  stream = OpenModel.new(stream) unless stream.is_a?(OpenModel)
  execute_method_with_body(:post, hve_path('streams'), stream.marshal_dump)
end

- (Object) create_user(user)

Creates a new user in the system based on the User instance



19
20
21
22
# File 'lib/helix_web_services_client/users.rb', line 19

def create_user(user)
  user = OpenModel.new(user) unless user.is_a?(OpenModel)
  execute_method_with_body(:post, hve_path('users'), user.marshal_dump)
end

- (Object) delete_branch(branch)

Deletes the branch specification in the system.



35
36
37
38
39
# File 'lib/helix_web_services_client/branches.rb', line 35

def delete_branch(branch)
  branch = OpenModel.new(branch).branch unless branch.is_a?(String)
  execute_method_no_body(:delete, hve_path("branches/#{URI.encode(branch)}"))
  true
end

- (Object) delete_client(client)

Deletes the client specification in the system.



34
35
36
37
38
# File 'lib/helix_web_services_client/clients.rb', line 34

def delete_client(client)
  client = OpenModel.new(client).client unless client.is_a?(String)
  execute_method_no_body(:delete, hve_path("clients/#{URI.encode(client)}"))
  true
end

- (Object) delete_counter(counter)

Delete the counter

Parameters:

  • counter (String)

    The counter ID



37
38
39
# File 'lib/helix_web_services_client/counters.rb', line 37

def delete_counter(counter)
  execute_method_no_body(:delete, hve_path("counters/#{URI.encode(counter)}"))
end

- (Object) delete_depot(depot)

Deletes the depot specification in the system.



33
34
35
36
# File 'lib/helix_web_services_client/depots.rb', line 33

def delete_depot(depot)
  depot = depot.depot if depot.is_a?(OpenModel)
  execute_method_no_body(:delete, hve_path("depots/#{URI.encode(depot)}"))
end

- (Object) delete_file(path)



106
107
108
109
# File 'lib/helix_web_services_client/files.rb', line 106

def delete_file(path)
  path = encode_path(path)
  execute_method_no_body(:delete, hve_path("files/#{path}"))
end

- (Object) delete_group(group)

Deletes the group specification in the system.



33
34
35
36
# File 'lib/helix_web_services_client/groups.rb', line 33

def delete_group(group)
  group = group.group if group.is_a?(OpenModel)
  execute_method_no_body(:delete, hve_path("groups/#{URI.encode(group)}"))
end

- (Object) delete_helix_sync_device_client(project_id, device)



22
23
24
25
# File 'lib/helix_web_services_client/helix_sync.rb', line 22

def delete_helix_sync_device_client(project_id, device)
  obj = execute_method_no_body(:delete, "/helix-sync/v1/#{URI.encode(project_id)}/clients/device/#{URI.encode(device)}")
  OpenModel.new(obj)
end

- (Object) delete_helix_sync_pending_changelist(project_id)

Remove the pending changelist used for a Helix Sync project.



49
50
51
52
# File 'lib/helix_web_services_client/helix_sync.rb', line 49

def delete_helix_sync_pending_changelist(project_id)
  obj = execute_method_no_body(:delete, "/helix-sync/v1/#{URI.encode(project_id)}/pending")
  OpenModel.new(obj)
end

- (Object) delete_helix_sync_shelf_client(project_id)



27
28
29
30
# File 'lib/helix_web_services_client/helix_sync.rb', line 27

def delete_helix_sync_shelf_client(project_id)
  obj = execute_method_no_body(:delete, "/helix-sync/v1/#{URI.encode(project_id)}/clients/shelf")
  OpenModel.new(obj)
end

- (Object) delete_job(job_id)

Deletes the job specification in the system.



35
36
37
# File 'lib/helix_web_services_client/jobs.rb', line 35

def delete_job(job_id)
  execute_method_no_body(:delete, hve_path("jobs/#{URI.encode(job_id)}"))
end

- (Object) delete_key(user, key_name)

Delete a specific SSH key. It accepts an SSH key looks up the owner and then proceeds to remove it.

Parameters:

  • key (String)

    SSH key string to be removed



35
36
37
38
# File 'lib/helix_web_services_client/git_fusion_keys.rb', line 35

def delete_key(user, key_name)
  path = "/git-fusion/v1/users/#{user}/keys/#{key_name}"
  execute_method_no_body(:delete, path)
end

- (Object) delete_keys(user)

Delete all keys for a user. All keys for specified user will be deleted from perforce.

Parameters:

  • user (String)

    Chosen user to remove all keys for



43
44
45
46
# File 'lib/helix_web_services_client/git_fusion_keys.rb', line 43

def delete_keys(user)
  path = "/git-fusion/v1/users/#{user}/keys"
  execute_method_no_body(:delete, path)
end

- (Object) delete_label(label)

Deletes the label specification in the system.



33
34
35
36
# File 'lib/helix_web_services_client/labels.rb', line 33

def delete_label(label)
  label = label.label if label.is_a?(OpenModel)
  execute_method_no_body(:delete, hve_path("labels/#{URI.encode(label)}"))
end

- (Object) delete_repo(repo_name)

Delete a repository. This will remove config file for specified repository, removing it in result.

Parameters:

  • repo_name (String)

    Repository name to be encoded to git_fusion standards



57
58
59
60
# File 'lib/helix_web_services_client/git_fusion_repo.rb', line 57

def delete_repo(repo_name)
  path = "/git-fusion/v1/repos/#{GitFusionStrings.encode(repo_name)}"
  execute_method_no_body(:delete, path)
end

- (Object) delete_server(server)



31
32
33
34
# File 'lib/helix_web_services_client/servers.rb', line 31

def delete_server(server)
  server = server.server_id if server.is_a?(OpenModel)
  execute_method_no_body(:delete, hve_path("servers/#{URI.encode(server)}"))
end

- (Object) delete_stream(stream)



32
33
34
35
# File 'lib/helix_web_services_client/streams.rb', line 32

def delete_stream(stream)
  stream = stream.stream if stream.is_a?(OpenModel)
  execute_method_no_body(:delete, hve_path("streams/#{URI.encode(stream)}"))
end

- (Object) delete_user(user)



30
31
32
33
# File 'lib/helix_web_services_client/users.rb', line 30

def delete_user(user)
  user = user.user if user.is_a?(OpenModel)
  execute_method_no_body(:delete, hve_path("users/#{URI.encode(user)}"))
end

- (Object) depot(depot)

Returns the depot instance indicated by the depot name (or depot object)



13
14
15
16
17
# File 'lib/helix_web_services_client/depots.rb', line 13

def depot(depot)
  depot = depot.depot if depot.is_a?(OpenModel)
  obj = execute_method_no_body(:get, hve_path("depots/#{URI.encode(depot)}"))
  OpenModel.new(obj)
end

- (Object) depots

Array of Depot objects stored in the system. Not all fields will be filled out (e.g., view).



7
8
9
10
# File 'lib/helix_web_services_client/depots.rb', line 7

def depots
  arr = execute_method_no_body(:get, hve_path('depots'))
  arr.map { |a| OpenModel.new(a) }
end

- (Object) encode_component(str)

Parameters:

  • str (String)

    Component to be URI escaped



52
53
54
55
56
57
58
59
60
# File 'lib/helix_web_services_client/git_fusion_keys.rb', line 52

def encode_component(str)
  str.chars.map do |ch|
    if GitFusionStrings::URI_RESERVED_CHARACTERS.include?(ch)
      '%' + ch.ord.to_s(16)
    else
      ch
    end
  end.join('')
end

- (Object) execute_method_no_body(method, path, params = nil)

Runs the method against Helix Web Services, checks for errors, then parses the JSON response.

Parameters:

  • method (Symbol)

    HTTP method, for example, :get, :post, :delete

  • path (String)

    URL path part (no URI parameters) for the method

  • params (Hash) (defaults to: nil)

    URI parameters to send in



150
151
152
153
# File 'lib/helix_web_services_client.rb', line 150

def execute_method_no_body(method, path, params = nil)
  response = run_method_no_body(method, path, params)
  JSON.parse(response.body) if response.body && !response.body.empty?
end

- (Object) execute_method_with_body(method, path, params = nil, body = nil)

Runs the method against Helix Web Services, checks for errors, then parses the JSON response.

This variation will send the body (expected to be a Hash) as JSON to the server.

Parameters:

  • method (Symbol)

    HTTP method, for example, :get, :post, :delete

  • path (String)

    URL path part (no URI parameters) for the method

  • params (Hash) (defaults to: nil)

    URI parameters to send in

  • body (Hash) (defaults to: nil)

    The Request content (which will be converted to JSON)



165
166
167
168
# File 'lib/helix_web_services_client.rb', line 165

def execute_method_with_body(method, path, params = nil, body = nil)
  response = run_method_with_body(method, path, params, body)
  JSON.parse(response.body) if response.body && !response.body.empty?
end

- (Object) fetch_helix_sync_latest_changelist(project_id)

Retrieve the latest changelist.

If the change doesn't exist, you'll get a ResourceNotFound exception.



35
36
37
38
# File 'lib/helix_web_services_client/helix_sync.rb', line 35

def fetch_helix_sync_latest_changelist(project_id)
  obj = execute_method_no_body(:get, "/helix-sync/v1/#{URI.encode(project_id)}/last-change")
  OpenModel.new(obj)
end

- (Object) fetch_helix_sync_pending_changelist(project_id)

Retrieve the pending changelist.

If the change doesn't exist, you'll get a ResourceNotFound exception.



43
44
45
46
# File 'lib/helix_web_services_client/helix_sync.rb', line 43

def fetch_helix_sync_pending_changelist(project_id)
  obj = execute_method_no_body(:get, "/helix-sync/v1/#{URI.encode(project_id)}/pending")
  OpenModel.new(obj)
end

- (Object) file(path)

Returns the file metadata at this location, with the content field filled out.

If path happens to be a directory, this method is synonymous with the files() method.



48
49
50
# File 'lib/helix_web_services_client/files.rb', line 48

def file(path)
  files(path)
end

- (Object) files(path = '')

General file browsing method.

The path parameter should be a directory location, starting with a depot location, e.g., my_depot/dir1.

When path is empty, will return the list of depots.

Note: if path happens to be a file, instead of a directory, this is a synonym with the file() method.

If the path contains wildcards, the return will only be the list of HelixWebServicesClient::Models::File instances.

See also the HelixWebServicesClient::Models::File, HelixWebServicesClient::Models::Dir, and HelixWebServicesClient::Models::Depot for the output types.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/helix_web_services_client/files.rb', line 21

def files(path = '')
  unless path.empty?
    path = path.split('/').map { |p| URI.encode(p) }.join('/')
  end

  arr = nil

  if wildcards?(path)
    arr = execute_method_no_body(:get, hve_path('files'), path: path)
  else
    arr = execute_method_no_body(:get, hve_path("files/#{path}"))
  end

  if arr.is_a?(Array)
    arr.map{ |x| OpenModel.new(x) }
  else
    m = OpenModel.new(arr)
    m.Content = Base64.decode64(m.content)
    m
  end
end

- (Object) group(group)

Returns the group instance indicated by the group name (or group object)



13
14
15
16
17
# File 'lib/helix_web_services_client/groups.rb', line 13

def group(group)
  group = group.group if group.is_a?(OpenModel)
  obj = execute_method_no_body(:get, hve_path("groups/#{URI.encode(group)}"))
  OpenModel.new(obj)
end

- (Object) groups

Array of Group objects stored in the system. Not all fields will be filled out (e.g., view).



7
8
9
10
# File 'lib/helix_web_services_client/groups.rb', line 7

def groups
  arr = execute_method_no_body(:get, hve_path('groups'))
  arr.map { |x| OpenModel.new(x) }
end

- (Object) hve_path(subpath)



237
238
239
# File 'lib/helix_web_services_client.rb', line 237

def hve_path(subpath)
  "/p4/v#{api_level}/#{subpath}"
end

- (Object) increment_counter(counter)

Increment the value of a numerical counter

Parameters:

  • counter (String)

    The counter ID



22
23
24
# File 'lib/helix_web_services_client/counters.rb', line 22

def increment_counter(counter)
  execute_method_no_body(:post, hve_path("counters/#{URI.encode(counter)}/increment"))
end

- (Object) job(job_id)

Returns the array of jobs in the system. Each job model is simply a hash of string -> string values, since each system can very likely adjust job output.



13
14
15
16
# File 'lib/helix_web_services_client/jobs.rb', line 13

def job(job_id)
  obj = execute_method_no_body(:get, hve_path("jobs/#{URI.encode(job_id)}"))
  OpenModel.new(obj)
end

- (Object) jobs



5
6
7
8
# File 'lib/helix_web_services_client/jobs.rb', line 5

def jobs
  arr = execute_method_no_body(:get, hve_path('jobs'))
  arr.map { |x| OpenModel.new(x) }
end

- (Object) keys(user)

Return all keys for specified user. Every entry contains key name and its contents.

Parameters:

  • user (String)

    Username for which keys will be fetched



13
14
15
16
# File 'lib/helix_web_services_client/git_fusion_keys.rb', line 13

def keys(user)
  path = "/git-fusion/v1/users/#{user}/keys"
  execute_method_no_body(:get, path)
end

- (Object) label(label)

Returns the label instance indicated by the label name (or label object)



13
14
15
16
17
# File 'lib/helix_web_services_client/labels.rb', line 13

def label(label)
  label = label.label if label.is_a?(OpenModel)
  obj = execute_method_no_body(:get, hve_path("labels/#{URI.encode(label)}"))
  OpenModel.new(obj)
end

- (Object) labels

Array of Label objects stored in the system. Not all fields will be filled out (e.g., view).



7
8
9
10
# File 'lib/helix_web_services_client/labels.rb', line 7

def labels
  arr = execute_method_no_body(:get, hve_path('labels'))
  arr.map { |a| OpenModel.new(a) }
end

- (Object) list_repos

Return list of configured repositories. It will fetch all configured repositories returning a list of hashes with id and name of the repository, where id is a git-fusion encoded name, and name is a full human-readable string.



14
15
16
# File 'lib/helix_web_services_client/git_fusion_repo.rb', line 14

def list_repos
  execute_method_no_body(:get, '/git-fusion/v1/repos')
end

- (Object) login(user, password)

Generates a host unlocked ticket for the user.

In some installations, such as Helix Cloud, the authentication source is not the p4d instance used for connections. This allows you to generate p4 ticket which should then be passed along as the P4PASSWD per-request header.

Parameters:

  • user (String)
  • password (String)


11
12
13
14
15
# File 'lib/helix_web_services_client/login.rb', line 11

def (user, password)
  obj = execute_method_with_body(:post, hve_path('login'), nil,
                                 {user: user, password: password})
  obj['ticket']
end

- (Boolean) p4_ticket?(str)

Returns:

  • (Boolean)


140
141
142
# File 'lib/helix_web_services_client.rb', line 140

def p4_ticket?(str)
  /^[a-zA-Z0-9]{32,}$/.match(str) != nil
end

- (Object) path_for(subpath)

Basically just prepends the prefix to our subpath, typically, '/p4'.



198
199
200
201
202
203
204
205
206
# File 'lib/helix_web_services_client.rb', line 198

def path_for(subpath)
  if @prefix.nil? || @prefix.empty?
    subpath
  elsif subpath.nil? or subpath.empty?
    @prefix
  else
    File.join(@prefix, subpath)
  end
end

- (Object) preview_helix_sync_pending_change(project_id)

“Preview”, or generate the resolve plan, for the pending changelist.

If the change doesn't exist, you'll get a ResourceNotFound exception.



57
58
59
60
# File 'lib/helix_web_services_client/helix_sync.rb', line 57

def preview_helix_sync_pending_change(project_id)
  arr = execute_method_no_body(:get, "/helix-sync/v1/#{URI.encode(project_id)}/preview")
  arr.map { |o| OpenModel.new(o) }
end

- (Object) project(project_id)

Return the project details

Parameters:

  • project_id (String)

    The project's String id



23
24
25
26
27
# File 'lib/helix_web_services_client/projects.rb', line 23

def project(project_id)
  path = "/projects/v1/#{URI.encode(project_id)}"
  obj = execute_method_no_body(:get, path)
  OpenModel.new(obj)
end

- (Object) projects(details: nil, extension: nil)

Lists the projects available on the server for the user.

Parameters:

  • details (Boolean)

    Defaults to false, if true, output will be an array of project details. If false, output will be an array of project IDs.

  • extension (String)

    If set, will only return projects with the indicated extension ID.



11
12
13
14
15
16
17
18
# File 'lib/helix_web_services_client/projects.rb', line 11

def projects(details: nil, extension: nil)
  query = {}
  query[:details] = details if details
  query[:extension] = extension if extension
  arr = execute_method_no_body(:get, '/projects/v1', query)
  arr = arr.map { |a| OpenModel.new(a) } if details
  arr
end

- (Object) protections

Fetch all protections in the system. Returns a single Protections instance.



6
7
8
9
# File 'lib/helix_web_services_client/protections.rb', line 6

def protections
  obj = execute_method_no_body(:get, hve_path('protections'))
  OpenModel.new(obj)
end

- (Object) remove_setting(key)

Remove a setting added via add_setting



114
115
116
# File 'lib/helix_web_services_client.rb', line 114

def remove_setting(key)
  @conn.headers.delete("X-Perforce-Helix-Web-Services-#{key}")
end

- (Object) repo(repo_name)

Return the repository details. For specified repository it will fetch and return currently submitted configuration.

Parameters:

  • repo_name (String)

    Repository name to be encoded to git-fusion standards



22
23
24
25
# File 'lib/helix_web_services_client/git_fusion_repo.rb', line 22

def repo(repo_name)
  path = "/git-fusion/v1/repos/#{GitFusionStrings.encode(repo_name)}"
  execute_method_no_body(:get, path)
end

- (Object) run_method_no_body(method, path, params = nil)



170
171
172
173
174
175
176
# File 'lib/helix_web_services_client.rb', line 170

def run_method_no_body(method, path, params = nil)
  path = path_for(path)

  response = @conn.send(method, path, params)
  assert_ok(response)
  response
end

- (Object) run_method_with_body(method, path, params = nil, body = nil)



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/helix_web_services_client.rb', line 178

def run_method_with_body(method, path, params = nil, body = nil)
  if !body && params
    body = params
    params = nil
  end

  path = path_for(path)

  if params
    params_hash = Faraday::Utils::ParamsHash.new
    params_hash.merge!(params)
    path += "?#{params_hash.to_query}"
  end

  response = @conn.send(method, path, body)
  assert_ok(response)
  response
end

- (Object) server(server)

Returns a HelixWebServicesClient::OpenModel for the login



12
13
14
15
16
# File 'lib/helix_web_services_client/servers.rb', line 12

def server(server)
  server = server.ServerID if server.is_a?(OpenModel)
  obj = execute_method_no_body(:get, hve_path("servers/#{URI.encode(server)}"))
  OpenModel.new(obj)
end

- (Object) servers

Returns an array of Server objects representing people in the system.



6
7
8
9
# File 'lib/helix_web_services_client/servers.rb', line 6

def servers
  arr = execute_method_no_body(:get, hve_path('servers'))
  arr.map { |obj| OpenModel.new(obj) }
end

- (Object) services

Returns an array of all service definitions in the system. Each definition is a hash with type and uri values.



8
9
10
# File 'lib/helix_web_services_client/config.rb', line 8

def services
  execute_method_no_body(:get, '/config/v1/services')
end

- (Object) set_auth(user, token)

Note: this class is really just common implementation. Methods are generally defined in other files that reopen this class.



136
137
138
# File 'lib/helix_web_services_client.rb', line 136

def set_auth(user, token)
  @conn.basic_auth(user, token)
end

- (Object) set_counter(counter)

Set the counter value

Parameters:

  • counter (Hash|OpenModel)

    A has containing counter and value properties



29
30
31
32
# File 'lib/helix_web_services_client/counters.rb', line 29

def set_counter(counter)
  counter = OpenModel.new(counter) unless counter.is_a?(OpenModel)
  execute_method_with_body(:put, hve_path("counters/#{URI.encode(counter.counter)}"), counter.marshal_dump)
end

- (Object) stream(stream)

Fetch single stream details

Returns:

  • An OpenModel wrapper around the stream data



14
15
16
17
18
# File 'lib/helix_web_services_client/streams.rb', line 14

def stream(stream)
  stream = stream.stream if stream.is_a?(OpenModel)
  obj = execute_method_no_body(:get, hve_path("streams/#{URI.encode(stream)}"))
  OpenModel.new(obj)
end

- (Object) streams

Returns an array of Stream objects representing people in the system.



6
7
8
9
# File 'lib/helix_web_services_client/streams.rb', line 6

def streams
  arr = execute_method_no_body(:get, hve_path('streams'))
  arr.map { |obj| OpenModel.new(obj) }
end

- (Object) submit_config(repo_name, config)

Replace config for a specified repository. This will replace current config for a Git Fusion repo with a new one under the same name, for the same path.

Parameters:

  • repo_name (String)

    Repository name to be encoded to git-fusion standards

  • config (String)

    GitFusion config file



40
41
42
43
# File 'lib/helix_web_services_client/git_fusion_repo.rb', line 40

def submit_config(repo_name, config)
  path = "/git-fusion/v1/repos/#{GitFusionStrings.encode(repo_name)}"
  execute_method_with_body(:put, path, {'config' => config})
end

- (Object) submit_helix_sync_pending_change(project_id)

Submits the pending changelist for the helix sync project.

Currently this assumes that all files are shelved and nothing's open on the client. This is likely not what we want … but it's a start.

Parameters:

  • project_id (String)


68
69
70
71
# File 'lib/helix_web_services_client/helix_sync.rb', line 68

def submit_helix_sync_pending_change(project_id)
  obj = execute_method_no_body(:post, "/helix-sync/v1/#{URI.encode(project_id)}/submit")
  OpenModel.new(obj)
end

- (OpenModel) triggers

Fetch the list of trigger lines in the system.

Returns:

  • (OpenModel)

    A hash with a Triggers property that is an array of lines in the triggers table.



8
9
10
11
# File 'lib/helix_web_services_client/triggers.rb', line 8

def triggers
  obj = execute_method_no_body(:get, hve_path('triggers'))
  OpenModel.new(obj)
end

- (Object) update_branch(branch)

Updates the branch specification.



27
28
29
30
31
32
# File 'lib/helix_web_services_client/branches.rb', line 27

def update_branch(branch)
  branch = OpenModel.new(branch) unless branch.is_a?(OpenModel)
  execute_method_with_body(:patch, hve_path("branches/#{URI.encode(branch.branch)}"),
                           branch.marshal_dump)
  true
end

- (Object) update_client(client)

Updates the client specification.



26
27
28
29
30
31
# File 'lib/helix_web_services_client/clients.rb', line 26

def update_client(client)
  client = OpenModel.new(client) unless client.is_a?(OpenModel)
  execute_method_with_body(:patch, hve_path("clients/#{URI.encode(client.client)}"),
                           client.marshal_dump)
  true
end

- (Object) update_config(repo_name, config)

Modify config for a specified repository. This will update chosen parts of p4gf_file.

Parameters:

  • repo_name (String)

    Repository name to be encoded to git-fusion standards

  • config (String)

    String to update in current p4gf_config file



49
50
51
# File 'lib/helix_web_services_client/git_fusion_repo.rb', line 49

def update_config(repo_name, config)
  execute_method_with_body(:patch, "/git-fusion/v1/repos/#{GitFusionStrings.encode(repo_name)}", {'config' => config})
end

- (Object) update_depot(depot)

Updates the depot specification.



26
27
28
29
30
# File 'lib/helix_web_services_client/depots.rb', line 26

def update_depot(depot)
  depot = OpenModel.new(depot) unless depot.is_a?(OpenModel)
  execute_method_with_body(:patch, hve_path("depots/#{URI.encode(depot.depot)}"),
                           depot.marshal_dump)
end

- (Object) update_group(group)

Updates the group specification.



26
27
28
29
30
# File 'lib/helix_web_services_client/groups.rb', line 26

def update_group(group)
  group = OpenModel.new(group) unless group.is_a?(OpenModel)
  execute_method_with_body(:patch, hve_path("groups/#{URI.encode(group.group)}"),
                           group.marshal_dump)
end

- (Object) update_job(job)

Updates the job specification.



28
29
30
31
32
# File 'lib/helix_web_services_client/jobs.rb', line 28

def update_job(job)
  job = OpenModel.new(job) unless job.is_a?(OpenModel)
  execute_method_with_body(:patch, hve_path("jobs/#{URI.encode(job['Job'])}"),
                           job.marshal_dump)
end

- (Object) update_label(label)

Updates the label specification.



26
27
28
29
30
# File 'lib/helix_web_services_client/labels.rb', line 26

def update_label(label)
  label = OpenModel.new(label) unless label.is_a?(OpenModel)
  execute_method_with_body(:patch, hve_path("labels/#{URI.encode(label.label)}"),
                           label.marshal_dump)
end

- (Object) update_protections(protections)

Updates the protections table based on the Protections instance passed in

Parameters:

  • protections (Hash|OpenModel)

    A hash with a protections property that is an Array of protections entries



15
16
17
18
19
# File 'lib/helix_web_services_client/protections.rb', line 15

def update_protections(protections)
  protections = OpenModel.new(protections) unless protections.is_a?(OpenModel)
  execute_method_with_body(:put, hve_path('protections'),
                           protections.marshal_dump)
end

- (Object) update_server(server)



24
25
26
27
28
29
# File 'lib/helix_web_services_client/servers.rb', line 24

def update_server(server)
  server = OpenModel.new(server) unless server.is_a?(OpenModel)
  execute_method_with_body(:patch,
                           hve_path("servers/#{URI.encode(server.ServerID)}"),
                           server.marshal_dump)
end

- (Object) update_stream(stream)



26
27
28
29
30
# File 'lib/helix_web_services_client/streams.rb', line 26

def update_stream(stream)
  stream = OpenModel.new(stream) unless stream.is_a?(OpenModel)
  execute_method_with_body(:patch, hve_path("streams/#{URI.encode(stream.stream)}"),
                           stream.marshal_dump)
end

- (Object) update_triggers(triggers)

Update the triggers table using the Triggers model instance

Parameters:

  • triggers (Hash|OpenModel)

    A hash with a Triggers property



16
17
18
19
# File 'lib/helix_web_services_client/triggers.rb', line 16

def update_triggers(triggers)
  triggers = OpenModel.new(triggers) unless triggers.is_a?(OpenModel)
  execute_method_with_body(:put, hve_path('triggers'), triggers.marshal_dump)
end

- (Object) update_user(user)



24
25
26
27
28
# File 'lib/helix_web_services_client/users.rb', line 24

def update_user(user)
  user = OpenModel.new(user) unless user.is_a?(OpenModel)
  execute_method_with_body(:patch, hve_path("users/#{URI.encode(user.user)}"),
                           user.marshal_dump)
end

- (Object) upload_file(file)

Upload a single file's content.

The file hash should contain the following fields:

  • DepotFile: target depot path

  • Content: file content

Parameters:

  • file (Hash)

    See description



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/helix_web_services_client/files.rb', line 60

def upload_file(file)
  file = OpenModel.new(file) unless file.is_a?(OpenModel)
  path = encode_path(file.depot_file)
  body = {
      'DepotFile' => file.depot_file,
      'Content' => Base64.encode64(file.content)
  }
  execute_method_with_body(:patch,
                           hve_path("files/#{path}"),
                           nil,
                           body)
end

- (Object) upload_files(files: [], path: nil, description: nil)

Upload multiple files

Each file in the Files array should have two fields

  • DepotFile: target path, can be relative if path is indicated

  • Content: File content

The optional path parameter can indicate the root directory for all files.

Parameters:

  • files (Array)

    See description

  • path (String)

    If set, the root directory for all files

  • description (String)

    Informative message about the change



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/helix_web_services_client/files.rb', line 86

def upload_files(files: [], path: nil, description: nil)
  files = files.map do |f|
    OpenModel.new(f) unless f.is_a?(OpenModel)
  end

  path = path ? encode_path(path) : ''

  obj = {
      'Files' => files.map do |f|
        {
            'DepotFile' => f.depot_file,
            'Content' => Base64.encode64(f.content)
        }
      end
  }
  obj['Description'] = description if description

  execute_method_with_body(:patch, hve_path("files/#{path}"), nil, obj)
end

- (Object) user_details(user)

Returns a HelixWebServicesClient::OpenModel for the login



12
13
14
15
16
# File 'lib/helix_web_services_client/users.rb', line 12

def user_details(user)
  user = user.user if user.is_a?(OpenModel)
  obj = execute_method_no_body(:get, hve_path("users/#{URI.encode(user)}"))
  OpenModel.new(obj)
end

- (Object) users

Returns an array of User objects representing people in the system.



6
7
8
9
# File 'lib/helix_web_services_client/users.rb', line 6

def users
  arr = execute_method_no_body(:get, hve_path('users'))
  arr.map { |obj| OpenModel.new(obj) }
end

- (Object) version

Return the product version ID of the Helix Web Services instance



242
243
244
245
# File 'lib/helix_web_services_client.rb', line 242

def version
  response = run_method_no_body(:get, '/status')
  response.headers['X-Helix-Web-Services-Version']
end