superatomic / homebrew-bundle-extensions

🗄 Command extensions for Homebrew that allow for easy modification of brew bundles.
https://gh.superatomic.dev/homebrew-bundle-extensions
BSD 2-Clause "Simplified" License
14 stars 2 forks source link

Add the ability to 'add' `mas` dependencies to Brewfile #4

Open boldandbrad opened 2 years ago

boldandbrad commented 2 years ago

Goal

Add the ability to add Brewfile lines of the following format: mas "name", id: 12345678

Assumptions

  1. The "name" value itself does not matter to mas for install, only the "id" does (mas install [ID])
  2. Recent versions of macOS prohibit mas from installing applications that have not been previously purchased/installed on a Mac by the active Apple ID - mas known issues

Potential Command Structures

Potential Params

Inspiration/Reference

superatomic commented 2 years ago

Thank you so much for this detailed write-up! This is very helpful.

In addition, dumping mas apps is also implemented here: mac_app_store_dumper.rb I'm not quite sure what the spec file is (it might be test cases?) but I tend to find that the implementations normally are in the lib/ directory.

superatomic commented 2 years ago

I think all three ways of specifying mas applications can work with the brew add command in general alongside formulae and casks by using a bit of special syntax. Since the colon (:) doesn't appear in any formula names, it's a perfect character to indicate a mas app.

The form of a mas app would be ID:NAME, or /^\d+:[^:]+$/ as a regular expression. In addition, we could also accept different segments of the full syntax, like :NAME to search for the id by name, or ID: to let the name be automatically filled in. And because the only formula/cask that is just numbers is the cask 7777, the trailing colon at the end of the ID could be optional, with priority being for the formulae and casks first.

For example, this line would add the mas app with the ID 1482454543, the mas apps named xcode and bear, and the casks 7777 and firefox to the Brewfile:

brew add 1482454543 497799835:xcode :bear 7777 firefox

To add the mas app with an ID of 7777 instead of the cask, both brew add --mas 7777 and brew add 7777: would work.


Now, this is just one way of solving it. The advantage of using the colon separator this way is that it allows for there to be no confusion about what is meant to be a mas app, and to me, removing sections of the full ID:NAME format to have them be filled in feels natural. It also allows for typing brew add ID in all cases except for app 7777, which doesn't actually appear to be a valid app.

If you have any different ideas or improvements to this one, please let me know. Also, I swapped the order of the ID and NAME just because :firefox looked better than firefox: to me, and because it kind of makes sense for the most important bit of information (the id) to come first. Tell me if you preferred it the other way around.

boldandbrad commented 2 years ago

I like your suggested implementation for a few reasons:

The only other things I'll note are...

boldandbrad commented 2 years ago

After digging a little bit through the whalebrew repo, I don't think we need to worry about our regex. It seems like whalebrew formulae don't include : and almost all of them start with whalebrew/ which would be fairly easy to catch aside from potential conflict with the homebrew whalebrew formulae itself. Either way, it shouldn't be a concern for this issue.

superatomic commented 2 years ago

Regarding supporting names in quotes, I believe the shell itself can already handle that. By putting single quotes, double quotes, or escaping spaces, the name will be interpreted as one name once it is received by the argument parser.

For example, with current functionality, typing any of these:

brew add :"Canary Mail"
brew add :'Canary Mail'
brew add :Canary\ Mail
brew add :Canary' 'Mail
brew add ':Canary Mail'

Outputs the same exact error message:

Error: No available formula with the name ":canary mail".

Built-in commands like brew install also behave in the same way.