File: uninstall

package info (click to toggle)
linuxbrew-wrapper 20160916-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 108 kB
  • ctags: 47
  • sloc: ruby: 466; sh: 55; makefile: 10
file content (253 lines) | stat: -rwxr-xr-x 7,333 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
#!/usr/bin/env ruby

require "fileutils"
require "optparse"
require "pathname"

# Default options
options = {
  :force => false,
  :quiet => false,
  :dry_run => false,
  :skip_cache_and_logs => false,
}

# global status to indicate whether there is anything wrong.
$failed = false

module Tty extend self
  def blue; bold 34; end
  def white; bold 39; end
  def red; underline 31; end
  def reset; escape 0; end
  def bold n; escape "1;#{n}" end
  def underline n; escape "4;#{n}" end
  def escape n; "\033[#{n}m" if STDOUT.tty? end
end

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

class Pathname
  def resolved_path
    self.symlink? ? dirname+readlink : self
  end

  def /(other)
    self + other.to_s
  end

  def pretty_print
    if self.symlink?
      puts to_s + " -> " + resolved_path.to_s
    elsif self.directory?
      puts to_s + "/"
    else
      puts to_s
    end
  end
end

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

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

def system *args
  unless Kernel.system(*args)
    warn "Failed during: #{args.shell_s}"
    $failed = true
  end
end

####################################################################### script

$HOMEBREW_PREFIX_CANDIDATES=[]

OptionParser.new do |opts|
  opts.banner = "Homebrew Uninstaller\nUsage: ./uninstall [options]"
  opts.summary_width = 16
  opts.on("-pPATH", "--path=PATH", "Sets Homebrew prefix. Defaults to /usr/local.") { |p| $HOMEBREW_PREFIX_CANDIDATES << Pathname.new(p) }
  opts.on("--skip-cache-and-logs", "Skips removal of HOMEBREW_CACHE and HOMEBREW_LOGS.") { |p| options[:skip_cache_and_logs] = true }
  opts.on("-f", "--force", "Uninstall without prompting.") { options[:force] = true }
  opts.on("-q", "--quiet", "Suppress all output.") { options[:quiet] = true }
  opts.on("-d", "--dry-run", "Simulate uninstall but don't remove anything.") { options[:dry_run] = true }
  opts.on_tail("-h", "--help", "Display this message.") { puts opts; exit }
end.parse!

if $HOMEBREW_PREFIX_CANDIDATES.empty? # Attempt to locate Homebrew unless `--path` is passed
  p = `brew --prefix` rescue ""
  $HOMEBREW_PREFIX_CANDIDATES << Pathname.new(p.strip) unless p.empty?
  p = `command -v brew` rescue `which brew` rescue ""
  $HOMEBREW_PREFIX_CANDIDATES << Pathname.new(p.strip).dirname.parent unless p.empty?
  $HOMEBREW_PREFIX_CANDIDATES << Pathname.new("/usr/local") # Homebrew default path
  $HOMEBREW_PREFIX_CANDIDATES << Pathname.new("#{ENV["HOME"]}/.linuxbrew") # Linuxbrew default path
end

HOMEBREW_PREFIX = $HOMEBREW_PREFIX_CANDIDATES.detect do |p|
  p.directory? && (p/".git").exist? || (p/"bin/brew").executable?
end
abort "Failed to locate Homebrew!" if HOMEBREW_PREFIX.nil?

HOMEBREW_REPOSITORY = (HOMEBREW_PREFIX/".git").realpath.dirname || (HOMEBREW_PREFIX/"bin/brew").realpath.dirname.parent
HOMEBREW_CELLAR = if (HOMEBREW_PREFIX/"Cellar").exist?
  HOMEBREW_PREFIX/"Cellar"
else
  HOMEBREW_REPOSITORY/"Cellar"
end

gitignore = begin
  (HOMEBREW_REPOSITORY/".gitignore").read
rescue Errno::ENOENT
  `curl -fsSL https://raw.githubusercontent.com/Homebrew/brew/master/.gitignore`
end
abort "Failed to fetch Homebrew .gitignore!" if gitignore.empty?

$HOMEBREW_FILES = gitignore.split("\n").select { |line| line.start_with? "!" }.
  map { |line| line.chomp("/").gsub(%r{^!?/}, "") }.
  reject { |line| %w[bin share share/doc].include?(line) }.
  map { |p| HOMEBREW_REPOSITORY/p }
$HOMEBREW_FILES << HOMEBREW_REPOSITORY/".git"
$HOMEBREW_FILES << HOMEBREW_CELLAR

