nexus_cli 0.7.3 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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