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}'
}
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)
}

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



223
224
225
# File 'lib/dpl/providers/bintray.rb', line 223

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

#compact(hash) ⇒ Object



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

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

#create_packageObject



84
85
86
87
88
89
90
# File 'lib/dpl/providers/bintray.rb', line 84

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



96
97
98
99
100
101
102
# File 'lib/dpl/providers/bintray.rb', line 96

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



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

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



237
238
239
240
241
# File 'lib/dpl/providers/bintray.rb', line 237

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

#excluded?(path, pattern) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#exists?(type) ⇒ Boolean

Returns:

  • (Boolean)


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

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



147
148
149
150
151
152
153
# File 'lib/dpl/providers/bintray.rb', line 147

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



155
156
157
158
159
160
161
# File 'lib/dpl/providers/bintray.rb', line 155

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



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

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



227
228
229
230
231
# File 'lib/dpl/providers/bintray.rb', line 227

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



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

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

#httpObject



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

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

#installObject



63
64
65
# File 'lib/dpl/providers/bintray.rb', line 63

def install
  require 'json'
end

#only(hash, *keys) ⇒ Object



302
303
304
# File 'lib/dpl/providers/bintray.rb', line 302

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

#packageObject



247
248
249
# File 'lib/dpl/providers/bintray.rb', line 247

def package
  descriptor[:package]
end

#package_attrsObject



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

def package_attrs
  package[:attributes]
end

#package_exists?Boolean

Returns:

  • (Boolean)


80
81
82
# File 'lib/dpl/providers/bintray.rb', line 80

def package_exists?
  exists?(:package)
end

#package_nameObject



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

def package_name
  package[:name]
end

#parse(json) ⇒ Object



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

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

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



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

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

#path_for(str) ⇒ Object



173
174
175
176
177
178
179
# File 'lib/dpl/providers/bintray.rb', line 173

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

#post(path, body = nil) ⇒ Object



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

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



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

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

#publish_version?Boolean

Returns:

  • (Boolean)


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

def publish_version?
  descriptor[:publish]
end

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



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

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



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

def repo
  package[:repo]
end

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



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

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

#retrying(opts, &block) ⇒ Object



137
138
139
140
141
142
143
144
145
# File 'lib/dpl/providers/bintray.rb', line 137

def retrying(opts, &block)
  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



111
112
113
114
115
# File 'lib/dpl/providers/bintray.rb', line 111

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

#sign_version?Boolean

Returns:

  • (Boolean)


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

def sign_version?
  version[:gpgSign]
end

#subjectObject



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

def subject
  package[:subject]
end

#success?(code) ⇒ Boolean

Returns:

  • (Boolean)


233
234
235
# File 'lib/dpl/providers/bintray.rb', line 233

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

#update_file(file) ⇒ Object



129
130
131
132
133
134
135
# File 'lib/dpl/providers/bintray.rb', line 129

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



122
123
124
125
126
127
# File 'lib/dpl/providers/bintray.rb', line 122

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

#upload_filesObject



104
105
106
107
108
109
# File 'lib/dpl/providers/bintray.rb', line 104

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



243
244
245
# File 'lib/dpl/providers/bintray.rb', line 243

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

#validateObject



67
68
69
70
# File 'lib/dpl/providers/bintray.rb', line 67

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

#versionObject



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

def version
  descriptor[:version]
end

#version_attrsObject



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

def version_attrs
  version[:attributes]
end

#version_exists?Boolean

Returns:

  • (Boolean)


92
93
94
# File 'lib/dpl/providers/bintray.rb', line 92

def version_exists?
  exists?(:version)
end

#version_nameObject



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

def version_name
  version[:name]
end