mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
link: add --force and --dry-run options
`brew link` can now be made to delete any conflicting files using the --force argument. It also has a --dry-run option, similar to git clean -n, which will list any files which would be deleted without touching the filesystem. Closes Homebrew/homebrew#11811. Signed-off-by: Misty De Meo <mistydemeo@gmail.com>
This commit is contained in:
parent
dd9ef7b71b
commit
743b5e6feb
@ -186,11 +186,18 @@ For the full command list, see the COMMANDS section.
|
|||||||
If `--git` is passed, Homebrew will create a Git repository, useful for
|
If `--git` is passed, Homebrew will create a Git repository, useful for
|
||||||
creating patches to the software.
|
creating patches to the software.
|
||||||
|
|
||||||
* `ln`, `link` <formula>:
|
* `ln`, `link [--force] [--dry-run]` <formula>:
|
||||||
Symlink all of <formula>'s installed files into the Homebrew prefix. This
|
Symlink all of <formula>'s installed files into the Homebrew prefix. This
|
||||||
is done automatically when you install formula, but can be useful for DIY
|
is done automatically when you install formula, but can be useful for DIY
|
||||||
installations.
|
installations.
|
||||||
|
|
||||||
|
If `--force` is passed, Homebrew will delete files which already exist in
|
||||||
|
the prefix while linking.
|
||||||
|
|
||||||
|
If `--dry-run` or `-n` is passed, Homebrew will list all files which would
|
||||||
|
be deleted by `brew link --force`, but will not actually link or delete
|
||||||
|
any files.
|
||||||
|
|
||||||
* `ls, list [--unbrewed] [--versions]` [<formulae>]:
|
* `ls, list [--unbrewed] [--versions]` [<formulae>]:
|
||||||
Without any arguments, list all installed formulae.
|
Without any arguments, list all installed formulae.
|
||||||
|
|
||||||
|
@ -9,14 +9,30 @@ module Homebrew extend self
|
|||||||
abort "Cowardly refusing to `sudo brew link'"
|
abort "Cowardly refusing to `sudo brew link'"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if ARGV.force?
|
||||||
|
mode = :force
|
||||||
|
elsif ARGV.include?("--dry-run") || ARGV.include?("-n")
|
||||||
|
mode = :dryrun
|
||||||
|
else
|
||||||
|
mode = nil
|
||||||
|
end
|
||||||
|
|
||||||
ARGV.kegs.each do |keg|
|
ARGV.kegs.each do |keg|
|
||||||
if keg.linked_keg_record.directory? and keg.linked_keg_record.realpath == keg
|
if keg.linked_keg_record.directory? and keg.linked_keg_record.realpath == keg
|
||||||
opoo "Already linked: #{keg}"
|
opoo "Already linked: #{keg}"
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if mode == :dryrun
|
||||||
|
print "Would remove:\n" do
|
||||||
|
keg.link(mode)
|
||||||
|
end
|
||||||
|
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
print "Linking #{keg}... " do
|
print "Linking #{keg}... " do
|
||||||
puts "#{keg.link} symlinks created"
|
puts "#{keg.link(mode)} symlinks created"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -347,6 +347,11 @@ class Pathname
|
|||||||
raise <<-EOS.undent
|
raise <<-EOS.undent
|
||||||
Could not symlink file: #{src.expand_path}
|
Could not symlink file: #{src.expand_path}
|
||||||
Target #{self} already exists. You may need to delete it.
|
Target #{self} already exists. You may need to delete it.
|
||||||
|
To force the link and delete this file, do:
|
||||||
|
brew link -f formula_name
|
||||||
|
|
||||||
|
To list all files that would be deleted:
|
||||||
|
brew link -n formula_name
|
||||||
EOS
|
EOS
|
||||||
elsif !dirname.writable?
|
elsif !dirname.writable?
|
||||||
raise <<-EOS.undent
|
raise <<-EOS.undent
|
||||||
|
@ -58,7 +58,7 @@ class Keg < Pathname
|
|||||||
linked_keg_record.directory? and self == linked_keg_record.realpath
|
linked_keg_record.directory? and self == linked_keg_record.realpath
|
||||||
end
|
end
|
||||||
|
|
||||||
def link
|
def link mode=nil
|
||||||
raise "Cannot link #{fname}\nAnother version is already linked: #{linked_keg_record.realpath}" if linked_keg_record.directory?
|
raise "Cannot link #{fname}\nAnother version is already linked: #{linked_keg_record.realpath}" if linked_keg_record.directory?
|
||||||
|
|
||||||
$n=0
|
$n=0
|
||||||
@ -70,12 +70,12 @@ class Keg < Pathname
|
|||||||
|
|
||||||
# yeah indeed, you have to force anything you need in the main tree into
|
# yeah indeed, you have to force anything you need in the main tree into
|
||||||
# these dirs REMEMBER that *NOT* everything needs to be in the main tree
|
# these dirs REMEMBER that *NOT* everything needs to be in the main tree
|
||||||
link_dir('etc') {:mkpath}
|
link_dir('etc', mode) {:mkpath}
|
||||||
link_dir('bin') {:skip_dir}
|
link_dir('bin', mode) {:skip_dir}
|
||||||
link_dir('sbin') {:skip_dir}
|
link_dir('sbin', mode) {:skip_dir}
|
||||||
link_dir('include') {:link}
|
link_dir('include', mode) {:link}
|
||||||
|
|
||||||
link_dir('share') do |path|
|
link_dir('share', mode) do |path|
|
||||||
case path.to_s
|
case path.to_s
|
||||||
when 'locale/locale.alias' then :skip_file
|
when 'locale/locale.alias' then :skip_file
|
||||||
when INFOFILE_RX then ENV['HOMEBREW_KEEP_INFO'] ? :info : :skip_file
|
when INFOFILE_RX then ENV['HOMEBREW_KEEP_INFO'] ? :info : :skip_file
|
||||||
@ -86,7 +86,7 @@ class Keg < Pathname
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
link_dir('lib') do |path|
|
link_dir('lib', mode) do |path|
|
||||||
case path.to_s
|
case path.to_s
|
||||||
when 'charset.alias' then :skip_file
|
when 'charset.alias' then :skip_file
|
||||||
# pkg-config database gets explicitly created
|
# pkg-config database gets explicitly created
|
||||||
@ -106,7 +106,7 @@ class Keg < Pathname
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
linked_keg_record.make_relative_symlink(self)
|
linked_keg_record.make_relative_symlink(self) unless mode == :dryrun
|
||||||
|
|
||||||
return $n + $d
|
return $n + $d
|
||||||
end
|
end
|
||||||
@ -127,16 +127,21 @@ protected
|
|||||||
puts "Won't resolve conflicts for symlink #{dst} as it doesn't resolve into the Cellar" if ARGV.verbose?
|
puts "Won't resolve conflicts for symlink #{dst} as it doesn't resolve into the Cellar" if ARGV.verbose?
|
||||||
end
|
end
|
||||||
|
|
||||||
def make_relative_symlink dst, src
|
def make_relative_symlink dst, src, mode=nil
|
||||||
if dst.exist? and dst.realpath == src.realpath
|
if dst.exist? and dst.realpath == src.realpath
|
||||||
puts "Skipping; already exists: #{dst}" if ARGV.verbose?
|
puts "Skipping; already exists: #{dst}" if ARGV.verbose?
|
||||||
|
# cf. git-clean -n: list files to delete, don't really link or delete
|
||||||
|
elsif mode == :dryrun
|
||||||
|
puts dst if dst.exist?
|
||||||
|
return
|
||||||
else
|
else
|
||||||
|
dst.delete if mode == :force && dst.exist?
|
||||||
dst.make_relative_symlink src
|
dst.make_relative_symlink src
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# symlinks the contents of self+foo recursively into /usr/local/foo
|
# symlinks the contents of self+foo recursively into /usr/local/foo
|
||||||
def link_dir foo
|
def link_dir foo, mode=nil
|
||||||
root = self+foo
|
root = self+foo
|
||||||
return unless root.exist?
|
return unless root.exist?
|
||||||
|
|
||||||
@ -154,10 +159,10 @@ protected
|
|||||||
Find.prune
|
Find.prune
|
||||||
when :info
|
when :info
|
||||||
next if File.basename(src) == 'dir' # skip historical local 'dir' files
|
next if File.basename(src) == 'dir' # skip historical local 'dir' files
|
||||||
make_relative_symlink dst, src
|
make_relative_symlink dst, src, mode
|
||||||
dst.install_info
|
dst.install_info
|
||||||
else
|
else
|
||||||
make_relative_symlink dst, src
|
make_relative_symlink dst, src, mode
|
||||||
end
|
end
|
||||||
elsif src.directory?
|
elsif src.directory?
|
||||||
# if the dst dir already exists, then great! walk the rest of the tree tho
|
# if the dst dir already exists, then great! walk the rest of the tree tho
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
.\" generated with Ronn/v0.7.3
|
.\" generated with Ronn/v0.7.3
|
||||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||||
.
|
.
|
||||||
.TH "BREW" "1" "March 2012" "Homebrew" "brew"
|
.TH "BREW" "1" "June 2012" "Homebrew" "brew"
|
||||||
.
|
.
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
\fBbrew\fR \- The missing package manager for OS X
|
\fBbrew\fR \- The missing package manager for OS X
|
||||||
@ -208,9 +208,15 @@ Download and patch \fIformula\fR, then open a shell\. This allows the user to ru
|
|||||||
If \fB\-\-git\fR is passed, Homebrew will create a Git repository, useful for creating patches to the software\.
|
If \fB\-\-git\fR is passed, Homebrew will create a Git repository, useful for creating patches to the software\.
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBln\fR, \fBlink\fR \fIformula\fR
|
\fBln\fR, \fBlink [\-\-force] [\-\-dry\-run]\fR \fIformula\fR
|
||||||
Symlink all of \fIformula\fR\'s installed files into the Homebrew prefix\. This is done automatically when you install formula, but can be useful for DIY installations\.
|
Symlink all of \fIformula\fR\'s installed files into the Homebrew prefix\. This is done automatically when you install formula, but can be useful for DIY installations\.
|
||||||
.
|
.
|
||||||
|
.IP
|
||||||
|
If \fB\-\-force\fR is passed, Homebrew will delete files which already exist in the prefix while linking\.
|
||||||
|
.
|
||||||
|
.IP
|
||||||
|
If \fB\-\-dry\-run\fR or \fB\-n\fR is passed, Homebrew will list all files which would be deleted by \fBbrew link \-\-force\fR, but will not actually link or delete any files\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBls, list [\-\-unbrewed] [\-\-versions]\fR [\fIformulae\fR]
|
\fBls, list [\-\-unbrewed] [\-\-versions]\fR [\fIformulae\fR]
|
||||||
Without any arguments, list all installed formulae\.
|
Without any arguments, list all installed formulae\.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user