artifactory 1.1.0 → 1.2.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.
- checksums.yaml +4 -4
- data/.travis.yml +11 -7
- data/CHANGELOG.md +18 -0
- data/README.md +25 -4
- data/Rakefile +5 -2
- data/artifactory.gemspec +0 -3
- data/lib/artifactory.rb +2 -4
- data/lib/artifactory/client.rb +210 -85
- data/lib/artifactory/configurable.rb +6 -1
- data/lib/artifactory/defaults.rb +52 -3
- data/lib/artifactory/errors.rb +21 -14
- data/lib/artifactory/resources/artifact.rb +132 -58
- data/lib/artifactory/resources/base.rb +120 -6
- data/lib/artifactory/resources/build.rb +2 -1
- data/lib/artifactory/resources/group.rb +5 -72
- data/lib/artifactory/resources/layout.rb +106 -0
- data/lib/artifactory/resources/repository.rb +62 -114
- data/lib/artifactory/resources/system.rb +5 -1
- data/lib/artifactory/resources/user.rb +5 -79
- data/lib/artifactory/util.rb +8 -2
- data/lib/artifactory/version.rb +1 -1
- data/spec/integration/resources/layout_spec.rb +22 -0
- data/spec/integration/resources/repository_spec.rb +7 -0
- data/spec/integration/resources/system_spec.rb +4 -4
- data/spec/support/api_server/repository_endpoints.rb +5 -0
- data/spec/support/api_server/system_endpoints.rb +18 -0
- data/spec/unit/client_spec.rb +17 -98
- data/spec/unit/resources/artifact_spec.rb +99 -13
- data/spec/unit/resources/build_spec.rb +1 -1
- data/spec/unit/resources/group_spec.rb +1 -1
- data/spec/unit/resources/layout_spec.rb +61 -0
- data/spec/unit/resources/repository_spec.rb +31 -47
- data/spec/unit/resources/system_spec.rb +4 -2
- data/spec/unit/resources/user_spec.rb +1 -1
- metadata +16 -40
- data/locales/en.yml +0 -27
data/lib/artifactory/defaults.rb
CHANGED
|
@@ -55,12 +55,61 @@ module Artifactory
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
#
|
|
58
|
-
# The HTTP Proxy
|
|
58
|
+
# The HTTP Proxy server address as a string
|
|
59
59
|
#
|
|
60
60
|
# @return [String, nil]
|
|
61
61
|
#
|
|
62
|
-
def
|
|
63
|
-
ENV['
|
|
62
|
+
def proxy_address
|
|
63
|
+
ENV['ARTIFACTORY_PROXY_ADDRESS']
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
#
|
|
67
|
+
# The HTTP Proxy user password as a string
|
|
68
|
+
#
|
|
69
|
+
# @return [String, nil]
|
|
70
|
+
#
|
|
71
|
+
def proxy_password
|
|
72
|
+
ENV['ARTIFACTORY_PROXY_PASSWORD']
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
#
|
|
76
|
+
# The HTTP Proxy server port as a string
|
|
77
|
+
#
|
|
78
|
+
# @return [String, nil]
|
|
79
|
+
#
|
|
80
|
+
def proxy_port
|
|
81
|
+
ENV['ARTIFACTORY_PROXY_PORT']
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
# The HTTP Proxy server username as a string
|
|
86
|
+
#
|
|
87
|
+
# @return [String, nil]
|
|
88
|
+
#
|
|
89
|
+
def proxy_username
|
|
90
|
+
ENV['ARTIFACTORY_PROXY_USERNAME']
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
#
|
|
94
|
+
# The path to a pem file on disk for use with a custom SSL verification
|
|
95
|
+
#
|
|
96
|
+
# @return [String, nil]
|
|
97
|
+
#
|
|
98
|
+
def ssl_pem_file
|
|
99
|
+
ENV['ARTIFACTORY_SSL_PEM_FILE']
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
#
|
|
103
|
+
# Verify SSL requests (default: true)
|
|
104
|
+
#
|
|
105
|
+
# @return [true, false]
|
|
106
|
+
#
|
|
107
|
+
def ssl_verify
|
|
108
|
+
if ENV['ARTIFACTORY_SSL_VERIFY'].nil?
|
|
109
|
+
true
|
|
110
|
+
else
|
|
111
|
+
%w[t y].include?(ENV['ARTIFACTORY_SSL_VERIFY'].downcase[0])
|
|
112
|
+
end
|
|
64
113
|
end
|
|
65
114
|
end
|
|
66
115
|
end
|
data/lib/artifactory/errors.rb
CHANGED
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
module Artifactory
|
|
2
2
|
module Error
|
|
3
|
-
class
|
|
4
|
-
|
|
5
|
-
class_name = self.class.to_s.split('::').last
|
|
6
|
-
error_key = Util.underscore(class_name)
|
|
3
|
+
# Base class for all errors
|
|
4
|
+
class ArtifactoryError < StandardError; end
|
|
7
5
|
|
|
8
|
-
|
|
6
|
+
# Class for all HTTP errors
|
|
7
|
+
class HTTPError < ArtifactoryError
|
|
8
|
+
attr_reader :code
|
|
9
|
+
attr_reader :message
|
|
10
|
+
|
|
11
|
+
def initialize(hash = {})
|
|
12
|
+
@code = hash['status'].to_i
|
|
13
|
+
@http = hash['message'].to_s
|
|
14
|
+
|
|
15
|
+
super "The Artifactory server responded with an HTTP Error "\
|
|
16
|
+
"#{@code}: `#{@http}'"
|
|
9
17
|
end
|
|
10
18
|
end
|
|
11
19
|
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class Unauthorized < ConnectionError; end
|
|
20
|
+
# A general connection error with a more informative message
|
|
21
|
+
class ConnectionError < ArtifactoryError
|
|
22
|
+
def initialize(endpoint)
|
|
23
|
+
super "The Artifactory server at `#{endpoint}' is not currently " \
|
|
24
|
+
"accepting connections. Please ensure that the server is " \
|
|
25
|
+
"running an that your authentication information is correct."
|
|
26
|
+
end
|
|
27
|
+
end
|
|
21
28
|
end
|
|
22
29
|
end
|
|
@@ -198,7 +198,8 @@ module Artifactory
|
|
|
198
198
|
format_repos!(params)
|
|
199
199
|
|
|
200
200
|
client.get('/api/search/versions', params)['results']
|
|
201
|
-
rescue Error::
|
|
201
|
+
rescue Error::HTTPError => e
|
|
202
|
+
raise unless e.code == 404
|
|
202
203
|
[]
|
|
203
204
|
end
|
|
204
205
|
|
|
@@ -252,73 +253,54 @@ module Artifactory
|
|
|
252
253
|
params[:remote] = 1 if options[:remote]
|
|
253
254
|
|
|
254
255
|
client.get('/api/search/latestVersion', params)
|
|
255
|
-
rescue Error::
|
|
256
|
+
rescue Error::HTTPError => e
|
|
257
|
+
raise unless e.code == 404
|
|
256
258
|
nil
|
|
257
259
|
end
|
|
258
260
|
|
|
259
261
|
#
|
|
260
|
-
#
|
|
261
|
-
#
|
|
262
|
-
# @example Create an artifact object from the given URL
|
|
263
|
-
# Artifact.from_url('/path/to/some.deb') #=> #<Resource::Artifact>
|
|
264
|
-
#
|
|
265
|
-
# @param [Artifactory::Client] client
|
|
266
|
-
# the client object to make the request with
|
|
267
|
-
# @param [String] url
|
|
268
|
-
# the URL to find the artifact from
|
|
269
|
-
#
|
|
270
|
-
# @return [Resource::Artifact]
|
|
271
|
-
#
|
|
272
|
-
def from_url(url, options = {})
|
|
273
|
-
client = extract_client!(options)
|
|
274
|
-
from_hash(client.get(url), client: client)
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
#
|
|
278
|
-
# Create a instance from the given Hash. This method extracts the "safe"
|
|
279
|
-
# information from the hash and adds them to the instance.
|
|
280
|
-
#
|
|
281
|
-
# @example Create a new resource from a hash
|
|
282
|
-
# Artifact.from_hash('downloadUri' => '...', 'size' => '...')
|
|
283
|
-
#
|
|
284
|
-
# @param [Artifactory::Client] client
|
|
285
|
-
# the client object to make the request with
|
|
286
|
-
# @param [Hash] hash
|
|
287
|
-
# the hash to create the instance from
|
|
288
|
-
#
|
|
289
|
-
# @return [Resource::Artifact]
|
|
262
|
+
# @see Artifactory::Resource::Base.from_hash
|
|
290
263
|
#
|
|
291
264
|
def from_hash(hash, options = {})
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
instance.
|
|
296
|
-
instance.
|
|
297
|
-
instance.created = Time.parse(hash['created'])
|
|
298
|
-
instance.download_path = hash['downloadUri']
|
|
299
|
-
instance.last_modified = Time.parse(hash['lastModified'])
|
|
300
|
-
instance.last_updated = Time.parse(hash['lastUpdated'])
|
|
301
|
-
instance.md5 = hash['checksums']['md5']
|
|
302
|
-
instance.mime_type = hash['mimeType']
|
|
303
|
-
instance.repo = hash['repo']
|
|
304
|
-
instance.sha1 = hash['checksums']['sha1']
|
|
305
|
-
instance.size = hash['size'].to_i
|
|
265
|
+
super.tap do |instance|
|
|
266
|
+
instance.created = Time.parse(instance.created) rescue nil
|
|
267
|
+
instance.last_modified = Time.parse(instance.last_modified) rescue nil
|
|
268
|
+
instance.last_updated = Time.parse(instance.last_updated) rescue nil
|
|
269
|
+
instance.size = instance.size.to_i
|
|
306
270
|
end
|
|
307
271
|
end
|
|
308
272
|
end
|
|
309
273
|
|
|
310
|
-
attribute :
|
|
274
|
+
attribute :uri, ->{ raise 'API path missing!' }
|
|
275
|
+
attribute :checksums
|
|
311
276
|
attribute :created
|
|
312
|
-
attribute :
|
|
277
|
+
attribute :download_uri, ->{ raise 'Download URI missing!' }
|
|
278
|
+
attribute :key
|
|
313
279
|
attribute :last_modified
|
|
314
280
|
attribute :last_updated
|
|
315
281
|
attribute :local_path, ->{ raise 'Local destination missing!' }
|
|
316
282
|
attribute :mime_type
|
|
317
|
-
attribute :md5
|
|
318
283
|
attribute :repo
|
|
319
|
-
attribute :sha1
|
|
320
284
|
attribute :size
|
|
321
285
|
|
|
286
|
+
#
|
|
287
|
+
# The SHA of this artifact.
|
|
288
|
+
#
|
|
289
|
+
# @return [String]
|
|
290
|
+
#
|
|
291
|
+
def sha1
|
|
292
|
+
checksums && checksums['sha1']
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
#
|
|
296
|
+
# The MD5 of this artifact.
|
|
297
|
+
#
|
|
298
|
+
# @return [String]
|
|
299
|
+
#
|
|
300
|
+
def md5
|
|
301
|
+
checksums && checksums['md5']
|
|
302
|
+
end
|
|
303
|
+
|
|
322
304
|
#
|
|
323
305
|
# @see Artifact#copy_or_move
|
|
324
306
|
#
|
|
@@ -334,8 +316,8 @@ module Artifactory
|
|
|
334
316
|
# true if the object was deleted successfully, false otherwise
|
|
335
317
|
#
|
|
336
318
|
def delete
|
|
337
|
-
!!client.delete(
|
|
338
|
-
rescue Error::
|
|
319
|
+
!!client.delete(download_uri)
|
|
320
|
+
rescue Error::HTTPError
|
|
339
321
|
false
|
|
340
322
|
end
|
|
341
323
|
|
|
@@ -356,7 +338,7 @@ module Artifactory
|
|
|
356
338
|
# the list of properties
|
|
357
339
|
#
|
|
358
340
|
def properties
|
|
359
|
-
@properties ||= client.get(
|
|
341
|
+
@properties ||= client.get(uri, properties: nil)['properties']
|
|
360
342
|
end
|
|
361
343
|
|
|
362
344
|
#
|
|
@@ -402,18 +384,110 @@ module Artifactory
|
|
|
402
384
|
FileUtils.mkdir_p(target) unless File.exists?(target)
|
|
403
385
|
|
|
404
386
|
# Use the server artifact's filename if one wasn't given
|
|
405
|
-
filename = options[:filename] || File.basename(
|
|
387
|
+
filename = options[:filename] || File.basename(download_uri)
|
|
406
388
|
|
|
407
389
|
# Construct the full path for the file
|
|
408
|
-
destination = File.join(
|
|
390
|
+
destination = File.join(target, filename)
|
|
409
391
|
|
|
410
|
-
File.open(
|
|
411
|
-
file.write(
|
|
392
|
+
File.open(destination, 'wb') do |file|
|
|
393
|
+
file.write(client.get(download_uri))
|
|
412
394
|
end
|
|
413
395
|
|
|
414
396
|
destination
|
|
415
397
|
end
|
|
416
398
|
|
|
399
|
+
#
|
|
400
|
+
# Upload an artifact into the repository. If the first parameter is a File
|
|
401
|
+
# object, that file descriptor is passed to the uploader. If the first
|
|
402
|
+
# parameter is a string, it is assumed to be the path to a local file on
|
|
403
|
+
# disk. This method will automatically construct the File object from the
|
|
404
|
+
# given path.
|
|
405
|
+
#
|
|
406
|
+
# @see bit.ly/1dhJRMO Artifactory Matrix Properties
|
|
407
|
+
#
|
|
408
|
+
# @example Upload an artifact from a File instance
|
|
409
|
+
# file = File.new('/local/path/to/file.deb')
|
|
410
|
+
# artifact = Artifact.new
|
|
411
|
+
# artifact.upload(file, 'libs-release-local', file.deb')
|
|
412
|
+
#
|
|
413
|
+
# @example Upload an artifact from a path
|
|
414
|
+
# artifact.upload('/local/path/to/file.deb', 'libs-release-local', 'file.deb')
|
|
415
|
+
#
|
|
416
|
+
# @example Upload an artifact with matrix properties
|
|
417
|
+
# artifact.upload('/local/path/to/file.deb', 'libs-release-local', file.deb', {
|
|
418
|
+
# status: 'DEV',
|
|
419
|
+
# rating: 5,
|
|
420
|
+
# branch: 'master'
|
|
421
|
+
# })
|
|
422
|
+
#
|
|
423
|
+
# @param [String] key
|
|
424
|
+
# the key of the repository to which to upload the file
|
|
425
|
+
# @param [String, File] path_or_io
|
|
426
|
+
# the file or path to the file to upload
|
|
427
|
+
# @param [String] path
|
|
428
|
+
# the path where this resource will live in the remote artifactory
|
|
429
|
+
# repository, relative to the repository key
|
|
430
|
+
# @param [Hash] headers
|
|
431
|
+
# the list of headers to send with the request
|
|
432
|
+
# @param [Hash] properties
|
|
433
|
+
# a list of matrix properties
|
|
434
|
+
#
|
|
435
|
+
# @return [Resource::Artifact]
|
|
436
|
+
#
|
|
437
|
+
def upload(key, path_or_io, path, properties = {}, headers = {})
|
|
438
|
+
file = if respond_to?(:read)
|
|
439
|
+
path_or_io
|
|
440
|
+
else
|
|
441
|
+
File.new(File.expand_path(path_or_io))
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
matrix = to_matrix_properties(properties)
|
|
445
|
+
endpoint = File.join("#{url_safe(key)}#{matrix}", path)
|
|
446
|
+
|
|
447
|
+
response = client.put(endpoint, file, headers)
|
|
448
|
+
self.class.from_hash(response)
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
#
|
|
452
|
+
# Upload an artifact with the given SHA checksum. Consult the artifactory
|
|
453
|
+
# documentation for the possible responses when the checksums fail to
|
|
454
|
+
# match.
|
|
455
|
+
#
|
|
456
|
+
# @see Artifact#upload More syntax examples
|
|
457
|
+
#
|
|
458
|
+
# @example Upload an artifact with a checksum
|
|
459
|
+
# artifact = Artifact.new
|
|
460
|
+
# artifact.upload_with_checksum('/local/file', 'libs-release-local', /remote/path', 'ABCD1234')
|
|
461
|
+
#
|
|
462
|
+
# @param (see Artifact#upload)
|
|
463
|
+
# @param [String] checksum
|
|
464
|
+
# the SHA1 checksum of the artifact to upload
|
|
465
|
+
#
|
|
466
|
+
def upload_with_checksum(key, path_or_io, path, checksum, properties = {})
|
|
467
|
+
upload(key, path_or_io, path, properties,
|
|
468
|
+
'X-Checksum-Deploy' => true,
|
|
469
|
+
'X-Checksum-Sha1' => checksum,
|
|
470
|
+
)
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
#
|
|
474
|
+
# Upload an artifact with the given archive. Consult the artifactory
|
|
475
|
+
# documentation for the format of the archive to upload.
|
|
476
|
+
#
|
|
477
|
+
# @see Artifact#upload More syntax examples
|
|
478
|
+
#
|
|
479
|
+
# @example Upload an artifact with a checksum
|
|
480
|
+
# artifact = Artifact.new('libs-release-local')
|
|
481
|
+
# artifact.upload_from_archive('/local/archive', '/remote/path')#
|
|
482
|
+
#
|
|
483
|
+
# @param (see Repository#upload)
|
|
484
|
+
#
|
|
485
|
+
def upload_from_archive(key, path_or_io, path, properties = {})
|
|
486
|
+
upload(key, path_or_io, path, properties,
|
|
487
|
+
'X-Explode-Archive' => true,
|
|
488
|
+
)
|
|
489
|
+
end
|
|
490
|
+
|
|
417
491
|
private
|
|
418
492
|
|
|
419
493
|
#
|
|
@@ -426,7 +500,7 @@ module Artifactory
|
|
|
426
500
|
# @return [String]
|
|
427
501
|
#
|
|
428
502
|
def relative_path
|
|
429
|
-
@relative_path ||=
|
|
503
|
+
@relative_path ||= uri.split('/api/storage', 2).last
|
|
430
504
|
end
|
|
431
505
|
|
|
432
506
|
#
|
|
@@ -27,7 +27,7 @@ module Artifactory
|
|
|
27
27
|
def attribute(key, default = nil)
|
|
28
28
|
key = key.to_sym unless key.is_a?(Symbol)
|
|
29
29
|
|
|
30
|
-
# Set
|
|
30
|
+
# Set this attribute in the top-level hash
|
|
31
31
|
attributes[key] = nil
|
|
32
32
|
|
|
33
33
|
define_method(key) do
|
|
@@ -52,6 +52,73 @@ module Artifactory
|
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
+
#
|
|
56
|
+
# The list of attributes defined by this class.
|
|
57
|
+
#
|
|
58
|
+
# @return [Array<Symbol>]
|
|
59
|
+
#
|
|
60
|
+
def attributes
|
|
61
|
+
@attributes ||= {}
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
#
|
|
65
|
+
# Determine if this class has a given attribute.
|
|
66
|
+
#
|
|
67
|
+
# @param [#to_sym] key
|
|
68
|
+
# the key to check as an attribute
|
|
69
|
+
#
|
|
70
|
+
# @return [true, false]
|
|
71
|
+
#
|
|
72
|
+
def has_attribute?(key)
|
|
73
|
+
attributes.has_key?(key.to_sym)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
#
|
|
77
|
+
# Construct a new object from the given URL.
|
|
78
|
+
#
|
|
79
|
+
# @param [String] url
|
|
80
|
+
# the URL to find the user from
|
|
81
|
+
# @param [Hash] options
|
|
82
|
+
# the list of options
|
|
83
|
+
#
|
|
84
|
+
# @option options [Artifactory::Client] :client
|
|
85
|
+
# the client object to make the request with
|
|
86
|
+
#
|
|
87
|
+
# @return [~Resource::Base]
|
|
88
|
+
#
|
|
89
|
+
def from_url(url, options = {})
|
|
90
|
+
client = extract_client!(options)
|
|
91
|
+
from_hash(client.get(url), client: client)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
#
|
|
95
|
+
# Construct a new object from the hash.
|
|
96
|
+
#
|
|
97
|
+
# @param [Hash] hash
|
|
98
|
+
# the hash to create the object with
|
|
99
|
+
# @param [Hash] options
|
|
100
|
+
# the list options
|
|
101
|
+
#
|
|
102
|
+
# @option options [Artifactory::Client] :client
|
|
103
|
+
# the client object to make the request with
|
|
104
|
+
#
|
|
105
|
+
# @return [~Resource::Base]
|
|
106
|
+
#
|
|
107
|
+
def from_hash(hash, options = {})
|
|
108
|
+
instance = new
|
|
109
|
+
instance.client = extract_client!(options)
|
|
110
|
+
|
|
111
|
+
hash.inject(instance) do |instance, (key, value)|
|
|
112
|
+
method = :"#{Util.underscore(key)}="
|
|
113
|
+
|
|
114
|
+
if instance.respond_to?(method)
|
|
115
|
+
instance.send(method, value)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
instance
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
55
122
|
#
|
|
56
123
|
# Get the client (connection) object from the given options. If the
|
|
57
124
|
# +:client+ key is preset in the hash, it is assumed to contain the
|
|
@@ -103,10 +170,6 @@ module Artifactory
|
|
|
103
170
|
def url_safe(value)
|
|
104
171
|
URI.escape(value.to_s)
|
|
105
172
|
end
|
|
106
|
-
|
|
107
|
-
def attributes
|
|
108
|
-
@attributes ||= {}
|
|
109
|
-
end
|
|
110
173
|
end
|
|
111
174
|
|
|
112
175
|
attribute :client, ->{ Artifactory.client }
|
|
@@ -159,6 +222,55 @@ module Artifactory
|
|
|
159
222
|
self.class.url_safe(value)
|
|
160
223
|
end
|
|
161
224
|
|
|
225
|
+
#
|
|
226
|
+
# The hash representation
|
|
227
|
+
#
|
|
228
|
+
# @example An example hash response
|
|
229
|
+
# { 'key' => 'local-repo1', 'includesPattern' => '**/*' }
|
|
230
|
+
#
|
|
231
|
+
# @return [Hash]
|
|
232
|
+
#
|
|
233
|
+
def to_hash
|
|
234
|
+
attributes.inject({}) do |hash, (key, value)|
|
|
235
|
+
unless Resource::Base.has_attribute?(key)
|
|
236
|
+
hash[Util.camelize(key, true)] = value
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
hash
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
#
|
|
244
|
+
# The JSON representation of this object.
|
|
245
|
+
#
|
|
246
|
+
# @see Artifactory::Resource::Base#to_json
|
|
247
|
+
#
|
|
248
|
+
# @return [String]
|
|
249
|
+
#
|
|
250
|
+
def to_json
|
|
251
|
+
JSON.fast_generate(to_hash)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
#
|
|
255
|
+
# Create URI-escaped string from matrix properties
|
|
256
|
+
#
|
|
257
|
+
# @see http://bit.ly/1qeVYQl
|
|
258
|
+
#
|
|
259
|
+
def to_matrix_properties(hash = {})
|
|
260
|
+
properties = hash.map do |k, v|
|
|
261
|
+
key = URI.escape(k.to_s)
|
|
262
|
+
value = URI.escape(v.to_s)
|
|
263
|
+
|
|
264
|
+
"#{key}=#{value}"
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
if properties.empty?
|
|
268
|
+
nil
|
|
269
|
+
else
|
|
270
|
+
";#{properties.join(';')}"
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
162
274
|
# @private
|
|
163
275
|
def to_s
|
|
164
276
|
"#<#{short_classname}>"
|
|
@@ -167,7 +279,9 @@ module Artifactory
|
|
|
167
279
|
# @private
|
|
168
280
|
def inspect
|
|
169
281
|
list = attributes.collect do |key, value|
|
|
170
|
-
|
|
282
|
+
unless Resource::Base.has_attribute?(key)
|
|
283
|
+
"#{key}: #{value.inspect}"
|
|
284
|
+
end
|
|
171
285
|
end.compact
|
|
172
286
|
|
|
173
287
|
"#<#{short_classname} #{list.join(', ')}>"
|