Class: Bundix::Fetcher

Inherits:
Object
  • Object
show all
Defined in:
lib/bundix/source.rb

Instance Method Summary collapse

Instance Method Details

#debrief_access_denied(host) ⇒ Object



43
44
45
46
47
48
49
# File 'lib/bundix/source.rb', line 43

def debrief_access_denied(host)
  print_error(
    "Authentication is required for #{host}.\n" +
    "Please supply credentials for this source. You can do this by running:\n" +
    " bundle config packages.shopify.io username:password"
  )
end

#download(file, url) ⇒ Object



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
# File 'lib/bundix/source.rb', line 7

def download(file, url)
  warn "Downloading #{file} from #{url}"
  uri = URI(url)
  open_options = {}

  unless uri.user
    inject_credentials_from_bundler_settings(uri)
  end

  if uri.user
    open_options[:http_basic_authentication] = [uri.user, uri.password]
    uri.user = nil
    uri.password = nil
  end

  begin
    open(uri.to_s, 'r', 0600, open_options) do |net|
      File.open(file, 'wb+') { |local|
        File.copy_stream(net, local)
      }
    end
  rescue OpenURI::HTTPError => e
    # e.message: "403 Forbidden" or "401 Unauthorized"
    debrief_access_denied(uri.host) if e.message =~ /^40[13] /
    raise
  end
end

#fetch_local_hash(spec) ⇒ Object



94
95
96
97
98
99
100
101
102
103
# File 'lib/bundix/source.rb', line 94

def fetch_local_hash(spec)
  spec.source.caches.each do |cache|
    path = File.join(cache, "#{spec.full_name}.gem")
    next unless File.file?(path)
    hash = nix_prefetch_url(path)[SHA256_32]
    return format_hash(hash) if hash
  end

  nil
end

#fetch_remote_hash(spec, remote) ⇒ Object



114
115
116
117
118
119
120
121
122
123
# File 'lib/bundix/source.rb', line 114

def fetch_remote_hash(spec, remote)
  uri = "#{remote}/gems/#{spec.full_name}.gem"
  result = nix_prefetch_url(uri)
  return unless result
  result[SHA256_32]
rescue => e
  puts "ignoring error during fetching: #{e}"
  puts e.backtrace
  nil
end

#fetch_remotes_hash(spec, remotes) ⇒ Object



105
106
107
108
109
110
111
112
# File 'lib/bundix/source.rb', line 105

def fetch_remotes_hash(spec, remotes)
  remotes.each do |remote|
    hash = fetch_remote_hash(spec, remote)
    return remote, format_hash(hash) if hash
  end

  nil
end

#format_hash(hash) ⇒ Object



90
91
92
# File 'lib/bundix/source.rb', line 90

def format_hash(hash)
  sh(NIX_HASH, '--type', 'sha256', '--to-base32', hash)[SHA256_32]
end

#inject_credentials_from_bundler_settings(uri) ⇒ Object



35
36
37
38
39
40
41
# File 'lib/bundix/source.rb', line 35

def inject_credentials_from_bundler_settings(uri)
  @bundler_settings ||= Bundler::Settings.new(Bundler.root + '.bundle')

  if val = @bundler_settings[uri.host]
    uri.user, uri.password = val.split(':', 2)
  end
end

#nix_prefetch_git(uri, revision, submodules: false) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/bundix/source.rb', line 75

def nix_prefetch_git(uri, revision, submodules: false)
  home = ENV['HOME']
  ENV['HOME'] = '/homeless-shelter'

  args = []
  args << '--url' << uri
  args << '--rev' << revision
  args << '--hash' << 'sha256'
  args << '--fetch-submodules' if submodules

  sh(NIX_PREFETCH_GIT, *args)
ensure
  ENV['HOME'] = home
end

#nix_prefetch_url(url) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/bundix/source.rb', line 56

def nix_prefetch_url(url)
  dir = File.join(ENV['XDG_CACHE_HOME'] || "#{ENV['HOME']}/.cache", 'bundix')
  FileUtils.mkdir_p dir
  file = File.join(dir, url.gsub(/[^\w-]+/, '_'))

  download(file, url) unless File.size?(file)
  return unless File.size?(file)

  sh(
    Bundix::NIX_PREFETCH_URL,
    '--type', 'sha256',
    '--name', File.basename(url), # --name mygem-1.2.3.gem
    "file://#{file}",             # file:///.../https_rubygems_org_gems_mygem-1_2_3_gem
  ).force_encoding('UTF-8').strip
rescue => ex
  puts ex
  nil
end


51
52
53
54
# File 'lib/bundix/source.rb', line 51

def print_error(msg)
  msg = "\x1b[31m#{msg}\x1b[0m" if $stdout.tty?
  STDERR.puts(msg)
end

#sh(*args, &block) ⇒ Object



3
4
5
# File 'lib/bundix/source.rb', line 3

def sh(*args, &block)
  Bundix.sh(*args, &block)
end