File: install

package info (click to toggle)
linuxbrew-wrapper 20180923-1
  • links: PTS, VCS
  • area: contrib
  • in suites: buster
  • size: 160 kB
  • sloc: ruby: 677; sh: 73; makefile: 6
file content (520 lines) | stat: -rwxr-xr-x 17,196 bytes parent folder | download
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
#!/usr/bin/env ruby
# This script installs only to /usr/local on macOS.
# On Linux, it installs to /home/linuxbrew/.linuxbrew if you have sudo access
# and ~/.linuxbrew otherwise.
# To install elsewhere you can untar
# https://github.com/Linuxbrew/brew/tarball/master anywhere you like
# or set the environment variable HOMEBREW_PREFIX.

def mac?
  RUBY_PLATFORM[/darwin/]
end

def linux?
  RUBY_PLATFORM[/linux/]
end

if mac?
  HOMEBREW_NAME = "Homebrew".freeze
  HOMEBREW_PREFIX = "/usr/local".freeze
  HOMEBREW_REPOSITORY = "/usr/local/Homebrew".freeze
  HOMEBREW_CACHE = "#{ENV["HOME"]}/Library/Caches/Homebrew".freeze
  HOMEBREW_OLD_CACHE = "/Library/Caches/Homebrew".freeze
  BREW_REPO = "https://github.com/Homebrew/brew".freeze
  CORE_TAP_REPO = "https://github.com/Homebrew/homebrew-core".freeze
else
  HOMEBREW_NAME = "Linuxbrew".freeze
  HOMEBREW_PREFIX_DEFAULT = "/home/linuxbrew/.linuxbrew".freeze
  HOMEBREW_CACHE = "#{ENV["HOME"]}/.cache/Homebrew".freeze
  HOMEBREW_OLD_CACHE = nil
  BREW_REPO = "https://github.com/Linuxbrew/brew".freeze
  CORE_TAP_REPO = "https://github.com/Linuxbrew/homebrew-core".freeze
end

# TODO: bump version when new macOS is released
MACOS_LATEST_SUPPORTED = "10.14".freeze
# TODO: bump version when new macOS is released
MACOS_OLDEST_SUPPORTED = "10.12".freeze

# no analytics during installation
ENV["HOMEBREW_NO_ANALYTICS_THIS_RUN"] = "1"
ENV["HOMEBREW_NO_ANALYTICS_MESSAGE_OUTPUT"] = "1"

# get nicer global variables
require "English"

module Tty
  module_function

  def blue
    bold 34
  end

  def red
    bold 31
  end

  def reset
    escape 0
  end

  def bold(code = 39)
    escape "1;#{code}"
  end

  def underline
    escape "4;39"
  end

  def escape(code)
    "\033[#{code}m" if STDOUT.tty?
  end
end

class Array
  def shell_s
    cp = dup
    first = cp.shift
    cp.map { |arg| arg.gsub " ", "\\ " }.unshift(first).join(" ")
  end
end

def ohai(*args)
  puts "#{Tty.blue}==>#{Tty.bold} #{args.shell_s}#{Tty.reset}"
end

def warn(warning)
  puts "#{Tty.red}Warning#{Tty.reset}: #{warning.chomp}"
end

def system(*args)
  abort "Failed during: #{args.shell_s}" unless Kernel.system(*args)
end

def sudo?
  return @have_sudo unless @have_sudo.nil?

  Kernel.system "/usr/bin/sudo", "-v"
  @have_sudo = $CHILD_STATUS && $CHILD_STATUS.success?
end

def sudo(*args)
  if sudo?
    args.unshift("-A") unless ENV["SUDO_ASKPASS"].nil?
    ohai "/usr/bin/sudo", *args
    system "/usr/bin/sudo", *args
  else
    ohai *args
    system *args
  end
end

def getc
  system "/bin/stty raw -echo"
  if STDIN.respond_to?(:getbyte)
    STDIN.getbyte
  else
    STDIN.getc
  end
ensure
  system "/bin/stty -raw echo"
end

def wait_for_user
  puts
  puts "Press RETURN to continue or any other key to abort"
  c = getc
  # we test for \r and \n because some stuff does \r instead
  abort unless (c == 13) || (c == 10)
end

class Version
  include Comparable
  attr_reader :parts

  def initialize(str)
    @parts = str.split(".").map { |p| p.to_i }
  end

  def <=>(other)
    parts <=> self.class.new(other).parts
  end
