aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/cmd
diff options
context:
space:
mode:
authorSimon Sigurdhsson2013-03-11 16:41:08 +0100
committerMike McQuaid2013-03-30 19:50:47 +0000
commitf8a88b5f28070b15eb31285f8ae6ffdd37e0859b (patch)
tree73a2cf37557a5939357fb637843558a2a5ed47a3 /Library/Homebrew/cmd
parent4a52bf1c3186b75551cb37cbf721da185291c384 (diff)
downloadbrew-f8a88b5f28070b15eb31285f8ae6ffdd37e0859b.tar.bz2
brew-pin: prevent selected formulae from upgrade.
* Added `pin` et. al. to manpage. * Added `brew pin` to `brew.1` * Added `brew unpin` to `brew.1` * Added `brew list --pinned` to `brew.1` * Added information about frozen formulae to `brew upgrade` in `brew.1` * Added `pin` et.al. to completion scripts. * Unpin formulae when uninstalling them * Unpin and re-pin formulae when upgrading (avoids stale symlink) References Homebrew/homebrew#18386. Closes Homebrew/homebrew#18515. Signed-off-by: Mike McQuaid <mike@mikemcquaid.com>
Diffstat (limited to 'Library/Homebrew/cmd')
-rw-r--r--Library/Homebrew/cmd/list.rb17
-rw-r--r--Library/Homebrew/cmd/pin.rb16
-rw-r--r--Library/Homebrew/cmd/uninstall.rb2
-rw-r--r--Library/Homebrew/cmd/unpin.rb16
-rw-r--r--Library/Homebrew/cmd/upgrade.rb20
5 files changed, 69 insertions, 2 deletions
diff --git a/Library/Homebrew/cmd/list.rb b/Library/Homebrew/cmd/list.rb
index 4b0aa4a13..3ce3b18e3 100644
--- a/Library/Homebrew/cmd/list.rb
+++ b/Library/Homebrew/cmd/list.rb
@@ -8,7 +8,10 @@ module Homebrew extend self
# Things below use the CELLAR, which doesn't until the first formula is installed.
return unless HOMEBREW_CELLAR.exist?
- if ARGV.include? '--versions'
+ if ARGV.include? '--pinned'
+ require 'formula'
+ list_pinned
+ elsif ARGV.include? '--versions'
list_versions
elsif ARGV.named.empty?
ENV['CLICOLOR'] = nil
@@ -48,6 +51,18 @@ private
puts "#{d.basename} #{versions*' '}"
end
end
+
+ def list_pinned
+ if ARGV.named.empty?
+ HOMEBREW_CELLAR.children.select{ |pn| pn.directory? }
+ else
+ ARGV.named.map{ |n| HOMEBREW_CELLAR+n }.select{ |pn| pn.exist? }
+ end.select do |d|
+ Formula.factory(d.basename.to_s).pinned?
+ end.each do |d|
+ puts "#{d.basename}"
+ end
+ end
end
class PrettyListing
diff --git a/Library/Homebrew/cmd/pin.rb b/Library/Homebrew/cmd/pin.rb
new file mode 100644
index 000000000..26b487a0d
--- /dev/null
+++ b/Library/Homebrew/cmd/pin.rb
@@ -0,0 +1,16 @@
+require 'formula'
+
+module Homebrew extend self
+ def pin
+ if Process.uid.zero? and not File.stat(HOMEBREW_BREW_FILE).uid.zero?
+ abort "Cowardly refusing to `sudo pin'"
+ end
+ raise FormulaUnspecifiedError if ARGV.named.empty?
+ ARGV.formulae.each do |fmla|
+ f = Formula.factory(fmla.to_s)
+ onoe "Cannot pin uninstalled formula #{f.name}!" unless f.pinable?
+ opoo "Formula #{f.name} already pinned!" if f.pinable? and f.pinned?
+ f.pin if f.pinable? and not f.pinned?
+ end
+ end
+end
diff --git a/Library/Homebrew/cmd/uninstall.rb b/Library/Homebrew/cmd/uninstall.rb
index 19ad6eeb5..5a7479f9c 100644
--- a/Library/Homebrew/cmd/uninstall.rb
+++ b/Library/Homebrew/cmd/uninstall.rb
@@ -10,6 +10,7 @@ module Homebrew extend self
keg.lock do
puts "Uninstalling #{keg}..."
keg.unlink
+ Formula.factory(keg.fname).unpin
keg.uninstall
rm_opt_link keg.fname
end
@@ -28,6 +29,7 @@ module Homebrew extend self
if keg.directory?
keg = Keg.new(keg)
keg.unlink
+ Formula.factory(keg.fname).unpin
keg.rmtree
end
end
diff --git a/Library/Homebrew/cmd/unpin.rb b/Library/Homebrew/cmd/unpin.rb
new file mode 100644
index 000000000..6855db4bf
--- /dev/null
+++ b/Library/Homebrew/cmd/unpin.rb
@@ -0,0 +1,16 @@
+require 'formula'
+
+module Homebrew extend self
+ def unpin
+ if Process.uid.zero? and not File.stat(HOMEBREW_BREW_FILE).uid.zero?
+ abort "Cowardly refusing to `sudo unpin'"
+ end
+ raise FormulaUnspecifiedError if ARGV.named.empty?
+ ARGV.formulae.each do |fmla|
+ f = Formula.factory(fmla.to_s)
+ onoe "Cannot unpin uninstalled formula #{f.name}!" unless f.pinable?
+ opoo "Formula #{f.name} already unpinned!" if f.pinable? and not f.pinned?
+ f.unpin if f.pinable? and f.pinned?
+ end
+ end
+end
diff --git a/Library/Homebrew/cmd/upgrade.rb b/Library/Homebrew/cmd/upgrade.rb
index b5effee50..af2e4a0e1 100644
--- a/Library/Homebrew/cmd/upgrade.rb
+++ b/Library/Homebrew/cmd/upgrade.rb
@@ -18,8 +18,10 @@ module Homebrew extend self
if ARGV.named.empty?
require 'cmd/outdated'
+ upgrade_pinned = false
outdated = Homebrew.outdated_brews
else
+ upgrade_pinned = true
outdated = ARGV.formulae.select do |f|
if f.installed?
onoe "#{f}-#{f.installed_version} already installed"
@@ -32,10 +34,19 @@ module Homebrew extend self
exit 1 if outdated.empty?
end
- if outdated.length > 1
+ unless upgrade_pinned
+ pinned = outdated.select { |f| f.pinned? }
+ outdated -= pinned
+ end
+
+ if outdated.length > 0
oh1 "Upgrading #{outdated.length} outdated package#{outdated.length.plural_s}, with result:"
puts outdated.map{ |f| "#{f.name} #{f.version}" } * ", "
end
+ if not upgrade_pinned and pinned.length > 0
+ oh1 "Not upgrading #{pinned.length} pinned package#{outdated.length.plural_s}:"
+ puts pinned.map{ |f| "#{f.name} #{f.version}" } * ", "
+ end
outdated.each do |f|
upgrade_formula f
@@ -60,6 +71,13 @@ module Homebrew extend self
installer.install
installer.caveats
installer.finish
+
+ # If the formula was pinned, and we were force-upgrading it, unpin and
+ # pin it again to get a symlink pointing to the correct keg.
+ if f.pinned?
+ f.unpin
+ f.pin
+ end
rescue FormulaInstallationAlreadyAttemptedError
# We already attempted to upgrade f as part of the dependency tree of
# another formula. In that case, don't generate an error, just move on.