Class: HelixVersioningEngine::HVEProjectsService

Inherits:
Object
  • Object
show all
Defined in:
lib/helix_versioning_engine/hve_projects_service.rb

Overview

Define simple projects based on a single directory location in a Helix Versioning Engine.

This project service uses the HVE_PROJECTS_PATH setting to list available projects on the particular server. If you only have one Helix Versioning Engine, it's suitable to create this as a systemwide default. Otherwise, you likely only want to specify this via headers.

This will return everything as “helix versioning engine” project.

Constant Summary

HVE_CONTENT_TYPE =
'application/vnd.perforce.project.hve.v1+json'
HVE_ID =
'hveProject'

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (HVEProjectsService) initialize(env: nil)

Returns a new instance of HVEProjectsService



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

def initialize(env: nil)
  @env = env
end

Instance Attribute Details

- (Object) env

Rack environment.



24
25
26
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 24

def env
  @env
end

Instance Method Details

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

Generate a new client that only contains the project mapping.

The client name is a combination of user, project, and device. We prefix it with “_hve” just for clarity.

We do not host lock the client.

Parameters:

  • project_id (String)

    Our encoded project name

  • device (String)

    A device ID, like a hostname

  • root (String)

    The Root value for the client parameter



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 88

def create_client(project_id, device, root)
  client_name = "_hve_#{user}_#{project_id}_#{device}"

  client_spec = p4.fetch_client(client_name)

  client_spec._root = root;
  client_spec._host = nil;

  client_spec._options = 'allwrite noclobber nocompress unlocked nomodtime rmdir';

  project_name = unencode_name(project_id)

  client_spec._view = [
      %Q|"#{depot_path_for_name(project_name)}/..." "//#{client_name}/..."|
  ]

  results = p4.save_client(client_spec)
  puts "new client results: #{results}"

  client_name
end

- (Object) create_pending_change(project_id)

If the user doesn't have a current pending change for the project, create one, and return that.



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 139

def create_pending_change(project_id)
  change = find_pending_change_for_project(project_id)

  return change if change

  change_spec = p4.fetch_change
  change_spec._description = "_hws_#{user}_#{project_id}"

  save_results = p4.save_change(change_spec)

  change = save_results.first.gsub(/Change (\d+) created./, '\1')

  # If we don't reset the client of this pending change, we won't be able
  # to cleanup the temporary client.
  change_spec = p4.fetch_change(change)
  change_spec._client = 'INVALID'
  p4.save_change(change_spec)

  change
end

- (Object) depot_path_for_name(name)



172
173
174
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 172

def depot_path_for_name(name)
  "#{hve_projects_path}/#{name}"
end

- (Object) encode_name(name)



160
161
162
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 160

def encode_name(name)
  HWSStrings.component_encode(name)
end

- (Object) fetch(id)

The ID is a URL encoded version of the directory name under HVE_PROJECTS_PATH.

This will unencode the ID and fetch by name.



56
57
58
59
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 56

def fetch(id)
  name = unencode_name(id)
  fetch_by_name(name)
end

- (Object) fetch_by_name(name)

Returns the project's “details” based on the project name.

No validation is done to ensure this directory actually exists in the system.



65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 65

def fetch_by_name(name)
  id = encode_name(name)

  {
      'id': id,
      'name': name,
      'server': server_uri_for_id(id),
      HVE_ID => {
          'depotPath': depot_path_for_name(name)
      }
  }
end

- (Object) find_latest_change_for_project(project_id)

Find the latest submitted change for the project

Use the 'p4 changes -m 1 -s submitted [depot path]'

Parameters:

  • project_id (String)

    The encoded project ID



115
116
117
118
119
120
121
122
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 115

def find_latest_change_for_project(project_id)
  project_name = unencode_name(project_id)
  depot_path = depot_path_for_name(project_name)

  results = p4.run_changes('-m', '1', '-s', 'submitted', "#{depot_path}/...")

  results.first['change'] unless results.empty?
end

- (Object) find_pending_change_for_project(project_id)

The HVE project 'changelist' is a pending changelist whose description is hve[user]_[project_id]

We use 'changes -l' to find the change to match potentially long project names.



129
130
131
132
133
134
135
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 129

def find_pending_change_for_project(project_id)
  results = p4.run_changes('-l', '-u', user, '-s', 'pending')

  change = results.find { |r| r['desc'].include?(project_id) }

  change['change'] if change
end

- (Object) hve_projects_path



180
181
182
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 180

def hve_projects_path
  env['hws_settings'].HVE_PROJECTS_PATH || fail('HVE_PROJECTS_PATH not set')
end

- (Object) list(details: false, extension: nil)

List HVE Projects as configured in the system.

See the Appendix in the documentation for details on values.



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 33

def list(details: false, extension: nil)
  return if extension and (extension != HVE_ID or extension != HVE_CONTENT_TYPE)

  project_dirs = list_project_names
  project_names = project_dirs.map { |d| File.basename(d) }

  if details
    project_names.map { |n| fetch_by_name(n) }
  else
    project_names.map { |n| encode_name(n) }
  end
end

- (Object) list_project_names



46
47
48
49
50
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 46

def list_project_names
  pattern = "#{hve_projects_path}/*"
  results = p4.run_dirs(pattern)
  results.map { |r| r['dir'] }
end

- (Object) p4



176
177
178
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 176

def p4
  env['p4'] || fail('p4 required to use HVEProjects')
end

- (Object) p4host



220
221
222
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 220

def p4host
  env['hws_settings'].P4HOST
end

- (Object) p4port



216
217
218
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 216

def p4port
  env['hws_settings'].P4PORT || fail('P4PORT setting not available')
end

- (Object) safe_hve_projects_path



184
185
186
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 184

def safe_hve_projects_path
  hve_projects_path.gsub('//', '/')
end

- (Object) server



207
208
209
210
211
212
213
214
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 207

def server
  return p4port if p4port.include?(':')

  host = p4host ? p4host : 'localhost'
  port = p4port

  "#{host}:#{port}"
end

- (Object) server_uri_for_id(id)



168
169
170
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 168

def server_uri_for_id(id)
  "p4://#{userinfo}#{server}#{safe_hve_projects_path}/#{id}"
end

- (Object) unencode_name(name)



164
165
166
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 164

def unencode_name(name)
  HWSStrings.component_decode(name)
end

- (Object) user



188
189
190
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 188

def user
  env['AUTH_CREDENTIALS'].first
end

- (Object) userinfo

For HVE Projects, it may be interesting to people to see various connection settings for each server URL.



194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/helix_versioning_engine/hve_projects_service.rb', line 194

def userinfo
  data = {}
  if env['hws_settings'].P4CHARSET
    data['P4CHARSET'] = env['hws_settings'].P4CHARSET
  end
  if data.keys.empty?
    ''
  else
    encoded_data = data.map {|k,v| "#{k}=#{v}"}.join(';')
    "#{encoded_data}@"
  end
end