From f96b8e713875fee683299cda6000834fae594255 Mon Sep 17 00:00:00 2001 From: nandahkrishna Date: Wed, 2 Dec 2020 18:04:22 +0530 Subject: [PATCH] livecheck: add GithubLatest strategy --- Library/Homebrew/livecheck/strategy.rb | 1 + .../livecheck/strategy/github_latest.rb | 59 +++++++++++++++++++ .../livecheck/strategy/github_latest_spec.rb | 26 ++++++++ 3 files changed, 86 insertions(+) create mode 100644 Library/Homebrew/livecheck/strategy/github_latest.rb create mode 100644 Library/Homebrew/test/livecheck/strategy/github_latest_spec.rb diff --git a/Library/Homebrew/livecheck/strategy.rb b/Library/Homebrew/livecheck/strategy.rb index 766512e08f..8a7b403dd4 100644 --- a/Library/Homebrew/livecheck/strategy.rb +++ b/Library/Homebrew/livecheck/strategy.rb @@ -78,6 +78,7 @@ end require_relative "strategy/apache" require_relative "strategy/bitbucket" require_relative "strategy/git" +require_relative "strategy/github_latest" require_relative "strategy/gnome" require_relative "strategy/gnu" require_relative "strategy/hackage" diff --git a/Library/Homebrew/livecheck/strategy/github_latest.rb b/Library/Homebrew/livecheck/strategy/github_latest.rb new file mode 100644 index 0000000000..38c3aea144 --- /dev/null +++ b/Library/Homebrew/livecheck/strategy/github_latest.rb @@ -0,0 +1,59 @@ +# typed: false +# frozen_string_literal: true + +module Homebrew + module Livecheck + module Strategy + # The {GithubLatest} strategy identifies versions of software at + # github.com by checking a repository's latest release page. + # + # GitHub URLs take a few differemt formats: + # + # * `https://github.com/example/example/releases/download/1.2.3/example-1.2.3.zip` + # * `https://github.com/example/example/archive/v1.2.3.tar.gz` + # + # This strategy is used when latest releases are marked for software hosted + # on GitHub. It is necessary to use `strategy :github_latest` in a `livecheck` + # block for Livecheck to use this strategy. + # + # The default regex identifies versions from `href` attributes containing the + # tag name. + # + # @api public + class GithubLatest + NICE_NAME = "GitHub Latest" + + # The `Regexp` used to determine if the strategy applies to the URL. + URL_MATCH_REGEX = /github.com/i.freeze + + # Whether the strategy can be applied to the provided URL. + # + # @param url [String] the URL to match against + # @return [Boolean] + def self.match?(url) + URL_MATCH_REGEX.match?(url) + end + + # Generates a URL and regex (if one isn't provided) and passes them + # to {PageMatch.find_versions} to identify versions in the content. + # + # @param url [String] the URL of the content to check + # @param regex [Regexp] a regex used for matching versions in content + # @return [Hash] + def self.find_versions(url, regex = nil) + %r{github\.com/(?[\da-z\-]+)/(?[\da-z_\-]+)}i =~ url + + # The page containing the latest release + page_url = "https://github.com/#{username}/#{repository}/releases/latest" + + # The default regex applies to most repositories, but may have to be + # replaced with a specific regex when the tag names contain the package + # name or other characters apart from the version. + regex ||= %r{href=.*?/tag/v?(\d+(?:\.\d+)+)["' >]}i + + Homebrew::Livecheck::Strategy::PageMatch.find_versions(page_url, regex) + end + end + end + end +end diff --git a/Library/Homebrew/test/livecheck/strategy/github_latest_spec.rb b/Library/Homebrew/test/livecheck/strategy/github_latest_spec.rb new file mode 100644 index 0000000000..2d1d4cc401 --- /dev/null +++ b/Library/Homebrew/test/livecheck/strategy/github_latest_spec.rb @@ -0,0 +1,26 @@ +# typed: false +# frozen_string_literal: true + +require "livecheck/strategy/github_latest" + +describe Homebrew::Livecheck::Strategy::GithubLatest do + subject(:github_latest) { described_class } + + let(:github_download_url) { "https://github.com/example/example/releases/download/1.2.3/example-1.2.3.zip" } + let(:github_archive_url) { "https://github.com/example/example/archive/v1.2.3.tar.gz" } + let(:non_github_url) { "https://brew.sh/test" } + + describe "::match?" do + it "returns true if the argument provided is a GitHub Download URL" do + expect(github_latest.match?(github_download_url)).to be true + end + + it "returns true if the argument provided is a GitHub Archive URL" do + expect(github_latest.match?(github_archive_url)).to be true + end + + it "returns false if the argument provided is not a GitHub URL" do + expect(github_latest.match?(non_github_url)).to be false + end + end +end