Class: Resource

Inherits:
Object
  • Object
show all
Includes:
FileUtils
Defined in:
Library/Homebrew/resource.rb,
Library/Homebrew/extend/os/mac/resource.rb,
Library/Homebrew/extend/os/linux/resource.rb

Overview

Resource is the fundamental representation of an external resource. The primary formula download, along with other declared resources, are instances of this class.

Direct Known Subclasses

Go, PatchResource

Defined Under Namespace

Classes: Go, Partial, PatchResource

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name = nil, &block) ⇒ Resource

Returns a new instance of Resource.


22
23
24
25
26
27
28
29
30
31
32
# File 'Library/Homebrew/resource.rb', line 22

def initialize(name = nil, &block)
  @name = name
  @url = nil
  @version = nil
  @mirrors = []
  @specs = {}
  @checksum = nil
  @using = nil
  @patches = []
  instance_eval(&block) if block_given?
end

Instance Attribute Details

#checksumObject

Returns the value of attribute checksum


16
17
18
# File 'Library/Homebrew/resource.rb', line 16

def checksum
  @checksum
end

#download_strategyObject

Returns the value of attribute download_strategy


16
17
18
# File 'Library/Homebrew/resource.rb', line 16

def download_strategy
  @download_strategy
end

#mirrorsObject (readonly)

Returns the value of attribute mirrors


14
15
16
# File 'Library/Homebrew/resource.rb', line 14

def mirrors
  @mirrors
end

#nameObject

Formula name must be set after the DSL, as we have no access to the formula name before initialization of the formula


20
21
22
# File 'Library/Homebrew/resource.rb', line 20

def name
  @name
end

#ownerObject

Returns the value of attribute owner


14
15
16
# File 'Library/Homebrew/resource.rb', line 14

def owner
  @owner
end

#patchesObject (readonly)

Returns the value of attribute patches


14
15
16
# File 'Library/Homebrew/resource.rb', line 14

def patches
  @patches
end

#source_modified_timeObject (readonly)

Returns the value of attribute source_modified_time


14
15
16
# File 'Library/Homebrew/resource.rb', line 14

def source_modified_time
  @source_modified_time
end

#specsObject (readonly)

Returns the value of attribute specs


14
15
16
# File 'Library/Homebrew/resource.rb', line 14

def specs
  @specs
end

#usingObject (readonly)

Returns the value of attribute using


14
15
16
# File 'Library/Homebrew/resource.rb', line 14

def using
  @using
end

#version(val = nil) ⇒ Object


165
166
167
168
169
170
# File 'Library/Homebrew/resource.rb', line 165

def version(val = nil)
  @version ||= begin
    version = detect_version(val)
    version.null? ? nil : version
  end
end

Instance Method Details

#apply_patchesObject


94
95
96
97
98
99
# File 'Library/Homebrew/resource.rb', line 94

def apply_patches
  return if patches.empty?

  ohai "Patching #{name}"
  patches.each(&:apply)
end

#cached_downloadObject


62
63
64
# File 'Library/Homebrew/resource.rb', line 62

def cached_download
  downloader.cached_location
end

#clear_cacheObject


66
67
68
# File 'Library/Homebrew/resource.rb', line 66

def clear_cache
  downloader.clear_cache
end

#download_nameObject


51
52
53
54
55
56
# File 'Library/Homebrew/resource.rb', line 51

def download_name
  return owner.name if name.nil?
  return escaped_name if owner.nil?

  "#{owner.name}--#{escaped_name}"
end

#downloaded?Boolean

Returns:

  • (Boolean)

58
59
60
# File 'Library/Homebrew/resource.rb', line 58

def downloaded?
  cached_download.exist?
end

#downloaderObject


39
40
41
42
# File 'Library/Homebrew/resource.rb', line 39

def downloader
  @downloader ||= download_strategy.new(url, download_name, version,
                                        mirrors: mirrors.dup, **specs)
end

#escaped_nameObject

Removes /s from resource names; this allows go package names to be used as resource names without confusing software that interacts with download_name, e.g. github.com/foo/bar


47
48
49
# File 'Library/Homebrew/resource.rb', line 47

def escaped_name
  name.tr("/", "-")
end

