From 87348488297fbcd053aff053fcb234984e12bd11 Mon Sep 17 00:00:00 2001 From: Eli Young Date: Thu, 12 Apr 2018 16:14:02 -0700 Subject: [PATCH] Support enabling auto-updates for non-GitHub taps --- Library/Homebrew/cmd/tap.rb | 12 ++++++++++- Library/Homebrew/cmd/update.sh | 8 ++++++-- Library/Homebrew/tap.rb | 15 ++++++++++++-- Library/Homebrew/test/dev-cmd/tap_spec.rb | 15 ++++++++++++++ Library/Homebrew/test/tap_spec.rb | 25 +++++++++++++++++++++++ docs/Manpage.md | 6 +++++- manpages/brew.1 | 5 ++++- 7 files changed, 79 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/cmd/tap.rb b/Library/Homebrew/cmd/tap.rb index 21d05d768e..94362f7fe4 100644 --- a/Library/Homebrew/cmd/tap.rb +++ b/Library/Homebrew/cmd/tap.rb @@ -1,7 +1,7 @@ #: * `tap`: #: List all installed taps. #: -#: * `tap` [`--full`] `/` []: +#: * `tap` [`--full`] [`--force-auto-update`] `/` []: #: Tap a formula repository. #: #: With unspecified, taps a formula repository from GitHub using HTTPS. @@ -18,6 +18,10 @@ #: 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. #: +#: By default, only taps hosted on GitHub are auto-updated (for performance +#: reasons). If `--force-auto-update` is passed, this tap will be auto-updated +#: even if it is not hosted on GitHub. +#: #: `tap` is re-runnable and exits successfully if there's nothing to do. #: However, retapping with a different will cause an exception, so first #: `untap` if you need to modify the . @@ -44,6 +48,7 @@ module Homebrew tap = Tap.fetch(ARGV.named[0]) begin tap.install clone_target: ARGV.named[1], + force_auto_update: force_auto_update?, full_clone: full_clone?, quiet: ARGV.quieter? rescue TapRemoteMismatchError => e @@ -56,4 +61,9 @@ module Homebrew def full_clone? ARGV.include?("--full") || ARGV.homebrew_developer? end + + def force_auto_update? + # if no relevant flag is present, return nil, meaning "no change" + true if ARGV.include?("--force-auto-update") + end end diff --git a/Library/Homebrew/cmd/update.sh b/Library/Homebrew/cmd/update.sh index f0fbdffafa..d3dae2be31 100644 --- a/Library/Homebrew/cmd/update.sh +++ b/Library/Homebrew/cmd/update.sh @@ -493,8 +493,12 @@ EOS [[ -z "$HOMEBREW_UPDATE_FORCE" ]] && [[ "$UPSTREAM_SHA_HTTP_CODE" = "304" ]] && exit elif [[ -n "$HOMEBREW_UPDATE_PREINSTALL" ]] then - # Don't try to do a `git fetch` that may take longer than expected. - exit + FORCE_AUTO_UPDATE="$(git config homebrew.forceautoupdate 2>/dev/null || echo "false")" + if [[ "$FORCE_AUTO_UPDATE" != "true" ]] + then + # Don't try to do a `git fetch` that may take longer than expected. + exit + fi fi if [[ -n "$HOMEBREW_VERBOSE" ]] diff --git a/Library/Homebrew/tap.rb b/Library/Homebrew/tap.rb index 48288e0081..bcd205bab8 100644 --- a/Library/Homebrew/tap.rb +++ b/Library/Homebrew/tap.rb @@ -201,7 +201,9 @@ class Tap # install this {Tap}. # # @param [Hash] options - # @option options [String] :clone_targe If passed, it will be used as the clone remote. + # @option options [String] :clone_target If passed, it will be used as the clone remote. + # @option options [Boolean, nil] :force_auto_update If present, whether to override the + # logic that skips non-GitHub repositories during auto-updates. # @option options [Boolean] :full_clone If set as true, full clone will be used. # @option options [Boolean] :quiet If set, suppress all output. def install(options = {}) @@ -210,12 +212,14 @@ class Tap full_clone = options.fetch(:full_clone, false) quiet = options.fetch(:quiet, false) requested_remote = options[:clone_target] || default_remote + # if :force_auto_update is unset, use nil, meaning "no change" + force_auto_update = options.fetch(:force_auto_update, nil) if official? && DEPRECATED_OFFICIAL_TAPS.include?(repo) odie "#{name} was deprecated. This tap is now empty as all its formulae were migrated." end - if installed? + if installed? && force_auto_update.nil? raise TapAlreadyTappedError, name unless full_clone raise TapAlreadyUnshallowError, name unless shallow? end @@ -224,6 +228,11 @@ class Tap Utils.ensure_git_installed! if installed? + unless force_auto_update.nil? + config["forceautoupdate"] = force_auto_update + return if !full_clone || !shallow? + end + if options[:clone_target] && requested_remote != remote raise TapRemoteMismatchError.new(name, @remote, requested_remote) end @@ -259,6 +268,8 @@ class Tap raise end + config["forceautoupdate"] = force_auto_update unless force_auto_update.nil? + link_completions_and_manpages formula_count = formula_files.size diff --git a/Library/Homebrew/test/dev-cmd/tap_spec.rb b/Library/Homebrew/test/dev-cmd/tap_spec.rb index d294da67aa..de9c3d891e 100644 --- a/Library/Homebrew/test/dev-cmd/tap_spec.rb +++ b/Library/Homebrew/test/dev-cmd/tap_spec.rb @@ -55,11 +55,26 @@ describe "brew tap", :integration_test do .and not_to_output.to_stderr .and be_a_success + expect { brew "tap", "--force-auto-update", "homebrew/bar", path/".git" } + .to output(/Tapped/).to_stdout + .and output(/Cloning/).to_stderr + .and be_a_success + + expect { brew "untap", "homebrew/bar" } + .to output(/Untapped/).to_stdout + .and not_to_output.to_stderr + .and be_a_success + expect { brew "tap", "homebrew/bar", path/".git", "-q", "--full" } .to be_a_success .and not_to_output.to_stdout .and not_to_output.to_stderr + expect { brew "tap", "--force-auto-update", "homebrew/bar" } + .to be_a_success + .and not_to_output.to_stdout + .and not_to_output.to_stderr + expect { brew "untap", "homebrew/bar" } .to output(/Untapped/).to_stdout .and not_to_output.to_stderr diff --git a/Library/Homebrew/test/tap_spec.rb b/Library/Homebrew/test/tap_spec.rb index 5e82370aac..fafc8a49af 100644 --- a/Library/Homebrew/test/tap_spec.rb +++ b/Library/Homebrew/test/tap_spec.rb @@ -209,6 +209,31 @@ describe Tap do expect { already_tapped_tap.install full_clone: true }.to raise_error(TapAlreadyUnshallowError) end + describe "force_auto_update" do + before do + setup_git_repo + end + + let(:already_tapped_tap) { described_class.new("Homebrew", "foo") } + + it "defaults to nil" do + expect(already_tapped_tap).to be_installed + expect(already_tapped_tap.config["forceautoupdate"]).to be_nil + end + + it "enables forced auto-updates when true" do + expect(already_tapped_tap).to be_installed + already_tapped_tap.install force_auto_update: true + expect(already_tapped_tap.config["forceautoupdate"]).to eq("true") + end + + it "disables forced auto-updates when false" do + expect(already_tapped_tap).to be_installed + already_tapped_tap.install force_auto_update: false + expect(already_tapped_tap.config["forceautoupdate"]).to eq("false") + end + end + specify "Git error" do tap = described_class.new("user", "repo") diff --git a/docs/Manpage.md b/docs/Manpage.md index 86ddff96fb..f69d2066ac 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -448,7 +448,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note * `tap`: List all installed taps. - * `tap` [`--full`] `user``/``repo` [`URL`]: + * `tap` [`--full`] [`--force-auto-update`] `user``/``repo` [`URL`]: Tap a formula repository. With `URL` unspecified, taps a formula repository from GitHub using HTTPS. @@ -465,6 +465,10 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note 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. + By default, only taps hosted on GitHub are auto-updated (for performance + reasons). If `--force-auto-update` is passed, this tap will be auto-updated + even if it is not hosted on GitHub. + `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`. diff --git a/manpages/brew.1 b/manpages/brew.1 index ba1f73cba6..b138ed8277 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -463,7 +463,7 @@ Symlink all of the specific \fIversion\fR of \fIformula\fR\'s install to Homebre List all installed taps\. . .TP -\fBtap\fR [\fB\-\-full\fR] \fIuser\fR\fB/\fR\fIrepo\fR [\fIURL\fR] +\fBtap\fR [\fB\-\-full\fR] [\fB\-\-force\-auto\-update\fR] \fIuser\fR\fB/\fR\fIrepo\fR [\fIURL\fR] Tap a formula repository\. . .IP @@ -476,6 +476,9 @@ With \fIURL\fR specified, taps a formula repository from anywhere, using any tra 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 +By default, only taps hosted on GitHub are auto\-updated (for performance reasons)\. If \fB\-\-force\-auto\-update\fR is passed, this tap will be auto\-updated even if it is not hosted on GitHub\. +. +.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