mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
tap: support --full even if installed
Makes `tap` re-runnable and unshallows when requested with `--full`. Tapping with a different URL raises an exception. The homebrew/core tap cannot be untapped with `untap` so running `brew tap --full homebrew/core` is now a built-in way to get a full clone of this tap without resorting to workarounds. Closes #17. Signed-off-by: ilovezfs <ilovezfs@icloud.com>
This commit is contained in:
parent
1b7e13df4f
commit
fad235d8e8
@ -17,8 +17,10 @@ module Homebrew
|
|||||||
tap.install :clone_target => ARGV.named[1],
|
tap.install :clone_target => ARGV.named[1],
|
||||||
:full_clone => ARGV.include?("--full"),
|
:full_clone => ARGV.include?("--full"),
|
||||||
:quiet => ARGV.quieter?
|
:quiet => ARGV.quieter?
|
||||||
rescue TapAlreadyTappedError => e
|
rescue TapRemoteMismatchError => e
|
||||||
opoo e
|
odie e
|
||||||
|
rescue TapAlreadyTappedError, TapAlreadyUnshallowError
|
||||||
|
# Do nothing.
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -119,6 +119,23 @@ class TapUnavailableError < RuntimeError
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class TapRemoteMismatchError < RuntimeError
|
||||||
|
attr_reader :name
|
||||||
|
attr_reader :expected_remote
|
||||||
|
attr_reader :actual_remote
|
||||||
|
|
||||||
|
def initialize(name, expected_remote, actual_remote)
|
||||||
|
@name = name
|
||||||
|
@expected_remote = expected_remote
|
||||||
|
@actual_remote = actual_remote
|
||||||
|
|
||||||
|
super <<-EOS.undent
|
||||||
|
Tap #{name} remote mismatch.
|
||||||
|
#{expected_remote} != #{actual_remote}
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class TapAlreadyTappedError < RuntimeError
|
class TapAlreadyTappedError < RuntimeError
|
||||||
attr_reader :name
|
attr_reader :name
|
||||||
|
|
||||||
@ -131,6 +148,18 @@ class TapAlreadyTappedError < RuntimeError
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class TapAlreadyUnshallowError < RuntimeError
|
||||||
|
attr_reader :name
|
||||||
|
|
||||||
|
def initialize(name)
|
||||||
|
@name = name
|
||||||
|
|
||||||
|
super <<-EOS.undent
|
||||||
|
Tap #{name} already a full clone.
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class TapPinStatusError < RuntimeError
|
class TapPinStatusError < RuntimeError
|
||||||
attr_reader :name, :pinned
|
attr_reader :name, :pinned
|
||||||
|
|
||||||
|
@ -394,7 +394,12 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note
|
|||||||
using protocols other than HTTPS, e.g., SSH, GIT, HTTP, FTP(S), RSYNC.
|
using protocols other than HTTPS, e.g., SSH, GIT, HTTP, FTP(S), RSYNC.
|
||||||
|
|
||||||
By default, the repository is cloned as a shallow copy (`--depth=1`), but
|
By default, the repository is cloned as a shallow copy (`--depth=1`), but
|
||||||
if `--full` is passed, a full clone will be used.
|
if `--full` is passed, a full clone will be used. To convert a shallow copy
|
||||||
|
to a full copy, you can retap passing `--full` without first untapping.
|
||||||
|
|
||||||
|
`tap` is re-runnable and exits successfully if there's nothing to do.
|
||||||
|
However, retapping with a different <URL> will cause an exception, so first
|
||||||
|
`untap` if you need to modify the <URL>.
|
||||||
|
|
||||||
* `tap` `--repair`:
|
* `tap` `--repair`:
|
||||||
Migrate tapped formulae from symlink-based to directory-based structure.
|
Migrate tapped formulae from symlink-based to directory-based structure.
|
||||||
|
@ -158,6 +158,11 @@ class Tap
|
|||||||
path.directory?
|
path.directory?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# True if this {Tap} is not a full clone.
|
||||||
|
def shallow?
|
||||||
|
(path/".git/shallow").exist?
|
||||||
|
end
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
def core_tap?
|
def core_tap?
|
||||||
false
|
false
|
||||||
@ -171,17 +176,33 @@ class Tap
|
|||||||
# @option options [Boolean] :quiet If set, suppress all output.
|
# @option options [Boolean] :quiet If set, suppress all output.
|
||||||
def install(options = {})
|
def install(options = {})
|
||||||
require "descriptions"
|
require "descriptions"
|
||||||
raise TapAlreadyTappedError, name if installed?
|
|
||||||
clear_cache
|
|
||||||
|
|
||||||
|
full_clone = options.fetch(:full_clone, false)
|
||||||
quiet = options.fetch(:quiet, false)
|
quiet = options.fetch(:quiet, false)
|
||||||
|
requested_remote = options[:clone_target] || "https://github.com/#{user}/homebrew-#{repo}"
|
||||||
|
|
||||||
|
if installed?
|
||||||
|
raise TapRemoteMismatchError.new(name, @remote, requested_remote) unless remote == requested_remote
|
||||||
|
raise TapAlreadyTappedError, name unless full_clone
|
||||||
|
raise TapAlreadyUnshallowError, name unless shallow?
|
||||||
|
end
|
||||||
|
|
||||||
# ensure git is installed
|
# ensure git is installed
|
||||||
Utils.ensure_git_installed!
|
Utils.ensure_git_installed!
|
||||||
|
|
||||||
|
if installed?
|
||||||
|
ohai "Unshallowing #{name}" unless quiet
|
||||||
|
args = %W[fetch --unshallow]
|
||||||
|
args << "-q" if quiet
|
||||||
|
path.cd { safe_system "git", *args }
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
clear_cache
|
||||||
|
|
||||||
ohai "Tapping #{name}" unless quiet
|
ohai "Tapping #{name}" unless quiet
|
||||||
remote = options[:clone_target] || "https://github.com/#{user}/homebrew-#{repo}"
|
args = %W[clone #{requested_remote} #{path} --config core.autocrlf=false]
|
||||||
args = %W[clone #{remote} #{path} --config core.autocrlf=false]
|
args << "--depth=1" unless full_clone
|
||||||
args << "--depth=1" unless options.fetch(:full_clone, false)
|
|
||||||
args << "-q" if quiet
|
args << "-q" if quiet
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
@ -164,7 +164,32 @@ class TapTest < Homebrew::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_install_tap_already_tapped_error
|
def test_install_tap_already_tapped_error
|
||||||
assert_raises(TapAlreadyTappedError) { @tap.install }
|
setup_git_repo
|
||||||
|
already_tapped_tap = Tap.new("Homebrew", "foo")
|
||||||
|
assert_equal true, already_tapped_tap.installed?
|
||||||
|
assert_raises(TapAlreadyTappedError) { already_tapped_tap.install }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_install_tap_remote_match_already_tapped_error
|
||||||
|
setup_git_repo
|
||||||
|
already_tapped_tap = Tap.new("Homebrew", "foo")
|
||||||
|
assert_equal true, already_tapped_tap.installed?
|
||||||
|
right_remote = "#{@tap.remote}"
|
||||||
|
assert_raises(TapAlreadyTappedError) { already_tapped_tap.install :clone_target => right_remote }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_install_tap_remote_mismatch_error
|
||||||
|
setup_git_repo
|
||||||
|
already_tapped_tap = Tap.new("Homebrew", "foo")
|
||||||
|
assert_equal true, already_tapped_tap.installed?
|
||||||
|
wrong_remote = "#{@tap.remote}-oops"
|
||||||
|
assert_raises(TapRemoteMismatchError) { already_tapped_tap.install :clone_target => wrong_remote }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_install_tap_already_unshallow_error
|
||||||
|
setup_git_repo
|
||||||
|
already_tapped_tap = Tap.new("Homebrew", "foo")
|
||||||
|
assert_raises(TapAlreadyUnshallowError) { already_tapped_tap.install :full_clone => true }
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_uninstall_tap_unavailable_error
|
def test_uninstall_tap_unavailable_error
|
||||||
|
@ -303,7 +303,12 @@ assumptions, so taps can be cloned from places other than GitHub and
|
|||||||
using protocols other than HTTPS, e.g., SSH, GIT, HTTP, FTP(S), RSYNC.</p>
|
using protocols other than HTTPS, e.g., SSH, GIT, HTTP, FTP(S), RSYNC.</p>
|
||||||
|
|
||||||
<p>By default, the repository is cloned as a shallow copy (<code>--depth=1</code>), but
|
<p>By default, the repository is cloned as a shallow copy (<code>--depth=1</code>), but
|
||||||
if <code>--full</code> is passed, a full clone will be used.</p></dd>
|
if <code>--full</code> is passed, a full clone will be used. To convert a shallow copy
|
||||||
|
to a full copy, you can retap passing <code>--full</code> without first untapping.</p>
|
||||||
|
|
||||||
|
<p><code>tap</code> is re-runnable and exits successfully if there's nothing to do.
|
||||||
|
However, retapping with a different <var>URL</var> will cause an exception, so first
|
||||||
|
<code>untap</code> if you need to modify the <var>URL</var>.</p></dd>
|
||||||
<dt><code>tap</code> <code>--repair</code></dt><dd><p>Migrate tapped formulae from symlink-based to directory-based structure.</p></dd>
|
<dt><code>tap</code> <code>--repair</code></dt><dd><p>Migrate tapped formulae from symlink-based to directory-based structure.</p></dd>
|
||||||
<dt><code>tap</code> <code>--list-official</code></dt><dd><p>List all official taps.</p></dd>
|
<dt><code>tap</code> <code>--list-official</code></dt><dd><p>List all official taps.</p></dd>
|
||||||
<dt><code>tap</code> <code>--list-pinned</code></dt><dd><p>List all pinned taps.</p></dd>
|
<dt><code>tap</code> <code>--list-pinned</code></dt><dd><p>List all pinned taps.</p></dd>
|
||||||
|
@ -416,7 +416,10 @@ With \fIURL\fR unspecified, taps a formula repository from GitHub using HTTPS\.
|
|||||||
With \fIURL\fR specified, taps a formula repository from anywhere, using any transport protocol that \fBgit\fR handles\. The one\-argument form of \fBtap\fR simplifies but also limits\. This two\-argument command makes no assumptions, so taps can be cloned from places other than GitHub and using protocols other than HTTPS, e\.g\., SSH, GIT, HTTP, FTP(S), RSYNC\.
|
With \fIURL\fR specified, taps a formula repository from anywhere, using any transport protocol that \fBgit\fR handles\. The one\-argument form of \fBtap\fR simplifies but also limits\. This two\-argument command makes no assumptions, so taps can be cloned from places other than GitHub and using protocols other than HTTPS, e\.g\., SSH, GIT, HTTP, FTP(S), RSYNC\.
|
||||||
.
|
.
|
||||||
.IP
|
.IP
|
||||||
By default, the repository is cloned as a shallow copy (\fB\-\-depth=1\fR), but if \fB\-\-full\fR is passed, a full clone will be used\.
|
By default, the repository is cloned as a shallow copy (\fB\-\-depth=1\fR), but if \fB\-\-full\fR is passed, a full clone will be used\. To convert a shallow copy to a full copy, you can retap passing \fB\-\-full\fR without first untapping\.
|
||||||
|
.
|
||||||
|
.IP
|
||||||
|
\fBtap\fR is re\-runnable and exits successfully if there\'s nothing to do\. However, retapping with a different \fIURL\fR will cause an exception, so first \fBuntap\fR if you need to modify the \fIURL\fR\.
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBtap\fR \fB\-\-repair\fR
|
\fBtap\fR \fB\-\-repair\fR
|
||||||
|
Loading…
x
Reference in New Issue
Block a user