homebrew: Support old_tokens and oldnames in homebrew package data (#10805)
Some checks failed
EOL CI / EOL Sanity (Ⓐ2.16) (push) Has been cancelled
EOL CI / EOL Units (Ⓐ2.16+py2.7) (push) Has been cancelled
EOL CI / EOL Units (Ⓐ2.16+py3.11) (push) Has been cancelled
EOL CI / EOL Units (Ⓐ2.16+py3.6) (push) Has been cancelled
EOL CI / EOL I (Ⓐ2.16+alpine3+py:azp/posix/1/) (push) Has been cancelled
EOL CI / EOL I (Ⓐ2.16+alpine3+py:azp/posix/2/) (push) Has been cancelled
EOL CI / EOL I (Ⓐ2.16+alpine3+py:azp/posix/3/) (push) Has been cancelled
EOL CI / EOL I (Ⓐ2.16+fedora38+py:azp/posix/1/) (push) Has been cancelled
EOL CI / EOL I (Ⓐ2.16+fedora38+py:azp/posix/2/) (push) Has been cancelled
EOL CI / EOL I (Ⓐ2.16+fedora38+py:azp/posix/3/) (push) Has been cancelled
EOL CI / EOL I (Ⓐ2.16+opensuse15+py:azp/posix/1/) (push) Has been cancelled
EOL CI / EOL I (Ⓐ2.16+opensuse15+py:azp/posix/2/) (push) Has been cancelled
EOL CI / EOL I (Ⓐ2.16+opensuse15+py:azp/posix/3/) (push) Has been cancelled
nox / Run extra sanity tests (push) Has been cancelled

* homebrew: Support old_tokens and oldnames in homebrew package data

Fixes #10804

Since brew info will accept old_tokens (for casks) and oldnames (for formulae) when provided by the homebrew module "name" argument, the module also needs to consider thes old names as valid for the given package.  This commit updates _extract_package_name to do that.

All existing package name tests, including existing tests for name aliases and tap prefixing, have been consolidated with new name tests into package_names.yml.

* Added changelog fragment.

* homebrew: replace non-py2 compliant f-string usage

* code formatting lint, and py2 compatibility fixes

* homebrew: added licenses to new files, nox lint

* Update plugins/modules/homebrew.py

use str.format() instead of string addition

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update tests/integration/targets/homebrew/tasks/casks.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update tests/integration/targets/homebrew/tasks/package_names_item.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update tests/integration/targets/homebrew/tasks/formulae.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Fixes for performance concerns on new homebrew tests.
1) tests for alternate package names are commented out in main.yml.
2) the "install via alternate name, uninstall via base name" test
   case was deemed duplicative, and has been deleted .
3) minor fixes to use jinja2 "~" for string concat instead of "+"

* Fix nox lint

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
brad2014 2025-09-15 18:26:01 +02:00 committed by GitHub
commit 833e6e36de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 146 additions and 58 deletions

View file

@ -385,12 +385,13 @@ class Homebrew(object):
self.outdated_packages.add(package_name)
def _extract_package_name(self, package_detail, is_cask):
# "brew info" can lookup by name, full_name, token, full_token, or aliases
# In addition, any name can be prefixed by the tap.
# Any of these can be supplied by the user as the package name. In case
# of ambiguity, where a given name might match multiple packages,
# formulae are preferred over casks. For all other ambiguities, the
# results are an error. Note that in the homebrew/core and
# "brew info" can lookup by name, full_name, token, full_token,
# oldnames, old_tokens, or aliases. In addition, any of the
# above names can be prefixed by the tap. Any of these can be
# supplied by the user as the package name. In case of
# ambiguity, where a given name might match multiple packages,
# formulae are preferred over casks. For all other ambiguities,
# the results are an error. Note that in the homebrew/core and
# homebrew/cask taps, there are no "other" ambiguities.
if is_cask: # according to brew info
name = package_detail["token"]
@ -405,15 +406,26 @@ class Homebrew(object):
#
# Issue https://github.com/ansible-collections/community.general/issues/10012:
# package_detail["tap"] is None if package is no longer available.
tapped_name = [package_detail["tap"] + "/" + name] if package_detail["tap"] else []
aliases = package_detail.get("aliases", [])
package_names = set([name, full_name] + tapped_name + aliases)
#
# Issue https://github.com/ansible-collections/community.general/issues/10804
# name can be an alias, oldnames or old_tokens optionally prefixed by tap
package_names = {name, full_name}
package_names.update(package_detail.get("aliases", []))
package_names.update(package_detail.get("oldnames", []))
package_names.update(package_detail.get("old_tokens", []))
if package_detail['tap']:
# names so far, with tap prefix added to each
tapped_names = {package_detail["tap"] + "/" + x for x in package_names}
package_names.update(tapped_names)
# Finally, identify which of all those package names was the one supplied by the user.
package_names = package_names & set(self.packages)
if len(package_names) != 1:
self.failed = True
self.message = "Package names are missing or ambiguous: " + ", ".join(str(p) for p in package_names)
self.message = "Package names for {name} are missing or ambiguous: {packages}".format(
name=name,
packages=", ".join(str(p) for p in package_names),
)
raise HomebrewException(self.message)
# Then make sure the user provided name resurface.