end

def force_curl?
  ARGV.include?("--force-curl")
end

def macos_version
  return unless mac?

  @macos_version ||= Version.new(`/usr/bin/sw_vers -productVersion`.chomp[/10\.\d+/])
end

def should_install_command_line_tools?
  return false unless mac?
  return false if force_curl?
  return false if macos_version < "10.9"

  if macos_version > "10.13"
    !File.exist?("/Library/Developer/CommandLineTools/usr/bin/git")
  else
    !File.exist?("/Library/Developer/CommandLineTools/usr/bin/git") ||
      !File.exist?("/usr/include/iconv.h")
  end
end

def git
  return false if force_curl?

  @git ||= if ENV["GIT"] && File.executable?(ENV["GIT"])
    ENV["GIT"]
  elsif Kernel.system "/usr/bin/which git >/dev/null"
    "git"
  else
    exe = `xcrun -find git 2>/dev/null`.chomp
    exe if $CHILD_STATUS && $CHILD_STATUS.success? && !exe.empty? && File.executable?(exe)
  end

  return unless @git

  # Github only supports HTTPS fetches on 1.7.10 or later:
  # https://help.github.com/articles/https-cloning-errors
  `#{@git} --version` =~ /git version (\d\.\d+\.\d+)/
  return if Regexp.last_match(1).nil?
  return if Version.new(Regexp.last_match(1)) < "1.7.10"

  @git
end

def user_only_chmod?(path)
  return false unless File.directory?(path)

  mode = File.stat(path).mode & 0777
  # u = (mode >> 6) & 07
  # g = (mode >> 3) & 07
  # o = (mode >> 0) & 07
  mode != 0755
end

def chmod?(path)
  File.exist?(path) && !(File.readable?(path) && File.writable?(path) && File.executable?(path))
end

def chown?(path)
  !File.owned?(path)
end

def chgrp?(path)
  !File.grpowned?(path)
end

# return the shell profile file based on users' preference shell
def shell_profile
  case ENV["SHELL"]
  when %r{/bash$} && File.readable?("~/.bash_profile") then "~/.bash_profile"
  when %r{/zsh$} then "~/.zprofile"
  else "~/.profile"
  end
end

# Invalidate sudo timestamp before exiting (if it wasn't active before).
Kernel.system "/usr/bin/sudo -n -v 2>/dev/null"
at_exit { Kernel.system "/usr/bin/sudo", "-k" } unless $CHILD_STATUS.success?

# The block form of Dir.chdir fails later if Dir.CWD doesn't exist which I
# guess is fair enough. Also sudo prints a warning message for no good reason
Dir.chdir "/usr"

####################################################################### script
abort "Mac OS X too old, see: https://github.com/mistydemeo/tigerbrew" if mac? && macos_version < "10.5"
abort "Don't run this as root!" if Process.uid.zero?
abort <<-EOABORT unless !mac? || `dsmemberutil checkmembership -U "#{ENV["USER"]}" -G admin`.include?("user is a member")
This script requires the user #{ENV["USER"]} to be an Administrator.
EOABORT

unless mac?
  if File.writable?(HOMEBREW_PREFIX_DEFAULT) || File.writable?("/home/linuxbrew") || File.writable?("/home")
    HOMEBREW_PREFIX = HOMEBREW_PREFIX_DEFAULT.freeze
  else
    Kernel.system "/usr/bin/sudo -n -v 2>/dev/null"
    unless $CHILD_STATUS.success?
      ohai "Select the Linuxbrew installation directory"
      puts "- #{Tty.bold}Enter your password#{Tty.reset} to install to #{Tty.underline}#{HOMEBREW_PREFIX_DEFAULT}#{Tty.reset} (#{Tty.bold}recommended#{Tty.reset})"
      puts "- #{Tty.bold}Press Control-D#{Tty.reset} to install to #{Tty.underline}#{ENV["HOME"]}/.linuxbrew#{Tty.reset}"
      puts "- #{Tty.bold}Press Control-C#{Tty.reset} to cancel installation"
    end
    if sudo?
      HOMEBREW_PREFIX = HOMEBREW_PREFIX_DEFAULT.freeze
    else
      HOMEBREW_PREFIX = "#{ENV["HOME"]}/.linuxbrew".freeze
    end
  end
  HOMEBREW_REPOSITORY = "#{HOMEBREW_PREFIX}/Homebrew".freeze
