-
-
Notifications
You must be signed in to change notification settings - Fork 10k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This adds a `Livecheck::Options` class, which is intended to house various configuration options that are set in `livecheck` blocks, conditionally set by livecheck at runtime, etc. The general idea is that when we add features involving configurations options (e.g., for livecheck, strategies, curl, etc.), we can make changes to `Options` without needing to modify parameters for strategy `find_versions` methods, `Strategy` methods like `page_headers` and `page_content`, etc. This is something that I've been trying to improve over the years and `Options` should help to reduce maintenance overhead in this area while also strengthening type signatures. `Options` replaces the existing `homebrew_curl` option (which related strategies pass to `Strategy` methods and on to `curl_args`) and the new `url_options` (which contains `post_form` or `post_json` values that are used to make `POST` requests). I recently added `url_options` as a temporary way of enabling `POST` support without `Options` but this restores the original `Options`-based implementation. Along the way, I added a `homebrew_curl` parameter to the `url` DSL method, allowing us to set an explicit value in `livecheck` blocks. This is something that we've needed in some cases but I also intend to replace implicit/inferred `homebrew_curl` usage with explicit values in `livecheck` blocks once this is available for use. My intention is to eventually remove the implicit behavior and only rely on explicit values. That will align with how `homebrew_curl` options work for other URLs and makes the behavior clear just from looking at the formula/cask file. Lastly, this removes the `unused` rest parameter from `find_versions` methods. I originally added `unused` as a way of handling parameters that some `find_versions` methods have but others don't (e.g., `cask` in `ExtractPlist`), as this allowed us to pass various arguments to `find_versions` methods without worrying about whether a particular parameter is available. This isn't an ideal solution and I originally wanted to handle this situation by only passing expected arguments to `find_versions` methods but there was a technical issue standing in the way. I recently found an answer to the issue, so this also replaces the existing `ExtractPlist` special case with generic logic that checks the parameters for a strategy's `find_versions` method and only passes expected arguments. Replacing aforementioned `find_versions` parameters with `Options` ensures that the remaining parameters are consistent across strategies and any differences are handled by the aforementioned logic. Outside of `ExtractPlist`, the only other difference is that some `find_versions` methods have a `provided_content` parameter but that's currently only used by tests (though it's intended for caching support in the future). I will be renaming that parameter to `content` in an upcoming PR and expanding it to the other strategies, which should make them all consistent outside of `ExtractPlist`.
- Loading branch information
Showing
30 changed files
with
513 additions
and
251 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
# typed: strict | ||
# frozen_string_literal: true | ||
|
||
module Homebrew | ||
module Livecheck | ||
# Options to modify livecheck's behavior. These primarily come from | ||
# `livecheck` blocks but they can also be set by livecheck at runtime. | ||
class Options | ||
# Whether to use brewed curl. | ||
sig { returns(T.nilable(T::Boolean)) } | ||
attr_reader :homebrew_curl | ||
|
||
# Form data to use when making a `POST` request. | ||
sig { returns(T.nilable(T::Hash[T.any(String, Symbol), String])) } | ||
attr_reader :post_form | ||
|
||
# JSON data to use when making a `POST` request. | ||
sig { returns(T.nilable(T::Hash[T.any(String, Symbol), String])) } | ||
attr_reader :post_json | ||
|
||
# @param homebrew_curl whether to use brewed curl | ||
# @param post_form form data to use when making a `POST` request | ||
# @param post_json JSON data to use when making a `POST` request | ||
sig { | ||
params( | ||
homebrew_curl: T.nilable(T::Boolean), | ||
post_form: T.nilable(T::Hash[T.any(String, Symbol), String]), | ||
post_json: T.nilable(T::Hash[T.any(String, Symbol), String]), | ||
).void | ||
} | ||
def initialize(homebrew_curl: nil, post_form: nil, post_json: nil) | ||
@homebrew_curl = homebrew_curl | ||
@post_form = post_form | ||
@post_json = post_json | ||
end | ||
|
||
# Returns a `Hash` of options that are provided as arguments to `url`. | ||
sig { returns(T::Hash[Symbol, T.untyped]) } | ||
def url_options | ||
{ | ||
homebrew_curl:, | ||
post_form:, | ||
post_json:, | ||
} | ||
end | ||
|
||
# Returns a `Hash` of all instance variable values. | ||
sig { returns(T::Hash[Symbol, T.untyped]) } | ||
def to_h | ||
{ | ||
homebrew_curl:, | ||
post_form:, | ||
post_json:, | ||
} | ||
end | ||
|
||
# Returns a `Hash` of all instance variables, using `String` keys. | ||
sig { returns(T::Hash[String, T.untyped]) } | ||
def to_hash | ||
{ | ||
"homebrew_curl" => @homebrew_curl, | ||
"post_form" => @post_form, | ||
"post_json" => @post_json, | ||
} | ||
end | ||
|
||
# Returns a new object formed by merging `other` values with a copy of | ||
# `self`. | ||
# | ||
# `nil` values are removed from `other` before merging if it is an | ||
# `Options` object, as these are unitiailized values. This ensures that | ||
# existing values in `self` aren't unexpectedly overwritten with defaults. | ||
sig { params(other: T.any(Options, T::Hash[Symbol, T.untyped])).returns(Options) } | ||
def merge(other) | ||
return dup if other.blank? | ||
|
||
this_hash = to_h | ||
other_hash = other.is_a?(Options) ? other.to_h.compact : other | ||
return dup if this_hash == other_hash | ||
|
||
new_options = this_hash.merge(other_hash) | ||
Options.new(**new_options) | ||
end | ||
|
||
sig { params(other: Options).returns(T::Boolean) } | ||
def ==(other) | ||
instance_of?(other.class) && | ||
@homebrew_curl == other.homebrew_curl && | ||
@post_form == other.post_form && | ||
@post_json == other.post_json | ||
end | ||
alias eql? == | ||
|
||
# Whether the object has only default values. | ||
sig { returns(T::Boolean) } | ||
def empty? | ||
@homebrew_curl.nil? && @post_form.nil? && @post_json.nil? | ||
end | ||
|
||
# Whether the object has any non-default values. | ||
sig { returns(T::Boolean) } | ||
def present? | ||
!@homebrew_curl.nil? || !@post_form.nil? || !@post_json.nil? | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.