Class: Dpl::Providers::Bintray

Inherits:
Dpl::Provider show all
Defined in:
lib/dpl/providers/bintray.rb

Defined Under Namespace

Classes: Upload

Constant Summary collapse

PATHS =
{
  packages: '/packages/%{subject}/%{repo}',
  package: '/packages/%{subject}/%{repo}/%{package_name}',
  package_attrs: '/packages/%{subject}/%{repo}/%{package_name}/attributes',
  versions: '/packages/%{subject}/%{repo}/%{package_name}/versions',
  version: '/packages/%{subject}/%{repo}/%{package_name}/versions/%{version_name}',
  version_attrs: '/packages/%{subject}/%{repo}/%{package_name}/versions/%{version_name}/attributes',
  version_sign: '/gpg/%{subject}/%{repo}/%{package_name}/versions/%{version_name}',
  version_publish: '/content/%{subject}/%{repo}/%{package_name}/%{version_name}/publish',
  version_file: '/content/%{subject}/%{repo}/%{package_name}/%{version_name}/%{target}',
  file_metadata: '/file_metadata/%{subject}/%{repo}/%{target}'
}.freeze
MAP =
{
  package: %i[name desc licenses labels vcs_url website_url
              issue_tracker_url public_download_numbers public_stats],
  version: %i[name desc released vcs_tag github_release_notes_file
              github_use_tag_release_notes attributes]
}.freeze

Constants inherited from Dpl::Provider

Dpl::Provider::FOLDS, Dpl::Provider::STAGES

Instance Attribute Summary

Attributes inherited from Dpl::Provider

#key_name, #repo_name

Instance Method Summary collapse

Methods inherited from Dpl::Provider

#before_finish, #before_init, #before_install, #before_prepare, #before_setup, #chmod, #cleanup, #cmd, #err, #error, #escape, examples, #expand, #file?, #finish?, #fold, #fold?, #info, #initialize, install_deps, install_deps?, #mkdir_p, move_files, #msg, #mv, #open, #opt_for, #opt_key, #opts_for, #print, #quote, #read, #remove_dpl_dir, #rm_rf, #run, #run_cmd, #run_cmds, #run_stage, #run_stage?, #script, #setup_dpl_dir, #setup_git_config, #setup_git_http_user_agent, #setup_git_ssh, #setup_ssh_key, #shell, #sq, #ssh_keygen, #symbolize, #try_ssh_access, #uncleanup, unmove_files, validate_runtimes, #wait_for_ssh_access, #warn

Methods included from Dpl::Provider::Dsl

#apt, #apt?, #cmds, #description, #env, #errs, #full_name, #gem, #gem?, #keep, #move, #msgs, #needs, #needs?, #node_js, #npm, #npm?, #opt, #pip, #pip?, #python, #ruby_pre?, #ruby_version, #runtimes, #status, #strs, #summary, #user_agent, #vars

Methods included from Squiggle

#sq

Methods included from Assets

#asset

Methods included from Env

included, #opts

Methods included from ConfigFile

included, #opts

Methods included from Interpolate

#interpolate, #obfuscate, #vars

Methods included from Memoize

included

Constructor Details

This class inherits a constructor from Dpl::Provider

Instance Method Details

#append_params(path, params) ⇒ Object



230
231
232
# File 'lib/dpl/providers/bintray.rb', line 230

def append_params(path, params)
  [path, *Array(params).map { |pair| pair.join('=') }].join(';')
end

#compact(hash) ⇒ Object



305
306
307
# File 'lib/dpl/providers/bintray.rb', line 305

def compact(hash)
  hash.reject { |_, value| value.nil? }
end

#create_packageObject



86
87
88
89
90
91
92
93
# File 'lib/dpl/providers/bintray.rb', line 86

def create_package
  info :create_package
  post(path(:packages), compact(only(package, *MAP[:package])))
  return unless package_attrs

  info :package_attrs
  post(path(:package_attrs), package_attrs)
end

#create_versionObject



99
100
101
102
103
104
105
106
# File 'lib/dpl/providers/bintray.rb', line 99

def create_version
  info :create_version
  post(path(:versions), compact(only(version, *MAP[:version])))
  return unless version_attrs

  info :version_attrs
  post(path(:version_attrs), version_attrs)
end

#deployObject



74
75
76
77
78
79
80
# File 'lib/dpl/providers/bintray.rb', line 74

def deploy
  create_package unless package_exists?
  create_version unless version_exists?
  upload_files
  sign_version if sign_version?
  publish_version && update_files if publish_version?
end

#descriptorObject