end

# Tests will fail if the prefix exists, but we don't have execution
# permissions. Abort in this case.
abort <<-EOABORT if File.directory?(HOMEBREW_PREFIX) && (!File.executable? HOMEBREW_PREFIX)
The Homebrew prefix, #{HOMEBREW_PREFIX}, exists but is not searchable. If this is
not intentional, please restore the default permissions and try running the
installer again:
    sudo chmod 775 #{HOMEBREW_PREFIX}
EOABORT

# TODO: bump version when new macOS is released
if mac? && (macos_version > MACOS_LATEST_SUPPORTED ||
   macos_version < MACOS_OLDEST_SUPPORTED)

  who = "We"
  if macos_version > MACOS_LATEST_SUPPORTED
    what = "pre-release version"
  elsif macos_version < MACOS_OLDEST_SUPPORTED
    who << " (and Apple)"
    what = "old version"
  else
    return
  end
  ohai "You are using macOS #{macos_version.parts.join(".")}."
  ohai "#{who} do not provide support for this #{what}."

  puts <<-EOS
This installation may not succeed.
After installation, you will encounter build failures and other breakages.
Please create pull-requests instead of asking for help on Homebrew's
GitHub, Discourse, Twitter or IRC. As you are running this #{what},
you are responsible for resolving any issues you experience.

  EOS
end

ohai "This script will install:"
puts "#{HOMEBREW_PREFIX}/bin/brew"
puts "#{HOMEBREW_PREFIX}/share/doc/homebrew"
puts "#{HOMEBREW_PREFIX}/share/man/man1/brew.1"
puts "#{HOMEBREW_PREFIX}/share/zsh/site-functions/_brew"
puts "#{HOMEBREW_PREFIX}/etc/bash_completion.d/brew"
puts "#{HOMEBREW_CACHE}/"
puts HOMEBREW_REPOSITORY.to_s

# Keep relatively in sync with
# https://github.com/Homebrew/brew/blob/master/Library/Homebrew/keg.rb
group_chmods = %w[bin etc include lib sbin share opt var
                  Frameworks
                  etc/bash_completion.d lib/pkgconfig
                  share/aclocal share/doc share/info share/locale share/man
                  share/man/man1 share/man/man2 share/man/man3 share/man/man4
                  share/man/man5 share/man/man6 share/man/man7 share/man/man8
                  var/log
                  bin/brew].
               map { |d| File.join(HOMEBREW_PREFIX, d) }.
               select { |d| chmod?(d) }
# zsh refuses to read from these directories if group writable
zsh_dirs = %w[share/zsh share/zsh/site-functions].
           map { |d| File.join(HOMEBREW_PREFIX, d) }
mkdirs = %w[bin etc include lib sbin share var opt
            share/zsh share/zsh/site-functions
            Cellar Caskroom Homebrew Frameworks].
         map { |d| File.join(HOMEBREW_PREFIX, d) }.
         reject { |d| File.directory?(d) }

user_chmods = zsh_dirs.select { |d| user_only_chmod?(d) }
chmods = group_chmods + user_chmods
chowns = chmods.select { |d| chown?(d) }
chgrps = chmods.select { |d| chgrp?(d) }

group = `id -gn`.chomp
abort "error: id -gn: failed" unless $CHILD_STATUS.success? && !group.empty?

unless group_chmods.empty?
  ohai "The following existing directories will be made group writable:"
  puts(*group_chmods)
end
unless user_chmods.empty?
  ohai "The following existing directories will be made writable by user only:"
  puts(*user_chmods)
end
unless chowns.empty?
  ohai "The following existing directories will have their owner set to #{Tty.underline}#{ENV["USER"]}#{Tty.reset}:"
  puts(*chowns)
end
unless chgrps.empty?
  ohai "The following existing directories will have their group set to #{Tty.underline}#{group}#{Tty.reset}:"
  puts(*chgrps)
end
unless mkdirs.empty?
  ohai "The following new directories will be created:"
  puts(*mkdirs)
end
if should_install_command_line_tools?
  ohai "The Xcode Command Line Tools will be installed."
end

wait_for_user if STDIN.tty? && !ENV["CI"]

