rcmdnk / homebrew-file

Brewfile manager for Homebrew
http://homebrew-file.readthedocs.io/
MIT License
356 stars 29 forks source link

brew init fails if there is an app installed with a single quote (') in the title #302

Open coma-toast opened 3 days ago

coma-toast commented 3 days ago

When attempting to set up using the instructions, I continually received the following error:

Do you want to set a repository (y)? ((n) for local Brewfile). [y/n]: n
Traceback (most recent call last):
  File "/usr/local/bin/brew-file", line 3970, in <module>
    sys.exit(main())
             ~~~~^^
  File "/usr/local/bin/brew-file", line 3957, in main
    b.execute()
    ~~~~~~~~~^^
  File "/usr/local/bin/brew-file", line 3278, in execute
    _ = self.initialize()
  File "/usr/local/bin/brew-file", line 2408, in initialize
    self.get_installed_packages()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/bin/brew-file", line 2214, in get_installed_packages
    "appstore_list", self.get_appstore_list()
                     ~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/bin/brew-file", line 2103, in get_appstore_list
    f"{v[0]} {k} {v[1]}" for k, v in self.get_appstore_dict().items()
                                     ~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/bin/brew-file", line 2086, in get_appstore_dict
    _, lines = self.helper.proc(
               ~~~~~~~~~~~~~~~~^
        f"mdls -attr kMDItemAppStoreAdamID -attr kMDItemVersion '{a}'",
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        print_cmd=False,
        ^^^^^^^^^^^^^^^^
        print_out=False,
        ^^^^^^^^^^^^^^^^
    )
    ^
  File "/usr/local/bin/brew-file", line 241, in proc
    cmd = shlex.split(cmd)
  File "/usr/local/Cellar/python@3.13/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/shlex.py", line 313, in split
    return list(lex)
  File "/usr/local/Cellar/python@3.13/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/shlex.py", line 300, in __next__
    token = self.get_token()
  File "/usr/local/Cellar/python@3.13/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/shlex.py", line 109, in get_token
    raw = self.read_token()
  File "/usr/local/Cellar/python@3.13/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/shlex.py", line 191, in read_token
    raise ValueError("No closing quotation")

I attempted several steps from other issues in this repo, but nothing worked. Further investigation it appears that the get_appstore_dict doesn't account for ' characters in the App title. /Applications/Alto's Adventure The Spirit of the Mountain.app was causing the variable a to truncate early, it seems.

It might be an easy fix, using shlex.quote(a) like so:

    def get_appstore_dict(self) -> dict[str, list[str]]:
        apps: dict[str, list[str]] = {}
        _, apps_tmp = self.helper.proc(
            "mdfind 'kMDItemAppStoreHasReceipt=1'",
            print_cmd=False,
            print_out=False,
        )
        for a in apps_tmp:
            escaped_app_path = shlex.quote(a)
            if not a.endswith(".app"):
                self.log.warning(f"Incorrect app name in mdfind: {escaped_app_path}")
                continue
            if not Path(escaped_app_path).is_dir():
                self.log.warning(f"App doesn't exist: {escaped_app_path}")
                continue
            _, lines = self.helper.proc(
                f"mdls -attr kMDItemAppStoreAdamID -attr kMDItemVersion '{escaped_app_path}'",
                print_cmd=False,
                print_out=False,
            )
            app = {
                x.split("=")[0].strip(): x.split("=")[1].strip() for x in lines
            }
            app_id = app["kMDItemAppStoreAdamID"]
            if app_id != "(null)":
                app_name = escaped_app_path.split("/")[-1].split(".app")[0]
                app_version = app["kMDItemVersion"].strip('"')
                apps[app_name] = [app_id, f"({app_version})"]
        return apps

App list:

Screenshot 2024-11-17 at 6 03 28 PM

Error:

Screenshot 2024-11-17 at 6 05 07 PM

I tested by uninstalling Alto's Adventure, and the brew init was able to complete successfully. I then reinstalled the app and re-initialized with those changes and it was able to complete without the error:

Screenshot 2024-11-17 at 6 14 27 PM
rcmdnk commented 3 days ago

@coma-toast Thanks for the report. It should be fixed in v10.0.2.

Could you please try update brew-file and run commands?