summaryrefslogtreecommitdiff
path: root/lib/download.rb
blob: 64a453f2e0383b12c79aa9107a9c261422e396c2 (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
158
159
160
161
162
163
164
165
166
167
168
169
170
# 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, package, tag_prefix = 'v')
    repository = Pathname.new('pkg') + package.name_version

    if repository.directory?
      sh 'git', '-C', repository.to_path, 'remote', 'update', '--prune'
    else
      sh 'git', 'clone', repo, repository.to_path
    end

    sh 'git', '-C', repository.to_path, 'checkout', "#{tag_prefix}#{package.version}"
    sh 'git', '-C', repository.to_path, 'submodule', 'update', '--init', '--recursive'

    repository
  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

  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
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 upload_command(local_path, remote_path)
  ['scp', "slackbuilds/#{local_path}", CONFIG[:remote_path] + remote_path]
end

def 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

def 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 download_and_deploy(uri, tarball)
  remote_path = tarball[tarball.index('/')..]

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

  checksum = SlackBuilder.download uri, "slackbuilds/#{tarball}"
  sh(*upload_command(tarball, remote_path))
  checksum.hexdigest
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)
  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