#fetch(verify_download_integrity: true) ⇒ Object


125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'Library/Homebrew/resource.rb', line 125

def fetch(verify_download_integrity: true)
  HOMEBREW_CACHE.mkpath

  fetch_patches

  begin
    downloader.fetch
  rescue ErrorDuringExecution, CurlDownloadStrategyError => e
    raise DownloadError.new(self, e)
  end

  download = cached_download
  verify_download_integrity(download) if verify_download_integrity
  download
end

#fetch_patches(skip_downloaded: false) ⇒ Object


88
89
90
91
92
# File 'Library/Homebrew/resource.rb', line 88

def fetch_patches(skip_downloaded: false)
  external_patches = patches.select(&:external?)
  external_patches.reject!(&:downloaded?) if skip_downloaded
  external_patches.each(&:fetch)
end

#files(*files) ⇒ Object


121
122
123
# File 'Library/Homebrew/resource.rb', line 121

def files(*files)
  Partial.new(self, files)
end

#mirror(val) ⇒ Object


172
173
174
# File 'Library/Homebrew/resource.rb', line 172

def mirror(val)
  mirrors << val
end

#on_linux(&_block) ⇒ Object

Block only executed on Linux. No-op on macOS.

on_linux do
  url "linux_only_url"
end

191
# File 'Library/Homebrew/resource.rb', line 191

def on_linux(&_block); end

#on_macos(&_block) ⇒ Object

Block only executed on macOS. No-op on Linux.

on_macos do
  url "mac_only_url"
end

185
# File 'Library/Homebrew/resource.rb', line 185

def on_macos(&_block); end

#patch(strip = :p1, src = nil, &block) ⇒ Object


176
177
178
179
# File 'Library/Homebrew/resource.rb', line 176

def patch(strip = :p1, src = nil, &block)
  p = Patch.create(strip, src, &block)
  patches << p
end

#prepare_patchesObject


84
85
86
# File 'Library/Homebrew/resource.rb', line 84

def prepare_patches
  patches.grep(DATAPatch) { |p| p.path = owner.owner.path }
end

#stage(target = nil, &block) ⇒ Object

Verifies download and unpacks it. The block may call |resource,staging| staging.retain! to retain the staging directory. Subclasses that override stage should implement the tmp dir using Mktemp so that works with all subtypes.

Raises:

  • (ArgumentError)

74
75
76
77
78
79
80
81
82
# File 'Library/Homebrew/resource.rb', line 74

def stage(target = nil, &block)
  raise ArgumentError, "target directory or block is required" if !target && block.blank?

  prepare_patches
  fetch_patches(skip_downloaded: true)
  fetch unless downloaded?

  unpack(target, &block)
end

#unpack(target = nil) ⇒ Object

If a target is given, unpack there; else unpack to a temp folder. If block is given, yield to that block with |stage|, where stage is a ResourceStageContext. A target or a block must be given, but not both.


105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'Library/Homebrew/resource.rb', line 105

def unpack(target = nil)
  mktemp(download_name) do |staging|
    downloader.stage
    @source_modified_time = downloader.source_modified_time
    apply_patches
    if block_given?
      yield ResourceStageContext.new(self, staging)
    elsif target
      target = Pathname(target)
      target.install Pathname.pwd.children
    end
  end
end

#url(val = nil, **specs) ⇒ Object


156
157
158
159
160
161
162
163
# File 'Library/Homebrew/resource.rb', line 156

def url(val = nil, **specs)
  return @url if val.nil?

  @url = val
  @specs.merge!(specs)
  @using = @specs.delete(:using)
  @download_strategy = DownloadStrategyDetector.detect(url, using)
end

#verify_download_integrity(fn) ⇒ Object


141
142
143
144
145
146
147
148
149
150
# File 'Library/Homebrew/resource.rb', line 141

def verify_download_integrity(fn)
  if fn.file?
    ohai "Verifying #{fn.basename} checksum" if Homebrew.args.verbose?
    fn.verify_checksum(checksum)
  end
rescue ChecksumMissingError
  opoo "Cannot verify integrity of #{fn.basename}"
  puts "A checksum was not provided for this resource."
  puts "For your reference the SHA-256 is: #{fn.sha256}"
end