From 0475c73b67cba9e88857d8e181e995398a6c1d42 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2020 05:33:46 +0000 Subject: [PATCH 01/19] build(deps): bump diff-lcs from 1.4.2 to 1.4.3 in /Library/Homebrew Bumps [diff-lcs](https://github.com/halostatue/diff-lcs) from 1.4.2 to 1.4.3. - [Release notes](https://github.com/halostatue/diff-lcs/releases) - [Changelog](https://github.com/halostatue/diff-lcs/blob/master/History.md) - [Commits](https://github.com/halostatue/diff-lcs/compare/v1.4.2...v1.4.3) Signed-off-by: dependabot-preview[bot] --- Library/Homebrew/Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Homebrew/Gemfile.lock b/Library/Homebrew/Gemfile.lock index 1ccf74b888..2034c676a8 100644 --- a/Library/Homebrew/Gemfile.lock +++ b/Library/Homebrew/Gemfile.lock @@ -17,7 +17,7 @@ GEM term-ansicolor (~> 1.3) thor (>= 0.19.4, < 2.0) tins (~> 1.6) - diff-lcs (1.4.2) + diff-lcs (1.4.3) docile (1.3.2) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) From 0ee9cc0b084a900b887efe08ba9a064e0a4adce9 Mon Sep 17 00:00:00 2001 From: vidusheeamoli Date: Tue, 30 Jun 2020 12:40:03 +0530 Subject: [PATCH 02/19] sorbet/files.yaml: add new files --- Library/Homebrew/sorbet/files.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Library/Homebrew/sorbet/files.yaml b/Library/Homebrew/sorbet/files.yaml index 443141c0eb..66a79e6c3b 100644 --- a/Library/Homebrew/sorbet/files.yaml +++ b/Library/Homebrew/sorbet/files.yaml @@ -652,6 +652,7 @@ false: - ./test/rubocops/components_redundancy_spec.rb - ./test/rubocops/conflicts_spec.rb - ./test/rubocops/dependency_order_spec.rb + - ./test/rubocops/deprecate_spec.rb - ./test/rubocops/formula_desc_spec.rb - ./test/rubocops/homepage_spec.rb - ./test/rubocops/lines_spec.rb @@ -884,6 +885,7 @@ true: - ./rubocops/cask/ast/stanza.rb - ./rubocops/cask/constants/stanza.rb - ./rubocops/cask/extend/string.rb + - ./rubocops/deprecate.rb - ./tap_constants.rb - ./test/support/helper/fixtures.rb - ./test/support/lib/config.rb From 6134af3108fc8713aef587c138481eb038ff8eaf Mon Sep 17 00:00:00 2001 From: vidusheeamoli Date: Tue, 30 Jun 2020 13:04:13 +0530 Subject: [PATCH 03/19] srb/tapioca: update rbi of recently bumped gems --- ...op-ast@0.0.3.rbi => rubocop-ast@0.1.0.rbi} | 110 ++++++++++++++++-- ...{zeitwerk@2.3.0.rbi => zeitwerk@2.3.1.rbi} | 2 +- 2 files changed, 101 insertions(+), 11 deletions(-) rename Library/Homebrew/sorbet/rbi/gems/{rubocop-ast@0.0.3.rbi => rubocop-ast@0.1.0.rbi} (90%) rename Library/Homebrew/sorbet/rbi/gems/{zeitwerk@2.3.0.rbi => zeitwerk@2.3.1.rbi} (73%) diff --git a/Library/Homebrew/sorbet/rbi/gems/rubocop-ast@0.0.3.rbi b/Library/Homebrew/sorbet/rbi/gems/rubocop-ast@0.1.0.rbi similarity index 90% rename from Library/Homebrew/sorbet/rbi/gems/rubocop-ast@0.0.3.rbi rename to Library/Homebrew/sorbet/rbi/gems/rubocop-ast@0.1.0.rbi index b5fdd557fe..e43fc405c9 100644 --- a/Library/Homebrew/sorbet/rbi/gems/rubocop-ast@0.0.3.rbi +++ b/Library/Homebrew/sorbet/rbi/gems/rubocop-ast@0.1.0.rbi @@ -1,5 +1,5 @@ # This file is autogenerated. Do not edit it by hand. Regenerate it with: -# tapioca sync +# tapioca sync --exclude json # typed: true @@ -344,6 +344,28 @@ class RuboCop::AST::IfNode < ::RuboCop::AST::Node def unless?; end end +class RuboCop::AST::IndexNode < ::RuboCop::AST::Node + include(::RuboCop::AST::ParameterizedNode) + include(::RuboCop::AST::MethodIdentifierPredicates) + include(::RuboCop::AST::MethodDispatchNode) + + def arguments; end + def assignment_method?; end + def attribute_accessor?; end + def method_name; end +end + +class RuboCop::AST::IndexasgnNode < ::RuboCop::AST::Node + include(::RuboCop::AST::ParameterizedNode) + include(::RuboCop::AST::MethodIdentifierPredicates) + include(::RuboCop::AST::MethodDispatchNode) + + def arguments; end + def assignment_method?; end + def attribute_accessor?; end + def method_name; end +end + class RuboCop::AST::IntNode < ::RuboCop::AST::Node include(::RuboCop::AST::NumericNode) end @@ -359,6 +381,19 @@ end RuboCop::AST::KeywordSplatNode::DOUBLE_SPLAT = T.let(T.unsafe(nil), String) +class RuboCop::AST::LambdaNode < ::RuboCop::AST::Node + include(::RuboCop::AST::ParameterizedNode) + include(::RuboCop::AST::MethodIdentifierPredicates) + include(::RuboCop::AST::MethodDispatchNode) + + def arguments; end + def assignment_method?; end + def attribute_accessor?; end + def lambda?; end + def lambda_literal?; end + def method_name; end +end + module RuboCop::AST::MethodDispatchNode include(::RuboCop::AST::MethodIdentifierPredicates) extend(::RuboCop::AST::NodePattern::Macros) @@ -409,9 +444,16 @@ module RuboCop::AST::MethodIdentifierPredicates def camel_case_method?; end def comparison_method?; end def const_receiver?; end + def enumerable_method?; end def enumerator_method?; end def method?(name); end def negation_method?; end + def nonmutating_array_method?; end + def nonmutating_binary_operator_method?; end + def nonmutating_hash_method?; end + def nonmutating_operator_method?; end + def nonmutating_string_method?; end + def nonmutating_unary_operator_method?; end def operator_method?; end def predicate_method?; end def prefix_bang?; end @@ -419,9 +461,23 @@ module RuboCop::AST::MethodIdentifierPredicates def self_receiver?; end end -RuboCop::AST::MethodIdentifierPredicates::ENUMERATOR_METHODS = T.let(T.unsafe(nil), Array) +RuboCop::AST::MethodIdentifierPredicates::ENUMERABLE_METHODS = T.let(T.unsafe(nil), Set) -RuboCop::AST::MethodIdentifierPredicates::OPERATOR_METHODS = T.let(T.unsafe(nil), Array) +RuboCop::AST::MethodIdentifierPredicates::ENUMERATOR_METHODS = T.let(T.unsafe(nil), Set) + +RuboCop::AST::MethodIdentifierPredicates::NONMUTATING_ARRAY_METHODS = T.let(T.unsafe(nil), Set) + +RuboCop::AST::MethodIdentifierPredicates::NONMUTATING_BINARY_OPERATOR_METHODS = T.let(T.unsafe(nil), Set) + +RuboCop::AST::MethodIdentifierPredicates::NONMUTATING_HASH_METHODS = T.let(T.unsafe(nil), Set) + +RuboCop::AST::MethodIdentifierPredicates::NONMUTATING_OPERATOR_METHODS = T.let(T.unsafe(nil), Set) + +RuboCop::AST::MethodIdentifierPredicates::NONMUTATING_STRING_METHODS = T.let(T.unsafe(nil), Set) + +RuboCop::AST::MethodIdentifierPredicates::NONMUTATING_UNARY_OPERATOR_METHODS = T.let(T.unsafe(nil), Set) + +RuboCop::AST::MethodIdentifierPredicates::OPERATOR_METHODS = T.let(T.unsafe(nil), Set) module RuboCop::AST::ModifierNode def modifier_form?; end @@ -450,6 +506,7 @@ class RuboCop::AST::Node < ::Parser::AST::Node def arg_type?; end def args_type?; end def argument?; end + def argument_type?; end def array_pattern_type?; end def array_pattern_with_tail_type?; end def array_type?; end @@ -506,9 +563,11 @@ class RuboCop::AST::Node < ::Parser::AST::Node def erange_type?; end def false_type?; end def falsey_literal?; end + def find_pattern_type?; end def first_line; end def float_type?; end def for_type?; end + def forward_arg_type?; end def forward_args_type?; end def forwarded_args_type?; end def guard_clause?; end @@ -542,6 +601,7 @@ class RuboCop::AST::Node < ::Parser::AST::Node def last_line; end def line_count; end def literal?; end + def loop_keyword?; end def lvar_type?; end def lvasgn_type?; end def masgn_type?; end @@ -582,6 +642,7 @@ class RuboCop::AST::Node < ::Parser::AST::Node def parent_module_name; end def parenthesized_call?; end def pin_type?; end + def post_condition_loop?; end def postexe_type?; end def preexe_type?; end def proc?(node = _); end @@ -654,6 +715,8 @@ class RuboCop::AST::Node < ::Parser::AST::Node def while_until_value_used?; end end +RuboCop::AST::Node::ARGUMENT_TYPES = T.let(T.unsafe(nil), Array) + RuboCop::AST::Node::ASSIGNMENTS = T.let(T.unsafe(nil), Array) RuboCop::AST::Node::BASIC_CONDITIONALS = T.let(T.unsafe(nil), Array) @@ -676,10 +739,14 @@ RuboCop::AST::Node::KEYWORDS = T.let(T.unsafe(nil), Array) RuboCop::AST::Node::LITERALS = T.let(T.unsafe(nil), Array) +RuboCop::AST::Node::LOOP_TYPES = T.let(T.unsafe(nil), Array) + RuboCop::AST::Node::MUTABLE_LITERALS = T.let(T.unsafe(nil), Array) RuboCop::AST::Node::OPERATOR_KEYWORDS = T.let(T.unsafe(nil), Array) +RuboCop::AST::Node::POST_CONDITION_LOOP_TYPES = T.let(T.unsafe(nil), Array) + RuboCop::AST::Node::REFERENCES = T.let(T.unsafe(nil), Array) RuboCop::AST::Node::SHORTHAND_ASSIGNMENTS = T.let(T.unsafe(nil), Array) @@ -697,7 +764,7 @@ class RuboCop::AST::NodePattern def eql?(other); end def marshal_dump; end def marshal_load(pattern); end - def match(*args); end + def match(*args, **rest); end def pattern; end def to_s; end @@ -708,12 +775,8 @@ class RuboCop::AST::NodePattern::Invalid < ::StandardError end module RuboCop::AST::NodePattern::Macros - def def_node_matcher(method_name, pattern_str); end - def def_node_search(method_name, pattern_str); end - def node_search(method_name, compiler, on_match, prelude, called_from); end - def node_search_all(method_name, compiler, called_from); end - def node_search_body(method_name, trailing_params, prelude, match_code, on_match); end - def node_search_first(method_name, compiler, called_from); end + def def_node_matcher(method_name, pattern_str, **keyword_defaults); end + def def_node_search(method_name, pattern_str, **keyword_defaults); end end module RuboCop::AST::NumericNode @@ -825,8 +888,22 @@ end class RuboCop::AST::RegexpNode < ::RuboCop::AST::Node def content; end + def delimiter?(char); end + def delimiters; end + def extended?; end + def ignore_case?; end + def interpolation?; end + def multiline_mode?; end + def no_encoding?; end + def percent_r_literal?; end def regopt; end + def single_interpolation?; end + def slash_literal?; end def to_regexp; end + + private + + def regopt_include?(option); end end RuboCop::AST::RegexpNode::OPTIONS = T.let(T.unsafe(nil), Hash) @@ -920,6 +997,7 @@ class RuboCop::AST::Token end module RuboCop::AST::Traversal + def on___ENCODING__(node); end def on_alias(node); end def on_and(node); end def on_and_asgn(node); end @@ -958,6 +1036,7 @@ module RuboCop::AST::Traversal def on_false(node); end def on_float(node); end def on_for(node); end + def on_forward_arg(node); end def on_forward_args(node); end def on_forwarded_args(node); end def on_gvar(node); end @@ -969,6 +1048,8 @@ module RuboCop::AST::Traversal def on_iflipflop(node); end def on_in_match(node); end def on_in_pattern(node); end + def on_index(node); end + def on_indexasgn(node); end def on_int(node); end def on_irange(node); end def on_ivar(node); end @@ -1005,6 +1086,7 @@ module RuboCop::AST::Traversal def on_pin(node); end def on_postexe(node); end def on_preexe(node); end + def on_procarg0(node); end def on_rational(node); end def on_redo(node); end def on_regexp(node); end @@ -1095,6 +1177,8 @@ RuboCop::AST::NodePattern::Compiler::CAPTURED_REST = T.let(T.unsafe(nil), String RuboCop::AST::NodePattern::Compiler::CLOSING = T.let(T.unsafe(nil), Regexp) +RuboCop::AST::NodePattern::Compiler::CONST = T.let(T.unsafe(nil), Regexp) + RuboCop::AST::NodePattern::Compiler::CUR_ELEMENT = T.let(T.unsafe(nil), String) RuboCop::AST::NodePattern::Compiler::CUR_NODE = T.let(T.unsafe(nil), String) @@ -1105,6 +1189,10 @@ RuboCop::AST::NodePattern::Compiler::FUNCALL = T.let(T.unsafe(nil), Regexp) RuboCop::AST::NodePattern::Compiler::IDENTIFIER = T.let(T.unsafe(nil), Regexp) +RuboCop::AST::NodePattern::Compiler::KEYWORD = T.let(T.unsafe(nil), Regexp) + +RuboCop::AST::NodePattern::Compiler::KEYWORD_NAME = T.let(T.unsafe(nil), Regexp) + RuboCop::AST::NodePattern::Compiler::LITERAL = T.let(T.unsafe(nil), Regexp) RuboCop::AST::NodePattern::Compiler::META = T.let(T.unsafe(nil), Regexp) @@ -1117,6 +1205,8 @@ RuboCop::AST::NodePattern::Compiler::NUMBER = T.let(T.unsafe(nil), Regexp) RuboCop::AST::NodePattern::Compiler::PARAM = T.let(T.unsafe(nil), Regexp) +RuboCop::AST::NodePattern::Compiler::PARAM_CONST = T.let(T.unsafe(nil), Regexp) + RuboCop::AST::NodePattern::Compiler::PARAM_NUMBER = T.let(T.unsafe(nil), Regexp) RuboCop::AST::NodePattern::Compiler::PREDICATE = T.let(T.unsafe(nil), Regexp) diff --git a/Library/Homebrew/sorbet/rbi/gems/zeitwerk@2.3.0.rbi b/Library/Homebrew/sorbet/rbi/gems/zeitwerk@2.3.1.rbi similarity index 73% rename from Library/Homebrew/sorbet/rbi/gems/zeitwerk@2.3.0.rbi rename to Library/Homebrew/sorbet/rbi/gems/zeitwerk@2.3.1.rbi index 27b1fb4bc6..198c6b42fc 100644 --- a/Library/Homebrew/sorbet/rbi/gems/zeitwerk@2.3.0.rbi +++ b/Library/Homebrew/sorbet/rbi/gems/zeitwerk@2.3.1.rbi @@ -1,5 +1,5 @@ # This file is autogenerated. Do not edit it by hand. Regenerate it with: -# tapioca sync +# tapioca sync --exclude json # typed: true From 8d55c87adbe9b080310b02c52ab226c4641dfd9a Mon Sep 17 00:00:00 2001 From: Michka Popoff Date: Tue, 30 Jun 2020 08:36:11 +0100 Subject: [PATCH 04/19] components order: fix audit and add test --- Library/Homebrew/rubocops/components_order.rb | 5 ++- .../test/rubocops/components_order_spec.rb | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/rubocops/components_order.rb b/Library/Homebrew/rubocops/components_order.rb index 04eaaea646..45153d7c92 100644 --- a/Library/Homebrew/rubocops/components_order.rb +++ b/Library/Homebrew/rubocops/components_order.rb @@ -226,11 +226,10 @@ module RuboCop next if succeeding_component.empty? offensive_nodes = check_precedence(preceding_component, succeeding_component) - break if offensive_nodes + return [present_components, offensive_nodes] if offensive_nodes end end - - [present_components, offensive_nodes] + nil end # Method to format message for reporting component precedence violations diff --git a/Library/Homebrew/test/rubocops/components_order_spec.rb b/Library/Homebrew/test/rubocops/components_order_spec.rb index a48b56601a..31f6cd5938 100644 --- a/Library/Homebrew/test/rubocops/components_order_spec.rb +++ b/Library/Homebrew/test/rubocops/components_order_spec.rb @@ -77,6 +77,37 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do RUBY end + it "When `install` precedes `depends_on`" do + expect_offense(<<~RUBY) + class Foo < Formula + url "https://brew.sh/foo-1.0.tgz" + + def install + end + + depends_on "openssl" + ^^^^^^^^^^^^^^^^^^^^ `depends_on` (line 7) should be put before `install` (line 4) + end + RUBY + end + + it "When `test` precedes `depends_on`" do + expect_offense(<<~RUBY) + class Foo < Formula + url "https://brew.sh/foo-1.0.tgz" + + def install + end + + def test + end + + depends_on "openssl" + ^^^^^^^^^^^^^^^^^^^^ `depends_on` (line 10) should be put before `install` (line 4) + end + RUBY + end + it "When only one of many `depends_on` precedes `conflicts_with`" do expect_offense(<<~RUBY) class Foo < Formula From 087ee9ab6cab8d76cae9ccba519704b71eedf7af Mon Sep 17 00:00:00 2001 From: vidusheeamoli Date: Tue, 30 Jun 2020 13:06:52 +0530 Subject: [PATCH 05/19] sorbet: update hidden definitions --- Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi b/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi index 096dbce314..0d2d80448f 100644 --- a/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi +++ b/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi @@ -19429,10 +19429,6 @@ class RuboCop::AST::Node def cask_block?(node=T.unsafe(nil)); end - def find_pattern_type?(); end - - def forward_arg_type?(); end - def key_node(node=T.unsafe(nil)); end def method_node(node=T.unsafe(nil)); end @@ -19604,6 +19600,10 @@ class RuboCop::Cop::FormulaAudit::Miscellaneous def languageNodeModule?(node0); end end +class RuboCop::Cop::FormulaAudit::Patches + def patch_data?(node0); end +end + class RuboCop::Cop::FormulaAudit::Test def test_calls(node0); end end From 455633f7d2f7d5d40b80ade9d5f8903b2c3ae9cb Mon Sep 17 00:00:00 2001 From: Pranas Ziaukas Date: Tue, 30 Jun 2020 12:12:34 +0300 Subject: [PATCH 06/19] Throttle balena-cli version bumps Discussion in Homebrew/homebrew-core#57082 --- Library/Homebrew/dev-cmd/audit.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index 9210c975f9..4a9d1cd9bc 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -553,6 +553,7 @@ module Homebrew THROTTLED_DENYLIST = { "aws-sdk-cpp" => "10", "awscli@1" => "10", + "balena-cli" => "10", "quicktype" => "10", "vim" => "50", }.freeze From 1c2ecfd761351ffa21c47081f753f96d38a60e1e Mon Sep 17 00:00:00 2001 From: Elizabeth Tackett Date: Thu, 25 Jun 2020 15:18:23 -0500 Subject: [PATCH 07/19] compare and display package versions --- scripts/README.md | 47 ++++++++++ scripts/bumpFormulae.rb | 20 +++++ scripts/helpers/api_parser.rb | 133 ++++++++++++++++++++++++++++ scripts/helpers/brew_commands.rb | 55 ++++++++++++ scripts/helpers/homebrew_formula.rb | 27 ++++++ scripts/helpers/parsed_file.rb | 23 +++++ scripts/printPackageUpdates.rb | 10 +++ 7 files changed, 315 insertions(+) create mode 100644 scripts/README.md create mode 100644 scripts/bumpFormulae.rb create mode 100644 scripts/helpers/api_parser.rb create mode 100644 scripts/helpers/brew_commands.rb create mode 100644 scripts/helpers/homebrew_formula.rb create mode 100644 scripts/helpers/parsed_file.rb create mode 100644 scripts/printPackageUpdates.rb diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000000..491bbe9657 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,47 @@ +# 0.0.1-API-Parser + +Parser for fixing this: https://github.com/Homebrew/brew/issues/5725 + +## Overview + +Homebrew is used to install software (packages). Homebrew uses 'formulae' to determine how a package is installed. +This project will automatically check which packages have had newer versions released, whether the package has an open PR on homebrew, and display the results. + +## High-level Solution + +- Fetch latest package version information from [repology.org](https://repology.org/) and store on file system. +- Fetch Homebrew Formulae information from [HomeBrew Formulae](https://formulae.brew.sh) +- Compare Current Homebrew Formulae version numbers and those coming from Repology's API and Livecheck. +- Determine whether package has open PR. +- Display results. + +## Details + +- This project can be run automatically at set intervals via GitHub Actions. +- Executing `ruby printPackageUpdates.rb` from the command line will query + both the Repology and Homebrew APIs. Homebrew's current version of each + package will be compared to the latest version of the package, per Repology's response. +- Homebrew's livecheck is also queried for each package, and that data is parsed, if available. +- Checks whether there is open PR for package. +- Each outdated package will be displayed to the console like so: +- Note that some packages will not be included in the Livecheck response. Those will have a 'Livecheck latest:' value of 'Not found'. + +``` +Package: openclonk +Brew current: 7.0 +Repology latest: 8.1 +Livecheck latest: 8.1 +Has Open PR?: true + +Package: openjdk +Brew current: 13.0.2+8 +Repology latest: 15.0.0.0~14 +Livecheck latest: Not found. +Has Open PR?: false + +Package: opentsdb +Brew current: 2.3.1 +Repology latest: 2.4.0 +Livecheck latest: 2.4.0 +Has Open PR?: true +``` diff --git a/scripts/bumpFormulae.rb b/scripts/bumpFormulae.rb new file mode 100644 index 0000000000..5ccf0aeda3 --- /dev/null +++ b/scripts/bumpFormulae.rb @@ -0,0 +1,20 @@ +require_relative 'helpers/parsed_file' +require_relative 'helpers/brew_commands.rb' + +brew_commands = BrewCommands.new + +parsed_file = ParsedFile.new +outdated_pckgs_to_update = parsed_file.get_latest_file("data/outdated_pckgs_to_update") + +File.foreach(outdated_pckgs_to_update) do |line| + line_hash = eval(line) + puts "\n bumping package: #{line_hash['name']} formula" + + begin + bump_pr_response, bump_pr_status = brew_commands.bump_formula_pr(line_hash['name'], line_hash['download_url'], line_hash['checksum']) + puts "#{bump_pr_response}" + rescue + puts "- An error occured whilst bumping package #{line_hash['name']} \n" + return + end +end diff --git a/scripts/helpers/api_parser.rb b/scripts/helpers/api_parser.rb new file mode 100644 index 0000000000..9ab58a97e7 --- /dev/null +++ b/scripts/helpers/api_parser.rb @@ -0,0 +1,133 @@ +require 'net/http' +require 'json' + +require_relative 'brew_commands' +require_relative 'homebrew_formula' + +class ApiParser + def call_api(url) + puts "- Calling API #{url}" + uri = URI(url) + response = Net::HTTP.get(uri) + + puts "- Parsing response" + JSON.parse(response) + end + + def query_repology_api(last_package_in_response = '') + url = 'https://repology.org/api/v1/projects/' + last_package_in_response + '?inrepo=homebrew&outdated=1' + + self.call_api(url) + end + + def parse_repology_api() + puts "\n-------- Query outdated packages from Repology --------" + page_no = 1 + puts "\n- Paginating repology api page: #{page_no}" + + outdated_packages = self.query_repology_api('') + last_pacakge_index = outdated_packages.size - 1 + response_size = outdated_packages.size + + while response_size > 1 do + page_no += 1 + puts "\n- Paginating repology api page: #{page_no}" + + last_package_in_response = outdated_packages.keys[last_pacakge_index] + response = self.query_repology_api("#{last_package_in_response}/") + + response_size = response.size + outdated_packages.merge!(response) + last_pacakge_index = outdated_packages.size - 1 + end + + puts "\n- #{outdated_packages.size} outdated pacakges identified by repology" + outdated_packages + end + + def query_homebrew + puts "\n-------- Get Homebrew Formulas --------" + self.call_api('https://formulae.brew.sh/api/formula.json') + end + + def parse_homebrew_formulas() + formulas = self.query_homebrew() + parsed_homebrew_formulas = {} + + formulas.each do |formula| + parsed_homebrew_formulas[formula['name']] = { + "fullname" => formula["full_name"], + "oldname" => formula["oldname"], + "version" => formula["versions"]['stable'], + "download_url" => formula["urls"]['stable']['url'], + } + end + + parsed_homebrew_formulas + end + + def validate_packages(outdated_repology_packages, brew_formulas) + puts "\n-------- Verify Outdated Repology packages as Homebrew Formulas --------" + packages = {} + + outdated_repology_packages.each do |package_name, repo_using_package| + # Identify homebrew repo + repology_homebrew_repo = repo_using_package.select { |repo| repo['repo'] == 'homebrew' }[0] + next if repology_homebrew_repo.empty? + + latest_version = nil + + # Identify latest version amongst repos + repo_using_package.each do |repo| + latest_version = repo['version'] if repo['status'] == 'newest' + end + + repology_homebrew_repo['latest_version'] = latest_version if latest_version + homebrew_package_details = brew_formulas[repology_homebrew_repo['srcname']] + + # Format package + packages[repology_homebrew_repo['srcname']] = format_package(homebrew_package_details, repology_homebrew_repo) + end + + packages + end + + + def format_package(homebrew_details, repology_details) + puts "- Formatting package: #{repology_details['srcname']}" + + homebrew_formula = HomebrewFormula.new + new_download_url = homebrew_formula.generate_new_download_url(homebrew_details['download_url'], homebrew_details['version'], repology_details['latest_version']) + + brew_commands = BrewCommands.new + livecheck_response = brew_commands.livecheck_check_formula(repology_details['srcname']) + has_open_pr = brew_commands.check_for_open_pr(repology_details['srcname'], new_download_url) + + formatted_package = { + 'fullname'=> homebrew_details['fullname'], + 'repology_version' => repology_details['latest_version'], + 'homebrew_version' => homebrew_details['version'], + 'livecheck_latest_version' => livecheck_response['livecheck_latest_version'], + 'current_download_url' => homebrew_details['download_url'], + 'latest_download_url' => new_download_url, + 'repology_latest_version' => repology_details['latest_version'], + 'has_open_pr' => has_open_pr + } + + formatted_package + end + + def display_version_data(outdated_packages) + puts "==============Formatted outdated packages============\n" + + outdated_packages.each do |package_name, package_details| + puts "" + puts "Package: #{package_name}" + puts "Brew current: #{package_details['homebrew_version']}" + puts "Repology latest: #{package_details['repology_version']}" + puts "Livecheck latest: #{package_details['livecheck_latest_version']}" + puts "Has Open PR?: #{package_details['has_open_pr']}" + end + end + +end diff --git a/scripts/helpers/brew_commands.rb b/scripts/helpers/brew_commands.rb new file mode 100644 index 0000000000..526162095b --- /dev/null +++ b/scripts/helpers/brew_commands.rb @@ -0,0 +1,55 @@ +require "open3" + +class BrewCommands + + def livecheck_check_formula(formula_name) + puts "- livecheck formula : #{formula_name}" + command_args = [ + "brew", + "livecheck", + formula_name, + "--quiet", + ] + + response = Open3.capture2e(*command_args) + self.parse_livecheck_response(response) + end + + def parse_livecheck_response(livecheck_output) + livecheck_output = livecheck_output.first.gsub(' ', '').split(/:|==>|\n/) + + # eg: ["burp", "2.2.18", "2.2.18"] + package_name, brew_version, latest_version = livecheck_output + + {'name' => package_name, 'current_brew_version' => brew_version, 'livecheck_latest_version' => latest_version} + end + + def bump_formula_pr(formula_name, url) + command_args = [ + "brew", + "bump-formula-pr", + "--no-browse", + "--dry-run", + formula_name, + "--url=#{url}", + ] + + response = Open3.capture2e(*command_args) + self.parse_formula_bump_response(response) + end + + def parse_formula_bump_response(formula_bump_response) + response, status = formula_bump_response + response + end + + def check_for_open_pr(formula_name, download_url) + puts "- Checking for open PRs for formula : #{formula_name}" + + response = bump_formula_pr(formula_name, download_url) + + return true if !response.include? 'Error: These open pull requests may be duplicates' + false + end + +end \ No newline at end of file diff --git a/scripts/helpers/homebrew_formula.rb b/scripts/helpers/homebrew_formula.rb new file mode 100644 index 0000000000..d99b7e8bde --- /dev/null +++ b/scripts/helpers/homebrew_formula.rb @@ -0,0 +1,27 @@ +require 'net/http' +require 'open-uri' + +class HomebrewFormula + + def generate_new_download_url(outdated_url, old_version, latest_version) + if [outdated_url, old_version, latest_version].include? nil + puts "\n- Could not generate download url" + nil + else + puts "\n- Generating download url" + outdated_url.gsub(old_version, latest_version) + end + end + + def generate_checksum(new_url) + begin + puts "- Generating checksum for url: #{new_url}" + tempfile = URI.parse(new_url).open + tempfile.close + return Digest::SHA256.file(tempfile.path).hexdigest + rescue + puts "- Failed to generate Checksum \n" + return nil + end + end +end diff --git a/scripts/helpers/parsed_file.rb b/scripts/helpers/parsed_file.rb new file mode 100644 index 0000000000..038a11a38d --- /dev/null +++ b/scripts/helpers/parsed_file.rb @@ -0,0 +1,23 @@ +require 'fileutils' + +class ParsedFile + + def get_latest_file(directory) + puts "- retrieving latest file in directory: #{directory}" + Dir.glob("#{directory}/*").max_by(1) {|f| File.mtime(f)}[0] + end + + def save_to(directory, data) + # Create directory if does not exist + FileUtils.mkdir_p directory unless Dir.exists?(directory) + + puts "- Generating datetime stamp" + #Include time to the filename for uniqueness when fetching multiple times a day + date_time = Time.new.strftime("%Y-%m-%dT%H_%M_%S") + + # Writing parsed data to file + puts "- Writing data to file" + File.write("#{directory}/#{date_time}.txt", data) + end + +end \ No newline at end of file diff --git a/scripts/printPackageUpdates.rb b/scripts/printPackageUpdates.rb new file mode 100644 index 0000000000..4b57abd95b --- /dev/null +++ b/scripts/printPackageUpdates.rb @@ -0,0 +1,10 @@ +require_relative 'helpers/api_parser' + +api_parser = ApiParser.new + +outdated_repology_packages = api_parser.parse_repology_api() +brew_formulas = api_parser.parse_homebrew_formulas() + +formatted_outdated_packages = api_parser.validate_packages(outdated_repology_packages, brew_formulas) + +api_parser.display_version_data(formatted_outdated_packages) From d846cf7a6a99cfa32ef989f09e9b326d72c833d3 Mon Sep 17 00:00:00 2001 From: Elizabeth Tackett Date: Mon, 29 Jun 2020 09:18:36 -0500 Subject: [PATCH 08/19] add repology util file --- Library/Homebrew/utils/repology.rb | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Library/Homebrew/utils/repology.rb diff --git a/Library/Homebrew/utils/repology.rb b/Library/Homebrew/utils/repology.rb new file mode 100644 index 0000000000..e69de29bb2 From ce41cb46280f39ebd7f20b396b302c16e15fb2cc Mon Sep 17 00:00:00 2001 From: Elizabeth Tackett Date: Mon, 29 Jun 2020 09:21:06 -0500 Subject: [PATCH 09/19] rename repology.rb to update.rb --- Library/Homebrew/utils/repology.rb | 0 Library/Homebrew/utils/update.rb | 6 ++++++ 2 files changed, 6 insertions(+) delete mode 100644 Library/Homebrew/utils/repology.rb create mode 100644 Library/Homebrew/utils/update.rb diff --git a/Library/Homebrew/utils/repology.rb b/Library/Homebrew/utils/repology.rb deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Library/Homebrew/utils/update.rb b/Library/Homebrew/utils/update.rb new file mode 100644 index 0000000000..84defcf33b --- /dev/null +++ b/Library/Homebrew/utils/update.rb @@ -0,0 +1,6 @@ +require 'net/http' +require 'json' + +module Utils + +end From 05d7c40ea5fb14243bdba939ab9ef86196269468 Mon Sep 17 00:00:00 2001 From: Elizabeth Tackett Date: Mon, 29 Jun 2020 09:26:27 -0500 Subject: [PATCH 10/19] place api_parser code into util module --- Library/Homebrew/utils/update.rb | 127 ++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/utils/update.rb b/Library/Homebrew/utils/update.rb index 84defcf33b..9f84ee7e58 100644 --- a/Library/Homebrew/utils/update.rb +++ b/Library/Homebrew/utils/update.rb @@ -2,5 +2,130 @@ require 'net/http' require 'json' module Utils - + class ApiParser + def call_api(url) + puts "- Calling API #{url}" + uri = URI(url) + response = Net::HTTP.get(uri) + + puts "- Parsing response" + JSON.parse(response) + end + + def query_repology_api(last_package_in_response = '') + url = 'https://repology.org/api/v1/projects/' + last_package_in_response + '?inrepo=homebrew&outdated=1' + + self.call_api(url) + end + + def parse_repology_api() + puts "\n-------- Query outdated packages from Repology --------" + page_no = 1 + puts "\n- Paginating repology api page: #{page_no}" + + outdated_packages = self.query_repology_api('') + last_pacakge_index = outdated_packages.size - 1 + response_size = outdated_packages.size + + while response_size > 1 do + page_no += 1 + puts "\n- Paginating repology api page: #{page_no}" + + last_package_in_response = outdated_packages.keys[last_pacakge_index] + response = self.query_repology_api("#{last_package_in_response}/") + + response_size = response.size + outdated_packages.merge!(response) + last_pacakge_index = outdated_packages.size - 1 + end + + puts "\n- #{outdated_packages.size} outdated pacakges identified by repology" + outdated_packages + end + end + + def query_homebrew + puts "\n-------- Get Homebrew Formulas --------" + self.call_api('https://formulae.brew.sh/api/formula.json') + end + + def parse_homebrew_formulas() + formulas = self.query_homebrew() + parsed_homebrew_formulas = {} + + formulas.each do |formula| + parsed_homebrew_formulas[formula['name']] = { + "fullname" => formula["full_name"], + "oldname" => formula["oldname"], + "version" => formula["versions"]['stable'], + "download_url" => formula["urls"]['stable']['url'], + } + end + + parsed_homebrew_formulas + end + + def validate_packages(outdated_repology_packages, brew_formulas) + puts "\n-------- Verify Outdated Repology packages as Homebrew Formulas --------" + packages = {} + + outdated_repology_packages.each do |package_name, repo_using_package| + # Identify homebrew repo + repology_homebrew_repo = repo_using_package.select { |repo| repo['repo'] == 'homebrew' }[0] + next if repology_homebrew_repo.empty? + + latest_version = nil + + # Identify latest version amongst repos + repo_using_package.each do |repo| + latest_version = repo['version'] if repo['status'] == 'newest' + end + + repology_homebrew_repo['latest_version'] = latest_version if latest_version + homebrew_package_details = brew_formulas[repology_homebrew_repo['srcname']] + + # Format package + packages[repology_homebrew_repo['srcname']] = format_package(homebrew_package_details, repology_homebrew_repo) + end + + packages + end + + + def format_package(homebrew_details, repology_details) + puts "- Formatting package: #{repology_details['srcname']}" + + homebrew_formula = HomebrewFormula.new + new_download_url = homebrew_formula.generate_new_download_url(homebrew_details['download_url'], homebrew_details['version'], repology_details['latest_version']) + + brew_commands = BrewCommands.new + livecheck_response = brew_commands.livecheck_check_formula(repology_details['srcname']) + has_open_pr = brew_commands.check_for_open_pr(repology_details['srcname'], new_download_url) + + formatted_package = { + 'fullname'=> homebrew_details['fullname'], + 'repology_version' => repology_details['latest_version'], + 'homebrew_version' => homebrew_details['version'], + 'livecheck_latest_version' => livecheck_response['livecheck_latest_version'], + 'current_download_url' => homebrew_details['download_url'], + 'latest_download_url' => new_download_url, + 'repology_latest_version' => repology_details['latest_version'], + 'has_open_pr' => has_open_pr + } + + formatted_package + end + + def display_version_data(outdated_packages) + puts "==============Formatted outdated packages============\n" + + outdated_packages.each do |package_name, package_details| + puts "" + puts "Package: #{package_name}" + puts "Brew current: #{package_details['homebrew_version']}" + puts "Repology latest: #{package_details['repology_version']}" + puts "Livecheck latest: #{package_details['livecheck_latest_version']}" + puts "Has Open PR?: #{package_details['has_open_pr']}" + end + end end From 5d9d0bb284ffebbac225c5027e5eef19b8b324d5 Mon Sep 17 00:00:00 2001 From: Elizabeth Tackett Date: Mon, 29 Jun 2020 09:27:42 -0500 Subject: [PATCH 11/19] update display text --- Library/Homebrew/utils/update.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/utils/update.rb b/Library/Homebrew/utils/update.rb index 9f84ee7e58..87b363bb08 100644 --- a/Library/Homebrew/utils/update.rb +++ b/Library/Homebrew/utils/update.rb @@ -121,11 +121,11 @@ module Utils outdated_packages.each do |package_name, package_details| puts "" - puts "Package: #{package_name}" - puts "Brew current: #{package_details['homebrew_version']}" - puts "Repology latest: #{package_details['repology_version']}" - puts "Livecheck latest: #{package_details['livecheck_latest_version']}" - puts "Has Open PR?: #{package_details['has_open_pr']}" + puts "Formula: #{package_name}" + puts "Current formula version: #{package_details['homebrew_version']}" + puts "Repology latest version: #{package_details['repology_version']}" + puts "Livecheck latest version: #{package_details['livecheck_latest_version']}" + puts "Open pull request: #{package_details['has_open_pr']}" end end end From f82da9009fe0f862df5ed534d3914a51bf4718f2 Mon Sep 17 00:00:00 2001 From: Elizabeth Tackett Date: Mon, 29 Jun 2020 09:33:24 -0500 Subject: [PATCH 12/19] remove unnecessary explicit return val --- Library/Homebrew/utils/update.rb | 3 +-- scripts/helpers/brew_commands.rb | 13 ++++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Library/Homebrew/utils/update.rb b/Library/Homebrew/utils/update.rb index 87b363bb08..48a18daa10 100644 --- a/Library/Homebrew/utils/update.rb +++ b/Library/Homebrew/utils/update.rb @@ -120,8 +120,7 @@ module Utils puts "==============Formatted outdated packages============\n" outdated_packages.each do |package_name, package_details| - puts "" - puts "Formula: #{package_name}" + puts "\nFormula: #{package_name}" puts "Current formula version: #{package_details['homebrew_version']}" puts "Repology latest version: #{package_details['repology_version']}" puts "Livecheck latest version: #{package_details['livecheck_latest_version']}" diff --git a/scripts/helpers/brew_commands.rb b/scripts/helpers/brew_commands.rb index 526162095b..380e64da48 100644 --- a/scripts/helpers/brew_commands.rb +++ b/scripts/helpers/brew_commands.rb @@ -1,7 +1,7 @@ require "open3" class BrewCommands - + def livecheck_check_formula(formula_name) puts "- livecheck formula : #{formula_name}" command_args = [ @@ -20,7 +20,7 @@ class BrewCommands # eg: ["burp", "2.2.18", "2.2.18"] package_name, brew_version, latest_version = livecheck_output - + {'name' => package_name, 'current_brew_version' => brew_version, 'livecheck_latest_version' => latest_version} end @@ -40,7 +40,7 @@ class BrewCommands def parse_formula_bump_response(formula_bump_response) response, status = formula_bump_response - response + response end def check_for_open_pr(formula_name, download_url) @@ -48,8 +48,7 @@ class BrewCommands response = bump_formula_pr(formula_name, download_url) - return true if !response.include? 'Error: These open pull requests may be duplicates' - false - end + !response.include? 'Error: These open pull requests may be duplicates' + end -end \ No newline at end of file +end From 24bb79c2abc4f55d7b0827b6d0fff3797f2b2fc1 Mon Sep 17 00:00:00 2001 From: Elizabeth Tackett Date: Mon, 29 Jun 2020 09:37:50 -0500 Subject: [PATCH 13/19] initialize bump.rb file --- Library/Homebrew/dev-cmd/bump.rb | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Library/Homebrew/dev-cmd/bump.rb diff --git a/Library/Homebrew/dev-cmd/bump.rb b/Library/Homebrew/dev-cmd/bump.rb new file mode 100644 index 0000000000..e69de29bb2 From 9a94bb254325b88062b019cd51076c47e599384a Mon Sep 17 00:00:00 2001 From: Elizabeth Tackett Date: Mon, 29 Jun 2020 09:47:19 -0500 Subject: [PATCH 14/19] skeleton code bump dev-cmd file --- Library/Homebrew/dev-cmd/bump.rb | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Library/Homebrew/dev-cmd/bump.rb b/Library/Homebrew/dev-cmd/bump.rb index e69de29bb2..89f9ede7b3 100644 --- a/Library/Homebrew/dev-cmd/bump.rb +++ b/Library/Homebrew/dev-cmd/bump.rb @@ -0,0 +1,19 @@ +require "cli/parser" + +module Homebrew + module_function + + def bump_args + Homebrew::CLI::Parser.new do + usage_banner <<~EOS + `bump` + + Display out-of-date brew formulae, the latest version available, and whether a pull request has been opened. + EOS + end + end + + def bump + bump_args.parse + end +end From 13d4f2472760106b1a02f9f1b900e829deee6a66 Mon Sep 17 00:00:00 2001 From: Elizabeth Tackett Date: Mon, 29 Jun 2020 09:51:58 -0500 Subject: [PATCH 15/19] focus util module on repology API call --- Library/Homebrew/utils/repology.rb | 46 ++++++++++ Library/Homebrew/utils/update.rb | 130 ----------------------------- 2 files changed, 46 insertions(+), 130 deletions(-) create mode 100644 Library/Homebrew/utils/repology.rb delete mode 100644 Library/Homebrew/utils/update.rb diff --git a/Library/Homebrew/utils/repology.rb b/Library/Homebrew/utils/repology.rb new file mode 100644 index 0000000000..822dfac51a --- /dev/null +++ b/Library/Homebrew/utils/repology.rb @@ -0,0 +1,46 @@ +require 'net/http' +require 'json' + +module Utils + module RepologyParser + def call_api(url) + puts "- Calling API #{url}" + uri = URI(url) + response = Net::HTTP.get(uri) + + puts "- Parsing response" + JSON.parse(response) + end + + def query_repology_api(last_package_in_response = '') + url = 'https://repology.org/api/v1/projects/' + last_package_in_response + '?inrepo=homebrew&outdated=1' + + self.call_api(url) + end + + def parse_repology_api() + puts "\n-------- Query outdated packages from Repology --------" + page_no = 1 + puts "\n- Paginating repology api page: #{page_no}" + + outdated_packages = self.query_repology_api('') + last_pacakge_index = outdated_packages.size - 1 + response_size = outdated_packages.size + + while response_size > 1 do + page_no += 1 + puts "\n- Paginating repology api page: #{page_no}" + + last_package_in_response = outdated_packages.keys[last_pacakge_index] + response = self.query_repology_api("#{last_package_in_response}/") + + response_size = response.size + outdated_packages.merge!(response) + last_pacakge_index = outdated_packages.size - 1 + end + + puts "\n- #{outdated_packages.size} outdated pacakges identified by repology" + outdated_packages + end + end +end diff --git a/Library/Homebrew/utils/update.rb b/Library/Homebrew/utils/update.rb deleted file mode 100644 index 48a18daa10..0000000000 --- a/Library/Homebrew/utils/update.rb +++ /dev/null @@ -1,130 +0,0 @@ -require 'net/http' -require 'json' - -module Utils - class ApiParser - def call_api(url) - puts "- Calling API #{url}" - uri = URI(url) - response = Net::HTTP.get(uri) - - puts "- Parsing response" - JSON.parse(response) - end - - def query_repology_api(last_package_in_response = '') - url = 'https://repology.org/api/v1/projects/' + last_package_in_response + '?inrepo=homebrew&outdated=1' - - self.call_api(url) - end - - def parse_repology_api() - puts "\n-------- Query outdated packages from Repology --------" - page_no = 1 - puts "\n- Paginating repology api page: #{page_no}" - - outdated_packages = self.query_repology_api('') - last_pacakge_index = outdated_packages.size - 1 - response_size = outdated_packages.size - - while response_size > 1 do - page_no += 1 - puts "\n- Paginating repology api page: #{page_no}" - - last_package_in_response = outdated_packages.keys[last_pacakge_index] - response = self.query_repology_api("#{last_package_in_response}/") - - response_size = response.size - outdated_packages.merge!(response) - last_pacakge_index = outdated_packages.size - 1 - end - - puts "\n- #{outdated_packages.size} outdated pacakges identified by repology" - outdated_packages - end - end - - def query_homebrew - puts "\n-------- Get Homebrew Formulas --------" - self.call_api('https://formulae.brew.sh/api/formula.json') - end - - def parse_homebrew_formulas() - formulas = self.query_homebrew() - parsed_homebrew_formulas = {} - - formulas.each do |formula| - parsed_homebrew_formulas[formula['name']] = { - "fullname" => formula["full_name"], - "oldname" => formula["oldname"], - "version" => formula["versions"]['stable'], - "download_url" => formula["urls"]['stable']['url'], - } - end - - parsed_homebrew_formulas - end - - def validate_packages(outdated_repology_packages, brew_formulas) - puts "\n-------- Verify Outdated Repology packages as Homebrew Formulas --------" - packages = {} - - outdated_repology_packages.each do |package_name, repo_using_package| - # Identify homebrew repo - repology_homebrew_repo = repo_using_package.select { |repo| repo['repo'] == 'homebrew' }[0] - next if repology_homebrew_repo.empty? - - latest_version = nil - - # Identify latest version amongst repos - repo_using_package.each do |repo| - latest_version = repo['version'] if repo['status'] == 'newest' - end - - repology_homebrew_repo['latest_version'] = latest_version if latest_version - homebrew_package_details = brew_formulas[repology_homebrew_repo['srcname']] - - # Format package - packages[repology_homebrew_repo['srcname']] = format_package(homebrew_package_details, repology_homebrew_repo) - end - - packages - end - - - def format_package(homebrew_details, repology_details) - puts "- Formatting package: #{repology_details['srcname']}" - - homebrew_formula = HomebrewFormula.new - new_download_url = homebrew_formula.generate_new_download_url(homebrew_details['download_url'], homebrew_details['version'], repology_details['latest_version']) - - brew_commands = BrewCommands.new - livecheck_response = brew_commands.livecheck_check_formula(repology_details['srcname']) - has_open_pr = brew_commands.check_for_open_pr(repology_details['srcname'], new_download_url) - - formatted_package = { - 'fullname'=> homebrew_details['fullname'], - 'repology_version' => repology_details['latest_version'], - 'homebrew_version' => homebrew_details['version'], - 'livecheck_latest_version' => livecheck_response['livecheck_latest_version'], - 'current_download_url' => homebrew_details['download_url'], - 'latest_download_url' => new_download_url, - 'repology_latest_version' => repology_details['latest_version'], - 'has_open_pr' => has_open_pr - } - - formatted_package - end - - def display_version_data(outdated_packages) - puts "==============Formatted outdated packages============\n" - - outdated_packages.each do |package_name, package_details| - puts "\nFormula: #{package_name}" - puts "Current formula version: #{package_details['homebrew_version']}" - puts "Repology latest version: #{package_details['repology_version']}" - puts "Livecheck latest version: #{package_details['livecheck_latest_version']}" - puts "Open pull request: #{package_details['has_open_pr']}" - end - end -end From bc5cdc2aac988b55e7618847bdf972015052d6bd Mon Sep 17 00:00:00 2001 From: Elizabeth Tackett Date: Mon, 29 Jun 2020 09:57:21 -0500 Subject: [PATCH 16/19] typo --- Library/Homebrew/utils/repology.rb | 65 +++++++++++++++--------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/Library/Homebrew/utils/repology.rb b/Library/Homebrew/utils/repology.rb index 822dfac51a..0ee4fabc01 100644 --- a/Library/Homebrew/utils/repology.rb +++ b/Library/Homebrew/utils/repology.rb @@ -1,46 +1,45 @@ require 'net/http' require 'json' -module Utils - module RepologyParser - def call_api(url) - puts "- Calling API #{url}" - uri = URI(url) - response = Net::HTTP.get(uri) +module RepologyParser + def call_api(url) + puts "- Calling API #{url}" + uri = URI(url) + response = Net::HTTP.get(uri) - puts "- Parsing response" - JSON.parse(response) - end + puts "- Parsing response" + JSON.parse(response) + end - def query_repology_api(last_package_in_response = '') - url = 'https://repology.org/api/v1/projects/' + last_package_in_response + '?inrepo=homebrew&outdated=1' + def query_repology_api(last_package_in_response = '') + url = 'https://repology.org/api/v1/projects/' + last_package_in_response + '?inrepo=homebrew&outdated=1' - self.call_api(url) - end + call_api(url) + end - def parse_repology_api() - puts "\n-------- Query outdated packages from Repology --------" - page_no = 1 + def parse_repology_api() + puts "\n-------- Query outdated packages from Repology --------" + page_no = 1 + puts "\n- Paginating repology api page: #{page_no}" + + outdated_packages = query_repology_api('') + last_pacakge_index = outdated_packages.size - 1 + response_size = outdated_packages.size + + while response_size > 1 do + page_no += 1 puts "\n- Paginating repology api page: #{page_no}" - outdated_packages = self.query_repology_api('') + last_package_in_response = outdated_packages.keys[last_pacakge_index] + response = query_repology_api("#{last_package_in_response}/") + + response_size = response.size + outdated_packages.merge!(response) last_pacakge_index = outdated_packages.size - 1 - response_size = outdated_packages.size - - while response_size > 1 do - page_no += 1 - puts "\n- Paginating repology api page: #{page_no}" - - last_package_in_response = outdated_packages.keys[last_pacakge_index] - response = self.query_repology_api("#{last_package_in_response}/") - - response_size = response.size - outdated_packages.merge!(response) - last_pacakge_index = outdated_packages.size - 1 - end - - puts "\n- #{outdated_packages.size} outdated pacakges identified by repology" - outdated_packages end + + puts "\n- #{outdated_packages.size} outdated packages identified by repology" + + outdated_packages end end From c3c70f137bfaa651b9745529cffaac3f4b622840 Mon Sep 17 00:00:00 2001 From: Elizabeth Tackett Date: Mon, 29 Jun 2020 09:57:54 -0500 Subject: [PATCH 17/19] remove extraneous file --- scripts/helpers/parsed_file.rb | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 scripts/helpers/parsed_file.rb diff --git a/scripts/helpers/parsed_file.rb b/scripts/helpers/parsed_file.rb deleted file mode 100644 index 038a11a38d..0000000000 --- a/scripts/helpers/parsed_file.rb +++ /dev/null @@ -1,23 +0,0 @@ -require 'fileutils' - -class ParsedFile - - def get_latest_file(directory) - puts "- retrieving latest file in directory: #{directory}" - Dir.glob("#{directory}/*").max_by(1) {|f| File.mtime(f)}[0] - end - - def save_to(directory, data) - # Create directory if does not exist - FileUtils.mkdir_p directory unless Dir.exists?(directory) - - puts "- Generating datetime stamp" - #Include time to the filename for uniqueness when fetching multiple times a day - date_time = Time.new.strftime("%Y-%m-%dT%H_%M_%S") - - # Writing parsed data to file - puts "- Writing data to file" - File.write("#{directory}/#{date_time}.txt", data) - end - -end \ No newline at end of file From d557ca80bc6ac08cda89cf397b73a0bd06e534f1 Mon Sep 17 00:00:00 2001 From: Elizabeth Tackett Date: Mon, 29 Jun 2020 10:16:58 -0500 Subject: [PATCH 18/19] fix brew style violations --- Library/Homebrew/dev-cmd/bump.rb | 2 ++ Library/Homebrew/utils/repology.rb | 16 +++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Library/Homebrew/dev-cmd/bump.rb b/Library/Homebrew/dev-cmd/bump.rb index 89f9ede7b3..7a5c6b427e 100644 --- a/Library/Homebrew/dev-cmd/bump.rb +++ b/Library/Homebrew/dev-cmd/bump.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "cli/parser" module Homebrew diff --git a/Library/Homebrew/utils/repology.rb b/Library/Homebrew/utils/repology.rb index 0ee4fabc01..80973956b1 100644 --- a/Library/Homebrew/utils/repology.rb +++ b/Library/Homebrew/utils/repology.rb @@ -1,5 +1,7 @@ -require 'net/http' -require 'json' +# frozen_string_literal: true + +require "net/http" +require "json" module RepologyParser def call_api(url) @@ -11,22 +13,22 @@ module RepologyParser JSON.parse(response) end - def query_repology_api(last_package_in_response = '') - url = 'https://repology.org/api/v1/projects/' + last_package_in_response + '?inrepo=homebrew&outdated=1' + def query_repology_api(last_package_in_response = "") + url = "https://repology.org/api/v1/projects/#{last_package_in_response}?inrepo=homebrew&outdated=1" call_api(url) end - def parse_repology_api() + def parse_repology_api puts "\n-------- Query outdated packages from Repology --------" page_no = 1 puts "\n- Paginating repology api page: #{page_no}" - outdated_packages = query_repology_api('') + outdated_packages = query_repology_api("") last_pacakge_index = outdated_packages.size - 1 response_size = outdated_packages.size - while response_size > 1 do + while response_size > 1 page_no += 1 puts "\n- Paginating repology api page: #{page_no}" From 3fb675626e2842bbf73b6e1e23d20802dbb93872 Mon Sep 17 00:00:00 2001 From: Elizabeth Tackett Date: Tue, 30 Jun 2020 09:57:34 -0500 Subject: [PATCH 19/19] parse application source code into modules. replace HTTP query for brew version info --- Library/Homebrew/utils/livecheck.rb | 27 +++++++++++++++++++++ Library/Homebrew/utils/repology.rb | 37 +++++++++++++++++++++++++---- Library/Homebrew/utils/versions.rb | 36 ++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 Library/Homebrew/utils/livecheck.rb create mode 100644 Library/Homebrew/utils/versions.rb diff --git a/Library/Homebrew/utils/livecheck.rb b/Library/Homebrew/utils/livecheck.rb new file mode 100644 index 0000000000..2b420ef86c --- /dev/null +++ b/Library/Homebrew/utils/livecheck.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require "open3" + +module Livecheck + def livecheck_formula_response(formula_name) + puts "- livecheck formula : #{formula_name}" + command_args = [ + "brew", + "livecheck", + formula_name, + "--quiet" + ] + + response = Open3.capture2e(*command_args) + parse_livecheck_response(response) + end + + def parse_livecheck_response(response) + output = response.first.gsub(' ', '').split(/:|==>|\n/) + + # eg: ["burp", "2.2.18", "2.2.18"] + package_name, brew_version, latest_version = output + + {'name' => package_name, 'current_brew_version' => brew_version, 'livecheck_latest_version' => latest_version} + end +end diff --git a/Library/Homebrew/utils/repology.rb b/Library/Homebrew/utils/repology.rb index 80973956b1..4e6c3cfbed 100644 --- a/Library/Homebrew/utils/repology.rb +++ b/Library/Homebrew/utils/repology.rb @@ -25,23 +25,50 @@ module RepologyParser puts "\n- Paginating repology api page: #{page_no}" outdated_packages = query_repology_api("") - last_pacakge_index = outdated_packages.size - 1 + last_package_index = outdated_packages.size - 1 response_size = outdated_packages.size - while response_size > 1 + while response_size > 1 do page_no += 1 puts "\n- Paginating repology api page: #{page_no}" - last_package_in_response = outdated_packages.keys[last_pacakge_index] + last_package_in_response = outdated_packages.keys[last_package_index] response = query_repology_api("#{last_package_in_response}/") response_size = response.size outdated_packages.merge!(response) - last_pacakge_index = outdated_packages.size - 1 + last_package_index = outdated_packages.size - 1 end - puts "\n- #{outdated_packages.size} outdated packages identified by repology" + puts "\n- #{outdated_packages.size} outdated packages identified" outdated_packages end + + def validate__repology_packages(outdated_repology_packages, brew_formulas) + puts "\n---- Verify Outdated Repology Packages as Homebrew Formulae -----" + + packages = {} + + outdated_repology_packages.each do |name, repositories| + # identify homebrew repo + repology_homebrew_repo = repositories.select do + |repo| repo['repo'] == 'homebrew' + end.first + + next if repology_homebrew_repo.empty? + latest_version = nil + + #identify latest version amongst repology repos + repositories.each do |repo| + latest_version = repo['version'] if repo['status'] == 'newest' + end + + packages[repology_homebrew_repo['srcname']] = { + 'repology_latest_version' => latest_version, + } + end + # hash of hashes {'openclonk' => {repology_latest_version => 7.0}, ..} + packages + end end diff --git a/Library/Homebrew/utils/versions.rb b/Library/Homebrew/utils/versions.rb new file mode 100644 index 0000000000..5da7f873ea --- /dev/null +++ b/Library/Homebrew/utils/versions.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require "open3" +require "formula" + +module Versions + def current_formula_version(formula_name) + Formula[formula_name].version.to_s.to_f + end + + def bump_formula_pr(formula_name, url) + command_args = [ + "brew", + "bump-formula-pr", + "--no-browse", + "--dry-run", + formula_name, + "--url=#{url}", + ] + + response = Open3.capture2e(*command_args) + parse_formula_bump_response(response) + end + + def parse_formula_bump_response(response) + response, status = formula_bump_response + response + end + + def check_for_open_pr(formula_name, download_url) + puts "- Checking for open PRs for formula : #{formula_name}" + + response = bump_formula_pr(formula_name, download_url) + !response.include? 'Error: These open pull requests may be duplicates' + end +end