nexus_cli 0.7.3 → 0.8.0

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.
@@ -1,113 +1,110 @@
1
- require 'restclient'
1
+ require 'httpclient'
2
2
  require 'nokogiri'
3
- require 'tempfile'
4
3
  require 'yaml'
5
4
 
6
5
  module NexusCli
7
6
  class ProRemote < OSSRemote
8
-
9
- def get_artifact_custom_info(artifact)
10
- return N3Metadata::n3_to_xml(get_artifact_custom_info_n3(artifact))
11
- end
12
-
13
- def get_artifact_custom_info_n3(artifact)
7
+ # Gets the custom metadata for an artifact
8
+ # @param [String] artifact The GAVE string of the artifact
9
+ # @result [String] The resulting custom metadata xml from the get operation
10
+ def get_artifact_custom_info_raw(artifact)
14
11
  group_id, artifact_id, version, extension = parse_artifact_string(artifact)
15
- get_string = N3Metadata::generate_n3_path(group_id, artifact_id, version, extension, configuration['repository'])
16
- begin
17
- n3 = nexus[get_string].get
18
- if !n3.match(/<urn:maven#deleted>/).nil?
19
- raise ArtifactNotFoundException
12
+ encoded_string = N3Metadata::create_base64_subject(group_id, artifact_id, version, extension)
13
+ response = nexus.get(nexus_url("service/local/index/custom_metadata/#{configuration['repository']}/#{encoded_string}"))
14
+ case response.status
15
+ when 200
16
+ if N3Metadata::missing_custom_metadata?(response.content)
17
+ raise N3NotFoundException
20
18
  else
21
- return n3
19
+ return response.content
22
20
  end
23
- rescue RestClient::ResourceNotFound => e
21
+ when 404
24
22
  raise ArtifactNotFoundException
23
+ else
24
+ raise UnexpectedStatusCodeException.new(response.status)
25
25
  end
26
26
  end
27
27
 
28
- def update_artifact_custom_info(artifact, *params)
29
- group_id, artifact_id, version, extension = parse_artifact_string(artifact)
30
- n3_user_urns = { "n3_header" => N3Metadata::generate_n3_header(group_id, artifact_id, version, extension) }.merge(N3Metadata::generate_n3_urns_from_hash(parse_update_params(*params)))
31
-
32
- n3_temp = Tempfile.new("nexus_n3")
33
- begin
34
- n3_temp.write(N3Metadata::parse_n3_hash(n3_user_urns))
35
- n3_temp.close
36
- update_artifact_custom_info_n3(artifact, n3_temp.path)
37
- ensure
38
- n3_temp.close
39
- n3_temp.unlink
40
- end
28
+ # Gets the custom metadata for an artifact in a simplified XML format
29
+ # @param [String] artifact The GAVE string of the artifact
30
+ # @result [String] The resulting custom metadata xml from the get operation
31
+ def get_artifact_custom_info(artifact)
32
+ N3Metadata::convert_result_to_simple_xml(get_artifact_custom_info_raw(artifact))
41
33
  end
42
34
 
43
- def update_artifact_custom_info_n3(artifact, file)
44
- # Check if artifact exists before posting custom metadata.
45
- get_artifact_info(artifact)
46
- # Update the custom metadata using the n3 file.
47
- group_id, artifact_id, version, extension = parse_artifact_string(artifact)
48
- post_string = N3Metadata::generate_n3_path(group_id, artifact_id, version, extension, configuration['repository'])
35
+ # Updates custom metadata for an artifact
36
+ # @param [String] artifact The GAVE string of the artifact
37
+ # @param [Array] *params The array of key:value strings
38
+ # @result [Integer] The resulting exit code of the operation
39
+ def update_artifact_custom_info(artifact, *params)
40
+ target_n3 = parse_custom_metadata_update_params(*params)
49
41
 
50
42
  # Get all the urn:nexus/user# keys and consolidate.
51
43
  # Read in nexus n3 file. If this is a newly-added artifact, there will be no n3 file so escape the exception.
52
44
  begin
53
- nexus_n3 = get_artifact_custom_info_n3(artifact)
54
- rescue ArtifactNotFoundException
55
- nexus_n3 = ""
45
+ nexus_n3 = N3Metadata::convert_result_to_hash(get_artifact_custom_info_raw(artifact))
46
+ rescue N3NotFoundException
47
+ nexus_n3 = {}
56
48
  end
57
49
 
58
- # Read in local n3 file.
59
- local_n3 = File.open(file).read
60
-
61
- n3_user_urns = { "n3_header" => N3Metadata::generate_n3_header(group_id, artifact_id, version, extension) }
62
- # Get the nexus keys.
63
- n3_user_urns = N3Metadata::generate_n3_urns_from_n3(nexus_n3, n3_user_urns)
64
- # Get the local keys and update the nexus keys.
65
- n3_user_urns = N3Metadata::generate_n3_urns_from_n3(local_n3, n3_user_urns)
66
- n3_temp = Tempfile.new("nexus_n3")
67
- begin
68
- n3_temp.write(N3Metadata::parse_n3_hash(n3_user_urns))
69
- n3_temp.close
70
- nexus[post_string].put({:file => File.new(n3_temp.path)})
71
- ensure
72
- n3_temp.close
73
- n3_temp.unlink
50
+ group_id, artifact_id, version, extension = parse_artifact_string(artifact)
51
+ encoded_string = N3Metadata::create_base64_subject(group_id, artifact_id, version, extension)
52
+ response = nexus.post(nexus_url("service/local/index/custom_metadata/#{configuration['repository']}/#{encoded_string}"), :body => create_custom_metadata_update_json(nexus_n3, target_n3), :header => DEFAULT_CONTENT_TYPE_HEADER)
53
+ case response.code
54
+ when 201
55
+ return true
56
+ else
57
+ raise UnexpectedStatusCodeException.new(response.status)
74
58
  end
75
59
  end
76
60
 
61
+ # Clears all custom metadata from an artifact
62
+ # @param [String] The GAVE string of the artifact
63
+ # @result [Integer] The resulting exit code of the operation
77
64
  def clear_artifact_custom_info(artifact)
78
- get_artifact_info(artifact)
65
+ get_artifact_custom_info(artifact) # Check that artifact has custom metadata
79
66
  group_id, artifact_id, version, extension = parse_artifact_string(artifact)
80
- post_string = N3Metadata::generate_n3_path(group_id, artifact_id, version, extension, configuration['repository'])
81
- n3_user_urns = { "n3_header" => N3Metadata::generate_n3_header(group_id, artifact_id, version, extension) }
82
- n3_temp = Tempfile.new("nexus_n3")
83
- begin
84
- n3_temp.write(N3Metadata::parse_n3_hash(n3_user_urns))
85
- n3_temp.close
86
- nexus[post_string].put({:file => File.new(n3_temp.path)})
87
- ensure
88
- n3_temp.close
89
- n3_temp.unlink
67
+ encoded_string = N3Metadata::create_base64_subject(group_id, artifact_id, version, extension)
68
+ response = nexus.post(nexus_url("service/local/index/custom_metadata/#{configuration['repository']}/#{encoded_string}"), :body => create_custom_metadata_clear_json, :header => DEFAULT_CONTENT_TYPE_HEADER)
69
+ case response.status
70
+ when 201
71
+ return true
72
+ else
73
+ raise UnexpectedStatusCodeException.new(response.status)
90
74
  end
91
75
  end
92
76
 
93
- def search_artifacts(*params)
94
- docs = Array.new
95
- parse_search_params(*params).each do |param|
96
- begin
97
- nexus['service/local/search/m2/freeform'].get(:params => {:p => param[0], :t => param[1], :v => param[2]}) do |response|
98
- raise BadSearchRequestException if response.code == 400
99
- docs.push(Nokogiri::XML(response.body).xpath("/search-results/data"))
100
- end
101
- rescue RestClient::ResourceNotFound => e
77
+ # Searches for artifacts using custom metadata
78
+ # @param [Array] *params The array of key:type:value strings
79
+ # @result [String] The resulting xml from the search
80
+ def search_artifacts_custom(*params)
81
+ nodesets = Array.new
82
+ parse_custom_metadata_search_params(*params).each do |param|
83
+ response = nexus.get(nexus_url("service/local/search/m2/freeform"), :query => {:p => param[0], :t => param[1], :v => param[2]})
84
+ case response.status
85
+ when 200
86
+ nodesets.push(Nokogiri::XML(response.body).xpath("/search-results/data"))
87
+ when 400
88
+ raise BadSearchRequestException
89
+ when 404
102
90
  raise ArtifactNotFoundException
91
+ else
92
+ raise UnexpectedStatusCodeException.new(response.status)
103
93
  end
104
94
  end
105
- result = docs.inject(docs.first) {|memo,doc| get_common_artifact_set(memo, doc)}
95
+ # Perform array intersection across all NodeSets for the final common set.
96
+ result = nodesets.inject(nodesets.first) {|memo, nodeset| get_common_artifact_set(memo, nodeset)}
106
97
  return result.nil? ? "" : result.to_xml(:indent => 4)
107
98
  end
108
99
 
109
100
  def get_pub_sub(repository_id)
110
- nexus["service/local/smartproxy/pub-sub/#{repository_id}"].get
101
+ response = nexus.get(nexus_url("service/local/smartproxy/pub-sub/#{repository_id}"))
102
+ case response.status
103
+ when 200
104
+ return response.content
105
+ else
106
+ raise UnexpectedStatusCodeException.new(response.status)
107
+ end
111
108
  end
112
109
 
113
110
  def enable_artifact_publish(repository_id)
@@ -123,17 +120,15 @@ module NexusCli
123
120
  end
124
121
 
125
122
  def artifact_publish(repository_id, params)
126
- nexus["service/local/smartproxy/pub-sub/#{repository_id}"].put(create_pub_sub_json(params), :content_type => "application/json") do |response|
127
- case response.code
128
- when 200
129
- return true
130
- else
131
- raise UnexpectedStatusCodeException.new(response.code)
132
- end
123
+ response = nexus.put(nexus_url("service/local/smartproxy/pub-sub/#{repository_id}"), :body => create_pub_sub_json(params), :header => DEFAULT_CONTENT_TYPE_HEADER)
124
+ case response.status
125
+ when 200
126
+ return true
127
+ else
128
+ raise UnexpectedStatusCodeException.new(response.status)
133
129
  end
134
130
  end
135
131
 
136
-
137
132
  def enable_artifact_subscribe(repository_id)
138
133
  raise NotProxyRepositoryException.new(repository_id) unless Nokogiri::XML(get_repository_info(repository_id)).xpath("/repository/data/repoType").first.content == "proxy"
139
134
 
@@ -151,13 +146,12 @@ module NexusCli
151
146
  end
152
147
 
153
148
  def artifact_subscribe(repository_id, params)
154
- nexus["service/local/smartproxy/pub-sub/#{repository_id}"].put(create_pub_sub_json(params), :content_type => "application/json") do |response|
155
- case response.code
156
- when 200
157
- return true
158
- else
159
- raise UnexpectedStatusCodeException.new(response.code)
160
- end
149
+ response = nexus.put(nexus_url("service/local/smartproxy/pub-sub/#{repository_id}"), :body => create_pub_sub_json(params), :header => DEFAULT_CONTENT_TYPE_HEADER)
150
+ case response.status
151
+ when 200
152
+ return true
153
+ else
154
+ raise UnexpectedStatusCodeException.new(response.status)
161
155
  end
162
156
  end
163
157
 
@@ -174,154 +168,177 @@ module NexusCli
174
168
  end
175
169
 
176
170
  def smart_proxy(params)
177
- nexus["service/local/smartproxy/settings"].put(create_smart_proxy_settings_json(params), :content_type => "application/json") do |response|
178
- case response.code
179
- when 200
180
- return true
181
- else
182
- raise UnexpectedStatusCodeException.new(response.code)
183
- end
171
+ response = nexus.put(nexus_url("service/local/smartproxy/settings"), :body => create_smart_proxy_settings_json(params), :header => DEFAULT_CONTENT_TYPE_HEADER)
172
+ case response.status
173
+ when 200
174
+ return true
175
+ else
176
+ raise UnexpectedStatusCodeException.new(response.status)
184
177
  end
185
178
  end
186
179
 
187
180
  def get_smart_proxy_settings
188
- nexus["service/local/smartproxy/settings"].get(:accept => "application/json")
181
+ response = nexus.get(nexus_url("service/local/smartproxy/settings"), :header => DEFAULT_ACCEPT_HEADER)
182
+ case response.status
183
+ when 200
184
+ return response.content
185
+ else
186
+ raise UnexpectedStatusCodeException.new(response.status)
187
+ end
189
188
  end
190
189
 
191
190
  def get_smart_proxy_key
192
- nexus["service/local/smartproxy/settings"].get(:accept => "application/json")
191
+ response = nexus.get(nexus_url("service/local/smartproxy/settings"), :header => DEFAULT_ACCEPT_HEADER)
192
+ case response.status
193
+ when 200
194
+ return response.content
195
+ else
196
+ raise UnexpectedStatusCodeException.new(response.status)
197
+ end
193
198
  end
194
199
 
195
200
  def add_trusted_key(certificate, description, path=true)
196
201
  params = {:description => description}
197
202
  params[:certificate] = path ? File.read(File.expand_path(certificate)) : certificate
198
- nexus["service/local/smartproxy/trusted-keys"].post(create_add_trusted_key_json(params), :content_type => "application/json") do |response|
199
- case response.code
200
- when 201
201
- return true
202
- else
203
- raise UnexpectedStatusCodeException.new(response.code)
204
- end
203
+ response = nexus.post(nexus_url("service/local/smartproxy/trusted-keys"), :body => create_add_trusted_key_json(params), :header => DEFAULT_CONTENT_TYPE_HEADER)
204
+ case response.status
205
+ when 201
206
+ return true
207
+ else
208
+ raise UnexpectedStatusCodeException.new(response.status)
205
209
  end
206
210
  end
207
211
 
208
212
  def delete_trusted_key(key_id)
209
- nexus["service/local/smartproxy/trusted-keys/#{key_id}"].delete do |response|
210
- case response.code
211
- when 204
212
- return true
213
- else
214
- raise UnexpectedStatusCodeException.new(response.code)
215
- end
213
+ response = nexus.delete(nexus_url("service/local/smartproxy/trusted-keys/#{key_id}"))
214
+ case response.status
215
+ when 204
216
+ return true
217
+ else
218
+ raise UnexpectedStatusCodeException.new(response.status)
216
219
  end
217
220
  end
218
221
 
219
222
  def get_trusted_keys
220
- nexus["service/local/smartproxy/trusted-keys"].get(:accept => "application/json")
223
+ response = nexus.get(nexus_url("service/local/smartproxy/trusted-keys"), :header => DEFAULT_ACCEPT_HEADER)
224
+ case response.status
225
+ when 200
226
+ return response.content
227
+ else
228
+ raise UnexpectedStatusCodeException.new(response.status)
229
+ end
221
230
  end
222
231
 
223
232
  def get_license_info
224
- nexus["service/local/licensing"].get(:accept => "application/json")
233
+ response = nexus.get(nexus_url("service/local/licensing"), :header => DEFAULT_ACCEPT_HEADER)
234
+ case response.status
235
+ when 200
236
+ return response.content
237
+ else
238
+ raise UnexpectedStatusCodeException.new(response.status)
239
+ end
225
240
  end
226
241
 
227
242
  def install_license(license_file)
228
243
  file = File.read(File.expand_path(license_file))
229
- nexus["service/local/licensing/upload"].post(file, :content_type => "application/octet-stream") do |response|
230
- case response.code
231
- when 201
232
- return true
233
- when 403
234
- raise LicenseInstallFailure
235
- else
236
- raise UnexpectedStatusCodeException.new(response.code)
237
- end
244
+ response = nexus.post(nexus_url("service/local/licensing/upload"), :body => file, :header => {"Content-Type" => "application/octet-stream"})
245
+ case response.status
246
+ when 201
247
+ return true
248
+ when 403
249
+ raise LicenseInstallFailure
250
+ else
251
+ raise UnexpectedStatusCodeException.new(response.status)
238
252
  end
239
253
  end
240
254
 
241
255
  def install_license_bytes(bytes)
242
- nexus["service/local/licensing/upload"].post(bytes, :content_type => "application/octet-stream") do |response|
243
- case response.code
244
- when 201
245
- return true
246
- when 403
247
- raise LicenseInstallFailure
248
- else
249
- raise UnexpectedStatusCodeException.new(response.code)
250
- end
256
+ response = nexus.post(nexus_url("service/local/licensing/upload"), :body => bytes, :header => {"Content-Type" => "application/octet-stream"})
257
+ case response.status
258
+ when 201
259
+ return true
260
+ when 403
261
+ raise LicenseInstallFailure
262
+ else
263
+ raise UnexpectedStatusCodeException.new(response.status)
251
264
  end
252
265
  end
253
266
 
254
267
  private
255
268
 
256
- def create_add_trusted_key_json(params)
257
- JSON.dump(:data => params)
258
- end
269
+ def create_add_trusted_key_json(params)
270
+ JSON.dump(:data => params)
271
+ end
259
272
 
260
- def create_smart_proxy_settings_json(params)
261
- JSON.dump(:data => params)
262
- end
273
+ def create_smart_proxy_settings_json(params)
274
+ JSON.dump(:data => params)
275
+ end
263
276
 
264
- def create_pub_sub_json(params)
265
- JSON.dump(:data => params)
266
- end
277
+ def create_pub_sub_json(params)
278
+ JSON.dump(:data => params)
279
+ end
267
280
 
268
- def parse_update_params(*params)
269
- begin
270
- parsed_params = Hash.new
271
- params.each do |param|
272
- # The first colon separates key and value.
273
- c1 = param.index(":")
274
- key = param[0..(c1 - 1)]
275
- value = param[(c1 + 1)..-1]
276
- !c1.nil? && N3Metadata::valid_n3_key?(key) && N3Metadata::valid_n3_value?(value) ? parsed_params[key] = value : raise
277
- end
278
- return parsed_params
279
- rescue
281
+ # Converts an array of parameters used to update custom metadata
282
+ # @param [Array] *params The array of key:value strings
283
+ # @return [Hash] The resulting hash of parsed key:value items
284
+ # @example
285
+ # parse_custom_metadata_update_params(["cookie:oatmeal raisin"]) #=> {"cookie"=>"oatmeal raisin"}
286
+ def parse_custom_metadata_update_params(*params)
287
+ params.inject({}) do |parsed_params, param|
288
+ # param = key:value
289
+ metadata_key, metadata_value = param.split(":", 2)
290
+ if N3Metadata::valid_n3_key?(metadata_key) && N3Metadata::valid_n3_value?(metadata_value)
291
+ parsed_params[metadata_key] = metadata_value
292
+ else
280
293
  raise N3ParameterMalformedException
281
294
  end
295
+ parsed_params
282
296
  end
297
+ end
283
298
 
284
- def parse_search_params(*params)
285
- begin
286
- parsed_params = Array.new
287
- params.each do |param|
288
- # The first two colons separate key, type, and value.
289
- c1 = param.index(":")
290
- c2 = param.index(":", (c1 + 1))
291
- key = param[0..(c1 - 1)]
292
- type = param[(c1 + 1)..(c2 - 1)]
293
- value = param[(c2 + 1)..-1]
294
- !c1.nil? && !c2.nil? && N3Metadata::valid_n3_key?(key) && N3Metadata::valid_n3_value?(value) && N3Metadata::valid_n3_search_type?(type) ? parsed_params.push([key, type, value]) : raise
295
- end
296
- return parsed_params
297
- rescue
299
+ # Converts an array of parameters used to search by custom metadata
300
+ # @param [Array] *params The array of key:type:value strings
301
+ # @result [Array] The resulting array of parsed key:type:value items
302
+ # @example
303
+ # parse_custom_metadata_search_params(["cookie:matches:oatmeal raisin"]) #=> #=> [["cookie","matches","oatmeal raisin"]]
304
+ def parse_custom_metadata_search_params(*params)
305
+ params.inject([]) do |parsed_params, param|
306
+ # param = key:type:value
307
+ metadata_key, search_type, metadata_value = param.split(":", 3)
308
+ if N3Metadata::valid_n3_key?(metadata_key) && N3Metadata::valid_n3_value?(metadata_value) && N3Metadata::valid_n3_search_type?(search_type)
309
+ parsed_params.push([metadata_key, search_type, metadata_value])
310
+ else
298
311
  raise SearchParameterMalformedException
299
312
  end
313
+ parsed_params
300
314
  end
315
+ end
301
316
 
302
- # Expects the XML set with `data` as root.
303
- def get_common_artifact_set(set1, set2)
304
- intersection = get_artifact_array(set1) & get_artifact_array(set2)
305
- return intersection.count > 0 ? Nokogiri::XML("<data>#{intersection.join}</data>").root : Nokogiri::XML("").root
306
- end
317
+ def create_custom_metadata_update_json(source, target)
318
+ JSON.dump(:data => N3Metadata::create_metadata_hash(source, target))
319
+ end
307
320
 
308
- # Collect <artifact>...</artifact> elements into an array.
309
- # This will allow use of array intersection to find common artifacts in searches.
310
- def get_artifact_array(set)
311
- artifacts = Array.new
312
- artifact = nil
313
- set.to_s.split("\n").collect {|x| x.to_s.strip}.each do |piece|
314
- if piece == "<artifact>"
315
- artifact = piece
316
- elsif piece == "</artifact>"
317
- artifact += piece
318
- artifacts.push(artifact)
319
- artifact = nil
320
- elsif !artifact.nil?
321
- artifact += piece
322
- end
323
- end
324
- return artifacts
321
+ def create_custom_metadata_clear_json
322
+ JSON.dump(:data => {})
323
+ end
324
+
325
+ # Gets the intersection of two artifact arrays, returning the common set
326
+ # @param [Array] set1, set2 The two Nokogiri::NodeSet objects to intersect
327
+ # @result [Nokogiri::NodeSet] The resulting object generated from the array intersect
328
+ def get_common_artifact_set(set1, set2)
329
+ intersection = get_artifact_array(set1) & get_artifact_array(set2)
330
+ return intersection.count > 0 ? Nokogiri::XML("<data>#{intersection.join}</data>").root : Nokogiri::XML("").root
331
+ end
332
+
333
+ # Collect <artifact> elements into an array
334
+ # @info This will allow use of array intersection to find common artifacts in searches
335
+ # @param [Nokogiri::NodeSet] set The object to be divided by <artifact> elements
336
+ # @result [Array] The result array of artifact elements
337
+ def get_artifact_array(set)
338
+ set.search("//artifact").inject([]) do |artifacts, artifact|
339
+ artifacts.push(artifact.to_s)
340
+ artifacts
325
341
  end
342
+ end
326
343
  end
327
344
  end