Skip to content

fix: parse packages with a brew "version" correctly.#1601

Open
morrison12 wants to merge 1 commit intopyinfra-dev:3.xfrom
morrison12:brew-fixes-2026-02
Open

fix: parse packages with a brew "version" correctly.#1601
morrison12 wants to merge 1 commit intopyinfra-dev:3.xfrom
morrison12:brew-fixes-2026-02

Conversation

@morrison12
Copy link
Copy Markdown
Contributor

brew.BrewPackages (and thus brew.BrewCasks by inheritance ignores the '@' separator that brew uses even though the separator is used by brew.packages (see /1/). This causes the "versions" of the formulae or cask to be reported as separate formulae or casks instead of multiple versions of a single formula or cask (see /2/) and extraneous install attempts (see Detected changes part of /2/). With the fix applied, there are multiple versions of a single formula or cask and no install attempt (see /3/).

  • Pull request is based on the default branch (3.x at this time) and started with 3.7 despite the version shown at /3/ !?!
  • Pull request includes tests for any new/updated operations/facts
  • [n/a] Pull request includes documentation for any new/updated operations/facts
  • Tests pass (see scripts/dev-test.sh)
  • Type checking & code style passes (see scripts/dev-lint.sh)

/1/

upgrade_command="brew upgrade",
version_join="@",
latest=latest,

/2/

+ pyinfra --version
pyinfra: v3.7
+ brew list --versions
+ grep openssl
openssl@1.1 1.1.1w
openssl@3 3.6.1
+ pyinfra @local fact brew.BrewPackages
+ grep openssl -A 3
        "openssl@1.1": [
            "1.1.1w"
        ],
        "openssl@3": [
            "3.6.1"
        ],
        "opus": [
+ pyinfra --dry @local brew.packages openssl@3.6.1
--> Loading config...
--> Loading inventory...
--> Connecting to hosts...
    [@local] Connected

--> Preparing operation func...
    [@local] Ready: packages

--> Detected changes:
    Operation                       Change       Conditional Change
    brew.packages (openssl@3.6.1)   1 (@local)   -

    Detected changes may not include every change pyinfra will execute.
    Hidden side effects of operations may alter behaviour of future operations,
    this will be shown in the results. The remote state will always be updated
    to reflect the state defined by the input operations.

--> Disconnecting from hosts...

/3/

+ pyinfra --version
pyinfra: v3.6
+ brew list --versions
+ grep openssl
openssl@1.1 1.1.1w
openssl@3 3.6.1
+ pyinfra @local fact brew.BrewPackages
+ grep openssl -A 3
        "openssl": [
            "1.1.1w",
            "3.6.1"
        ],
+ pyinfra --dry @local brew.packages openssl@3.6.1
--> Loading config...
--> Loading inventory...
--> Connecting to hosts...
    [@local] Connected

--> Preparing operation func...
    [@local] Ready: packages

--> Detected changes:
    Operation                       Change   Conditional Change
    brew.packages (openssl@3.6.1)   -        -

    Detected changes may not include every change pyinfra will execute.
    Hidden side effects of operations may alter behaviour of future operations,
    this will be shown in the results. The remote state will always be updated
    to reflect the state defined by the input operations.

--> Disconnecting from hosts...

Copy link
Copy Markdown
Member

@Fizzadar Fizzadar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is the right fix since brew uses @ for distinct formula (eg python@3.13, python@3.14). I think we'd be better off fixing this on the operation side though I'm unsure how 🤔

@morrison12
Copy link
Copy Markdown
Contributor Author

I'm not sure this is the right fix since brew uses @ for distinct formula (eg python@3.13, python@3.14). I think we'd be better off fixing this on the operation side though I'm unsure how 🤔

The current change works to add a version of, for example, python (see /1/ below) but unfortunately removing doesn't work which (see /2/ below) . As an aside, it also doesn't work without this change (see /3/) although without the error message.

In terms of changing the operation, removing the version_join definition from the call to ensure_package might do the trick. Will try that and see what else, if any, is needed.

/1/

(venv) machine user$ pyinfra @local fact brew.BrewPackages 2>&1 | grep python -A 3
        "python": [
            "3.12.13",
            "3.13.13",
            "3.14.4"
(venv) machine user$ pyinfra @local brew.packages python@3.10 present=True
--> Loading config...
--> Loading inventory...
--> Connecting to hosts...
    [@local] Connected

--> Preparing operation func...
    [@local] Ready: packages

--> Detected changes:
    Operation                                   Change       Conditional Change
    brew.packages (python@3.10, present=True)   1 (@local)   -

    Detected changes may not include every change pyinfra will execute.
    Hidden side effects of operations may alter behaviour of future operations,
    this will be shown in the results. The remote state will always be updated
    to reflect the state defined by the input operations.

    Detected changes displayed above, skip this step with -y

--> Beginning operation run...
--> Starting operation: brew.packages (python@3.10, present=True)
    [@local] Success

--> Results:
    Operation                                   Hosts   Success   Error   No Change
    brew.packages (python@3.10, present=True)   1       1         -       -
    Grand total                                 1       1         -       -

--> Disconnecting from hosts...
(venv) machine user$ pyinfra @local fact brew.BrewPackages 2>&1 | grep python -A 4
        "python": [
            "3.10.20",
            "3.12.13",
            "3.13.13",
            "3.14.4"


/2/
(venv) machine user$ pyinfra  @local brew.packages python@3.10.20 present=False
--> Loading config...
--> Loading inventory...
--> Connecting to hosts...
    [@local] Connected

--> Preparing operation func...
    [@local] Ready: packages

--> Detected changes:
    Operation                                       Change       Conditional Change
    brew.packages (python@3.10.20, present=False)   1 (@local)   -

    Detected changes may not include every change pyinfra will execute.
    Hidden side effects of operations may alter behaviour of future operations,
    this will be shown in the results. The remote state will always be updated
    to reflect the state defined by the input operations.

    Detected changes displayed above, skip this step with -y

--> Beginning operation run...
--> Starting operation: brew.packages (python@3.10.20, present=False)
    [@local] Error: No available formula with the name "python@3.10.20". Did you mean python@3.12, python@3.10, python@3.14, python@3.13 or python@3.11?
    [@local] Error: executed 0 commands

--> Disconnecting from hosts...
--> pyinfra error: No hosts remaining!

/3/
(venv) machine user$ pyinfra  @local brew.packages python@3.10.20 present=False
--> Loading config...
--> Loading inventory...
--> Connecting to hosts...
    [@local] Connected

--> Preparing operation func...
    [@local] Ready: packages

--> Detected changes:
    Operation                                       Change   Conditional Change
    brew.packages (python@3.10.20, present=False)   -        -

    Detected changes may not include every change pyinfra will execute.
    Hidden side effects of operations may alter behaviour of future operations,
    this will be shown in the results. The remote state will always be updated
    to reflect the state defined by the input operations.

    Detected changes displayed above, skip this step with -y

--> Beginning operation run...
--> Starting operation: brew.packages (python@3.10.20, present=False)
    [@local] No changes

--> Results:
    Operation                                       Hosts   Success   Error   No Change
    brew.packages (python@3.10.20, present=False)   1       -         -       1
    Grand total                                     1       -         -       1

--> Disconnecting from hosts...
(venv) machine user$ pyinfra @local fact brew.BrewPackages 2>&1 | grep python -A 4
        "python@3.10": [
            "3.10.20"
        ],
        "python@3.12": [
            "3.12.13"
        ],
        "python@3.13": [
            "3.13.13"
        ],
        "python@3.14": [
            "3.14.4"
        ],

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants