summaryrefslogtreecommitdiff
path: root/lib/download.rb
blob: 5b824f57896b8e680bab26cd57ef7664357868d8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

# frozen_string_literal: true

require_relative '../config/config'
require_relative 'package'
require 'net/http'
require 'pathname'
require 'progressbar'
require 'term/ansicolor'

module SlackBuilder
  extend Rake::FileUtilsExt

  def self.clone(repo, tarball, tag_prefix = 'v')
    name_version = File.basename tarball, '.tar.xz'
    remote_path = tarball[tarball.index('/')..]

    if remote_file_exists?(remote_path)
      uri = URI hosted_sources(remote_path)

      return download(uri, "slackbuilds/#{tarball}").hexdigest
    end

    clone_and_archive repo, name_version, tarball, tag_prefix

    sh(*upload_command(tarball, remote_path))

    Digest::MD5.hexdigest File.read("slackbuilds/#{tarball}")
  end

  def self.download(uri, target)
    print Term::ANSIColor.green "Downloading #{uri} "
    checksum = nil

    Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
      checksum = start_download uri, target, http
    end

    puts
    checksum
  end

  def hosted_sources(absolute_url)
    CONFIG[:download_url] + absolute_url
  end

  def remote_file_exists?(url)
    uri = URI hosted_sources(url)

    request = Net::HTTP.new uri.host, uri.port
    request.use_ssl = true
    response = request.request_head uri.path

    response.code.to_i == 200
  end

  def self.download_and_deploy(uri, tarball)
    remote_path = tarball[tarball.index('/')..]

    if SlackBuilder.remote_file_exists?(remote_path)
      uri = URI hosted_sources(remote_path)
      return download(uri, "slackbuilds/#{tarball}").hexdigest
    end

    checksum = download uri, "slackbuilds/#{tarball}"
    sh(*upload_command(tarball, remote_path))
    checksum.hexdigest
  end

  private_class_method def self.redirect_download(location, target)
    puts 'redirecting...'
    new_location = URI location

    download new_location, target
  end

  private_class_method def self.write_chunk(response, checksum, progressbar, io)
    response.read_body do |chunk|
      progressbar.progress += chunk.length
      io << chunk
      checksum << chunk
    end
  end

  private_class_method def self.write_download(target, response)
    checksum = Digest::MD5.new
    progressbar = ProgressBar.create title: target, total: response.header.content_length

    File.open target, 'w' do |io|
      write_chunk response, checksum, progressbar, io
    end
    progressbar.finish

    checksum
  end

  private_class_method def self.start_download(uri, target, http)
    request = Net::HTTP::Get.new uri

    http.request request do |response|
      case response
      when Net::HTTPRedirection
        return redirect_download response['location'], target
      else
        return write_download target, response
      end
    end
  end

  private_class_method def self.upload_command(local_path, remote_path)
    ['scp', "slackbuilds/#{local_path}", CONFIG[:remote_path] + remote_path]
  end

  private_class_method def self.clone_and_archive(repo, name_version, tarball, tag_prefix = 'v')
    _, _, version = name_version.rpartition '-'

    rm_rf name_version

    sh 'git', 'clone', repo, name_version
    sh 'git', '-C', name_version, 'checkout', "#{tag_prefix}#{version}"
    sh 'git', '-C', name_version, 'submodule', 'update', '--init', '--recursive'

    sh 'tar', 'Jcvf', "slackbuilds/#{tarball}", name_version
    rm_rf name_version
  end
end

def write_info(package, downloads:)
  File.write "slackbuilds/#{package.path}/#{package.name}.info",
    info_template(package, downloads)
end

def update_slackbuild_version(package_path, version)
  raise TypeError, %(expected a version string, got "#{version}") unless version.is_a?(String)

  name = package_path.split('/').last
  slackbuild_filename = "slackbuilds/#{package_path}/#{name}.SlackBuild"
  slackbuild_contents = File.read(slackbuild_filename)
    .gsub(/^VERSION=\${VERSION:-.+/, "VERSION=${VERSION:-#{version}}")

  File.open(slackbuild_filename, 'w') { |file| file.puts slackbuild_contents }
end

def commit(package_path, version)
  message = "#{package_path}: Updated for version #{version}"

  unless system('git', '-C', 'slackbuilds', 'checkout', CONFIG[:branch],
    err: '/dev/null')
    sh 'git', '-C', 'slackbuilds', 'checkout', '-b', CONFIG[:branch], 'master'
  end
  sh 'git', '-C', 'slackbuilds', 'add', package_path
  sh 'git', '-C', 'slackbuilds', 'commit', '-S', '-m', message
  # sh 'git', '-C', 'slackbuilds', 'push', 'origin', CONFIG[:branch]
end