if File.directory? HOMEBREW_PREFIX
  sudo "/bin/chmod", "u+rwx", *chmods unless chmods.empty?
  sudo "/bin/chmod", "g+rwx", *group_chmods unless group_chmods.empty?
  sudo "/bin/chmod", "755", *user_chmods unless user_chmods.empty?
  sudo "/bin/chown", ENV["USER"], *chowns unless chowns.empty?
  sudo "/bin/chgrp", group, *chgrps unless chgrps.empty?
else
  sudo "/bin/mkdir", "-p", HOMEBREW_PREFIX
  sudo "/bin/chown", "#{ENV["USER"]}:#{group}", HOMEBREW_PREFIX
end

unless mkdirs.empty?
  sudo "/bin/mkdir", "-p", *mkdirs
  sudo "/bin/chmod", "g+rwx", *mkdirs
  sudo "/bin/chmod", "755", *zsh_dirs
  sudo "/bin/chown", ENV["USER"], *mkdirs
  sudo "/bin/chgrp", group, *mkdirs
end

[HOMEBREW_CACHE, HOMEBREW_OLD_CACHE].compact.each do |cache|
  sudo "/bin/mkdir", "-p", cache unless File.directory? cache
  sudo "/bin/chmod", "g+rwx", cache if chmod? cache
  sudo "/bin/chown", ENV["USER"], cache if chown? cache
  sudo "/bin/chgrp", group, cache if chgrp? cache
end

if should_install_command_line_tools?
  ohai "Searching online for the Command Line Tools"
  # This temporary file prompts the 'softwareupdate' utility to list the Command Line Tools
  clt_placeholder = "/tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress"
  sudo "/usr/bin/touch", clt_placeholder
  clt_label = `/usr/sbin/softwareupdate -l | grep -B 1 -E "Command Line (Developer|Tools)" | awk -F"*" '/^ +\\*/ {print $2}' | sed 's/^ *//' | tail -n1`.chomp
  ohai "Installing #{clt_label}"
  sudo "/usr/sbin/softwareupdate", "-i", clt_label
  sudo "/bin/rm", "-f", clt_placeholder
  sudo "/usr/bin/xcode-select", "--switch", "/Library/Developer/CommandLineTools"
end

# Headless install may have failed, so fallback to original 'xcode-select' method
if should_install_command_line_tools? && STDIN.tty?
  ohai "Installing the Command Line Tools (expect a GUI popup):"
  sudo "/usr/bin/xcode-select", "--install"
  puts "Press any key when the installation has completed."
  getc
  sudo "/usr/bin/xcode-select", "--switch", "/Library/Developer/CommandLineTools"
end

abort <<-EOABORT if mac? && `/usr/bin/xcrun clang 2>&1` =~ /license/ && !$CHILD_STATUS.success?
You have not agreed to the Xcode license.
Before running the installer again please agree to the license by opening
Xcode.app or running:
    sudo xcodebuild -license
EOABORT

ohai "Downloading and installing #{HOMEBREW_NAME}..."
Dir.chdir HOMEBREW_REPOSITORY do
  if git
    # we do it in four steps to avoid merge errors when reinstalling
    system git, "init", "-q"

    # "git remote add" will fail if the remote is defined in the global config
    system git, "config", "remote.origin.url", BREW_REPO
    system git, "config", "remote.origin.fetch", "+refs/heads/*:refs/remotes/origin/*"

    # ensure we don't munge line endings on checkout
    system git, "config", "core.autocrlf", "false"

    args = git, "fetch", "origin", "master:refs/remotes/origin/master",
           "--tags", "--force"
    system(*args)

    system git, "reset", "--hard", "origin/master"

    system "ln", "-sf", "#{HOMEBREW_REPOSITORY}/bin/brew", "#{HOMEBREW_PREFIX}/bin/brew" unless HOMEBREW_REPOSITORY == HOMEBREW_PREFIX

    system "#{HOMEBREW_PREFIX}/bin/brew", "update", "--force"
  else
    # -m to stop tar erroring out if it can't modify the mtime for root owned directories
    # pipefail to cause the exit status from curl to propagate if it fails
    curl_flags = "fsSL"
    curl_flags += "k" if mac? && macos_version < "10.6"
    core_tap = "#{HOMEBREW_PREFIX}/Homebrew/Library/Taps/homebrew/homebrew-core"
    system "/bin/bash -o pipefail -c 'curl -#{curl_flags} #{BREW_REPO}/tarball/master | /bin/tar xz -m --strip 1'"

    system "ln", "-sf", "#{HOMEBREW_REPOSITORY}/bin/brew", "#{HOMEBREW_PREFIX}/bin/brew" unless HOMEBREW_REPOSITORY == HOMEBREW_PREFIX

    system "/bin/mkdir", "-p", core_tap
    Dir.chdir core_tap do
      system "/bin/bash -o pipefail -c 'curl -#{curl_flags} #{CORE_TAP_REPO}/tarball/master | /bin/tar xz -m --strip 1'"
    end
  end