244
245
246
247
248
# File 'lib/dpl/providers/bintray.rb', line 244

def descriptor
  @descriptor ||= symbolize(JSON.parse(File.read(file)))
rescue StandardError
  error :invalid_file
end

#excluded?(path, pattern) ⇒ Boolean

Returns:

  • (Boolean)


175
176
177
# File 'lib/dpl/providers/bintray.rb', line 175

def excluded?(path, pattern)
  !pattern.to_s.empty? && path.match(/#{pattern}/)
end

#exists?(type) ⇒ Boolean

Returns:

  • (Boolean)


188
189
190
191
192
193
194
# File 'lib/dpl/providers/bintray.rb', line 188

def exists?(type)
  case code = head(path(type), raise: false, silent: true)
  when 200, 201 then true
  when 404 then false
  else error :unexpected_code, code, type
  end
end

#filesObject



152
153
154
155
156
157
158
159
# File 'lib/dpl/providers/bintray.rb', line 152

def files
  return {} unless files = descriptor[:files]
  return @files if @files

  keys = %i[path includePattern excludePattern uploadPattern matrixParams listInDownloads]
  files = files.map { |file| file if file[:path] = path_for(file[:includePattern]) }
  @files = files.compact.map { |file| find(*file.values_at(*keys)) }.flatten
end

#find(path, includes, excludes, uploads, params, download) ⇒ Object



161
162
163
164
165
166
167
# File 'lib/dpl/providers/bintray.rb', line 161

def find(path, includes, excludes, uploads, params, download)
  paths = Find.find(path).select { |path| File.file?(path) }
  paths = paths.reject { |path| excluded?(path, excludes) }
  paths = paths.map { |path| [path, path.match(/#{includes}/)] }
  paths = paths.select(&:last)
  paths.map { |path, match| Upload.new(path, fmt(uploads, match.captures), params, download) }
end

#fmt(pattern, captures) ⇒ Object



169
170
171
172
173
# File 'lib/dpl/providers/bintray.rb', line 169

def fmt(pattern, captures)
  captures.each.with_index.inject(pattern) do |pattern, (capture, ix)|
    pattern.gsub("$#{ix + 1}", capture)
  end
end

#handle(req, res, opts = { raise: true }) ⇒ Object



234
235
236
237
238
# File 'lib/dpl/providers/bintray.rb', line 234

def handle(req, res, opts = { raise: true })
  error :request_failed, req.method, req.uri, res.code if opts[:raise] && !success?(res.code)
  info :request_success, res.code, res.message, parse(res)['message'] unless opts[:silent]
  res.code.to_i
end

#head(path, opts = {}) ⇒ Object



196
197
198
199
200
# File 'lib/dpl/providers/bintray.rb', line 196

def head(path, opts = {})
  req = Net::HTTP::Head.new(path)
  req.basic_auth(user, key)
  request(req, opts)
end

#httpObject



224
225
226
227
228
# File 'lib/dpl/providers/bintray.rb', line 224

def http
  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http
end

#installObject



65
66
67
# File 'lib/dpl/providers/bintray.rb', line 65

def install
  require 'json'
end

#only(hash, *keys) ⇒ Object



309
310
311
# File 'lib/dpl/providers/bintray.rb', line 309

def only(hash, *keys)
  hash.select { |key, _| keys.include?(key) }
end

#packageObject



254
255
256
# File 'lib/dpl/providers/bintray.rb', line 254

def package
  descriptor[:package]
end

#package_attrsObject



262
263
264
# File 'lib/dpl/providers/bintray.rb', line 262

def package_attrs
  package[:attributes]
end

#package_exists?Boolean

Returns:

  • (Boolean)


82
83
84
# File 'lib/dpl/providers/bintray.rb', line 82

def package_exists?
  exists?(:package)
end

#package_nameObject



258
259
260
# File 'lib/dpl/providers/bintray.rb', line 258

def package_name
  package[:name]
end

#parse(json) ⇒ Object



298
299
300
301
302
303
# File 'lib/dpl/providers/bintray.rb', line 298

def parse(json)
  hash = JSON.parse(json)
  hash.is_a?(Hash) ? hash : {}
rescue StandardError
  {}
end

#path(resource, args = {}) ⇒ Object



294
295
296
# File 'lib/dpl/providers/bintray.rb', line 294

def path(resource, args = {})
  interpolate(PATHS[resource], args, secure: true)
end

#path_for(str) ⇒ Object



179
180
181
182
183
184
185
186
# File 'lib/dpl/providers/bintray.rb', line 179

def path_for(str)
  ix = str.index('(')
  path = ix.to_i.zero? ? str : str[0, ix]
  return path if File.exist?(path)

  warn(:missing_path, path: path)
  nil
end

#post(path, body = nil) ⇒ Object



202
203
204
205
206
207
208
# File 'lib/dpl/providers/bintray.rb', line 202

def post(path, body = nil)
  req = Net::HTTP::Post.new(path)
  req.add_field('Content-Type', 'application/json')
  req.basic_auth(user, key)
  req.body = JSON.dump(body) if body
  request(req)
end

#publish_versionObject



121
122
123
124
# File 'lib/dpl/providers/bintray.rb', line 121

def publish_version
  info :publish_version
  post(path(:version_publish))
end

#publish_version?Boolean

Returns:

  • (Boolean)


290
291
292
# File 'lib/dpl/providers/bintray.rb', line 290

def publish_version?
  descriptor[:publish]
end

#put(path, body, params = {}, headers = {}) ⇒ Object



210
211
212
213
214
215
216
# File 'lib/dpl/providers/bintray.rb', line 210

def put(path, body, params = {}, headers = {})
  req = Net::HTTP::Put.new(append_params(path, params))
  headers.each { |key, value| req.add_field(key.to_s, value) }
  req.basic_auth(user, key)
  req.body = body
  request(req)
end

#repoObject



270
271
272
# File 'lib/dpl/providers/bintray.rb', line 270

def repo
  package[:repo]
end

#request(req, opts = {}) ⇒ Object



218
219
220
221
222
# File 'lib/dpl/providers/bintray.rb', line 218

def request(req, opts = {})
  res = http.request(req)
  handle(req, res, opts)
  res.code.to_i
end

#retrying(opts) ⇒ Object



141
142
143
144
145
146
147
148
149
150
# File 'lib/dpl/providers/bintray.rb', line 141

def retrying(opts)
  1.upto(opts[:max]) do |count|
    code = yield
    return if code < 400

    info :retrying, opts.merge(count: count, code: code)
    sleep opts[:pause]
  end
  error :giveup_retries
end

#sign_versionObject



115
116
117
118
119
# File 'lib/dpl/providers/bintray.rb', line 115

def sign_version
  body = compact(passphrase: passphrase)
  info :sign_version, (passphrase? ? 'with' : 'without')
  post(path(:version_sign), body)
end

#sign_version?Boolean

Returns:

  • (Boolean)


286
287
288
# File 'lib/dpl/providers/bintray.rb', line 286

def sign_version?
  version[:gpgSign]
end

#subjectObject



266
267
268
# File 'lib/dpl/providers/bintray.rb', line 266

def subject
  package[:subject]
end

#success?(code) ⇒ Boolean

Returns:

  • (Boolean)


240
241
242
# File 'lib/dpl/providers/bintray.rb', line 240

def success?(code)
  code.to_s[0].to_i == 2
end

#update_file(file) ⇒ Object



133
134
135
136
137
138
139
# File 'lib/dpl/providers/bintray.rb', line 133

def update_file(file)
  retrying(max: 10, pause: 5) do
    body = { list_in_downloads: file.download }.to_json
    headers = { 'Content-Type': 'application/json' }
    put(path(:file_metadata, target: file.target), body, {}, headers)
  end
end

#update_filesObject



126
127
128
129
130
131
# File 'lib/dpl/providers/bintray.rb', line 126

def update_files
  files.select(&:download).each do |file|
    info :list_download, path: file.target
    update_file(file)
  end
end

#upload_filesObject



108
109
110
111
112
113
# File 'lib/dpl/providers/bintray.rb', line 108

def upload_files
  files.each do |file|
    info :upload_file, source: file.source, target: file.target
    put(path(:version_file, target: file.target), file.read, file.params)
  end
end

#urlObject



250
251
252
# File 'lib/dpl/providers/bintray.rb', line 250

def url
  @url ||= URI.parse(super || URL)
end

#validateObject



69
70
71
72
# File 'lib/dpl/providers/bintray.rb', line 69

def validate
  error :missing_file unless File.exist?(file)
  # validate that the repo exists, and we have access
end

#versionObject



274
275
276
# File 'lib/dpl/providers/bintray.rb', line 274

def version
  descriptor[:version]
end

#version_attrsObject



282
283
284
# File 'lib/dpl/providers/bintray.rb', line 282

def version_attrs
  version[:attributes]
end

#version_exists?Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/dpl/providers/bintray.rb', line 95

def version_exists?
  exists?(:version)
end

#version_nameObject



278
279
280
# File 'lib/dpl/providers/bintray.rb', line 278

def version_name
  version[:name]
end