unless options[:skip_cache_and_logs]
  $HOMEBREW_FILES += %W[
    #{ENV["HOME"]}/Library/Caches/Homebrew
    #{ENV["HOME"]}/Library/Logs/Homebrew
    /Library/Caches/Homebrew
    #{ENV["HOME"]}/.cache/Homebrew
    #{ENV["HOMEBREW_CACHE"]}
    #{ENV["HOMEBREW_LOGS"]}
  ].map { |p| Pathname.new(p) }
end

if /darwin/i === RUBY_PLATFORM
  $HOMEBREW_FILES += %W[
    /Applications
    #{ENV["HOME"]}/Applications
  ].map { |p| Pathname.new(p) }.select(&:directory?).map do |p|
    p.children.select do |app|
      app.resolved_path.to_s.start_with? HOMEBREW_CELLAR.to_s
    end
  end.flatten
end

$HOMEBREW_FILES = $HOMEBREW_FILES.select(&:exist?).sort

unless options[:quiet]
  warn "This script #{options[:dry_run] ? "would" : "will"} remove:"
  $HOMEBREW_FILES.each(&:pretty_print)
end

if STDIN.tty? && (!options[:force] && !options[:dry_run])
  STDERR.print "Are you sure you want to uninstall Homebrew? [y/N] "
  abort unless gets.rstrip =~ /y|yes/i
end

ohai "Removing Homebrew installation..." unless options[:quiet]
paths = %W[Frameworks bin etc include lib opt sbin share var].
  map { |p| HOMEBREW_PREFIX/p }.select(&:exist?).map(&:to_s)
if paths.any?
  args = %W[-E] + paths + %W[-regex .*/info/([^.][^/]*\.info|dir)]
  if options[:dry_run]
    args << "-print"
  else
    args += %W[-exec /bin/bash -c]
    args << "/usr/bin/install-info --delete --quiet {} \"$(dirname {})/dir\""
    args << ";"
  end
  puts "Would delete:" if options[:dry_run]
  system "/usr/bin/find", *args
  args = paths + %W[-type l -lname */Cellar/*]
  if options[:dry_run]
    args << "-print"
  else
    args += %W[-exec unlink {} ;]
  end
  puts "Would delete:" if options[:dry_run]
  system "/usr/bin/find", *args
end

$HOMEBREW_FILES.each do |file|
  if options[:dry_run]
    puts "Would delete #{file}"
  else
    begin
      FileUtils.rm_rf(file)
    rescue => e
      warn "Failed to delete #{file}"
      puts e.message
      $failed = true
    end
  end
end

ohai "Removing empty directories..." unless options[:quiet]
paths = %W[Frameworks bin etc include lib opt sbin share var].
  map { |p| HOMEBREW_PREFIX/p }.select(&:exist?).map(&:to_s)
if paths.any?
  args = paths + %W[-name .DS_Store]
  if options[:dry_run]
    args << "-print"
  else
    args << "-delete"
  end
  puts "Would delete:" if options[:dry_run]
  system "/usr/bin/find", *args
  args = paths + %W[-depth -type d -empty]
  if options[:dry_run]
    args << "-print"
  else
    args += %W[-exec rmdir {} ;]
  end
  puts "Would remove directories:" if options[:dry_run]
  system "/usr/bin/find", *args
end

if options[:dry_run]
  exit
else
  # remove HOMEBREW_REPOSITORY HOMEBREW_PREFIX if they're empty.
  Kernel.system "rmdir #{HOMEBREW_REPOSITORY} &>/dev/null"
  Kernel.system "rmdir #{HOMEBREW_PREFIX} &>/dev/null"
end

unless options[:quiet]
  if $failed
    warn "Homebrew partially uninstalled (but there were steps that failed)!"
    puts "To finish uninstalling rerun this script with `sudo`."
  else
    ohai "Homebrew uninstalled!"
  end
end

residual_files = []
residual_files.concat(HOMEBREW_REPOSITORY.children) if HOMEBREW_REPOSITORY.exist?
residual_files.concat(HOMEBREW_PREFIX.children) if HOMEBREW_PREFIX.exist?
residual_files.uniq!

unless residual_files.empty? || options[:quiet]
  puts "The following possible Homebrew files were not deleted:"
  residual_files.each(&:pretty_print)
  puts "You may consider to remove them by yourself.\n"
end

if /darwin/i === RUBY_PLATFORM && HOMEBREW_PREFIX.exist? &&
  HOMEBREW_PREFIX.to_s == "/usr/local" && !options[:quiet]
  puts <<-EOS
You may want to restore /usr/local's original permissions
  sudo chmod 0755 /usr/local
  sudo chgrp wheel /usr/local

EOS
end

exit 1 if $failed