end

ohai "Installation successful!"
puts

# Use the shell's audible bell.
print "\a"

# Use an extra newline and bold to avoid this being missed.
ohai "Homebrew has enabled anonymous aggregate formulae and cask analytics."
puts <<-EOS
#{Tty.bold}Read the analytics documentation (and how to opt-out) here:
  #{Tty.underline}https://docs.brew.sh/Analytics.html#{Tty.reset}

EOS

ohai "Homebrew is run entirely by unpaid volunteers. Please consider donating:"
puts <<-EOS
  #{Tty.underline}https://github.com/Homebrew/brew#donations#{Tty.reset}
EOS

if git
  Dir.chdir HOMEBREW_REPOSITORY do
    system git, "config", "--local", "--replace-all", "homebrew.analyticsmessage", "true"
    system git, "config", "--local", "--replace-all", "homebrew.caskanalyticsmessage", "true"
  end
end

ohai "Next steps:"

if !mac?
  puts <<-EOS
- Install the Linuxbrew dependencies if you have sudo access:
  #{Tty.bold}Debian, Ubuntu, etc.#{Tty.reset}
    sudo apt-get install build-essential
  #{Tty.bold}Fedora, Red Hat, CentOS, etc.#{Tty.reset}
    sudo yum groupinstall 'Development Tools'
  See #{Tty.underline}http://linuxbrew.sh/#dependencies#{Tty.reset} for more information.
- Add Linuxbrew to your #{Tty.underline}#{shell_profile}#{Tty.reset} by running
    echo 'export PATH="#{HOMEBREW_PREFIX}/bin:$PATH"' >>#{shell_profile}
    echo 'export MANPATH="#{HOMEBREW_PREFIX}/share/man:$MANPATH"' >>#{shell_profile}
    echo 'export INFOPATH="#{HOMEBREW_PREFIX}/share/info:$INFOPATH"' >>#{shell_profile}
- Add Linuxbrew to your #{Tty.bold}PATH#{Tty.reset}
    PATH="#{HOMEBREW_PREFIX}/bin:$PATH"
- We recommend that you install GCC by running:
    brew install gcc
- After modifying your shell profile, you may need to restart your session
  (logout and then log back in) if the brew command isn't found.
  EOS
elsif macos_version < "10.9" && macos_version > "10.6"
  `/usr/bin/cc --version 2> /dev/null` =~ /clang-(\d{2,})/
  version = Regexp.last_match(1).to_i
  if version < 425
    puts "- Install the #{Tty.bold}Command Line Tools for Xcode:"
    puts "    #{Tty.underline}https://developer.apple.com/downloads#{Tty.reset}"
  end
elsif !File.exist? "/usr/bin/cc"
  puts "- Install #{Tty.bold}Xcode:"
  puts "    #{Tty.underline}https://developer.apple.com/xcode#{Tty.reset}"
end

unless git
  puts "- Run `brew update --force` to complete installation by installing:"
  puts "    #{HOMEBREW_PREFIX}/share/doc/homebrew"
  puts "    #{HOMEBREW_PREFIX}/share/man/man1/brew.1"
  puts "    #{HOMEBREW_PREFIX}/share/zsh/site-functions/_brew"
  puts "    #{HOMEBREW_PREFIX}/etc/bash_completion.d/brew"
  puts "    #{HOMEBREW_REPOSITORY}/.git"
end

puts "- Run `brew help` to get started"
puts "- Further documentation: "
puts "    #{Tty.underline}https://docs.brew.sh#{Tty.reset}"

warn "#{HOMEBREW_PREFIX}/bin is not in your PATH." unless ENV["PATH"].split(":").include? "#{HOMEBREW_PREFIX}/bin"