Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can we move apps instead of symlinking them? #3083

Closed
szhu opened this issue Feb 21, 2014 · 16 comments
Closed

Can we move apps instead of symlinking them? #3083

szhu opened this issue Feb 21, 2014 · 16 comments

Comments

@szhu
Copy link
Contributor

szhu commented Feb 21, 2014

Symlinking apps doesn't seem to be a good way to install "draggable" apps, and installing apps directly in the destination is probably a better idea.

Here are some issues with using symlinks:

  • Doesn't work properly with launchers. A command needed to be built just to accommodate Alfred. Quicksilver treats Cask-installed symlinks as files (Open With doesn't work), and I assume a fix would not be straightforward.
  • Some users might want to use various apps' self-updaters (Sparkle, etc.). After these apps update, they won't match the version number of the folder Cask installed them in.
  • Users don't usually want to keep around multiple versions of the same app anyway, so installing them in versioned folders isn't necessary. (Besides, the de-facto way to install different versions side by side is to rename older apps AppName (versionnumber).app.)
  • Apps that weren't meant to be installed by Cask might crash. (GitHub crashes for me when it tries to install a helper tool.)
  • Also an annoying symlink/alias icon in Finder that reminds me of Windows…

Here are some (additional) reasons why directly installing is a better idea:

  • Freedom to manipulate installed content outside of Cask. (Moved apps can still be located by their bundle IDs. The Mac App Store does this well.)
  • Freedom to start or stop using Cask at any time. Cask-install apps should be identical to manually installed ones. (Cask can display a notice/confirmation for apps removed manually or apps installed manually that the user has requested to manipulate with Cask, and that would be more than enough.)
  • Per-user installs would be easier if there are no traces of installs left in a system-wide location.
  • Consistency within Cask. Cask doesn't change where .pkg installers install their stuff.
  • Familiarity. There's no reason apps have to be installed in their own folder, so why confuse users? In fact, if Cask can install apps the normal way, it would be something I could recommend to my non technically inclined friends.

However, symlinking is a good solution for pretty much everything that isn't an bundle — this is why Homebrew works so well — and for apps like Eclipse and Audacity that require their data to be outside the bundle but the same containing folder.

The gist of all this is that Mac Apps were made to be manipulated directly by the user, and Cask does not work well with this. Cask should instead augment the Mac app management experience, instead of restricting it.

@szhu
Copy link
Contributor Author

szhu commented Feb 21, 2014

Also, usually apps receive self-updates before someone publishes it on Cask. Cask should check version numbers (because, again, OS X bundles contain this information) and make sure that it doesn't unintentionally downgrade.

@alebcay
Copy link
Member

alebcay commented Feb 21, 2014

The biggest reason apps are symlinked right now instead of moved/copied as the default (that I can tell) is the ability to have multiple versions of an app installed. I don't think there's a "select" function (as in like port select - if Homebrew had that, it would be awesome) to go back to a previous version of an app (not without checking out old versions of a file, but that'll only get overwritten with an update).

@szhu
Copy link
Contributor Author

szhu commented Feb 21, 2014

Most apps have the version number 'latest' anyway — can we make this happen for at least those apps?

@vitorgalvao
Copy link
Member

This is done for ideological reasons, so it is unlikely to change. This is not to say you don’t make some good points, but you’re also missing a lot of others. Homebrew-cask has evolved beyond much more than what it started as, so this question might need to be revisited, but this is not a trivial change at all. The homebrew- part in the name means that a lot of functionality comes from homebrew itself (which makes technical reasons a consideration as well), and naturally some of the things that come attached to it make more sense than others. In addition, this project has an already considerable user base, so even though it’s not yet even at 1.0, a change like this needs thought (even considering just linking there is a strong divide between people who prefer linking to ~/Applications and the ones who prefer /Applications).

Many of the points you mention are or have been already discussed/resolved. Usually I’d try to find them and link to the appropriate discussions, but there are so many points here that it’d be more productive to point them out in a per-case basis for points you might wish to discuss further, as trying to address each of your concerns was leaving me with an (even more) unmanageable wall of text.

However, I’d like to briefly address the point in your last comment.

Most apps have the version number 'latest' anyway

From my quick check, this seems to be the case for less than (but close to) half, not most, and this may not always be the case, as we’re discussing changing that.

can we make this happen for at least those apps?

That is a bad idea, and you’ve already explained why in your first post.

Consistency within Cask

Even though your point was made for a different case, it applies even stronger here, as you’re suggesting an arbitrary change in certain casks, that would be invisible and incomprehensible to most users, even more than your familiarity point (I don’t recall a single user being confused by seeing a symlink instead of an app; and would be surprised to see it from one that can use this project in its current form — CLI-only). Homebrew-cask does not change what happens with .pkg installers because there’s no good way to do it.

This approach has merits to it, as does your suggestion, but in some places your wording sounds more like what you wish homebrew-cask did, as opposed to what would be better for it to do. This is in no way a condemnation — this kind of project is born out of being unsatisfied about how things work, so it can definitely be a good thing. For a long time I even used a script to do what you ask, as I also disliked the linking approach. Having said that, there are a lot of good decisions here, and they always take the community into account, so I urge you to stick around, as new ideas are well received.

@szhu
Copy link
Contributor Author

szhu commented Feb 22, 2014

Thanks for the response, it explains a lot of things.

How feasible do you think would it be to have persistent install settings? These would include:

  • whether to move, symlink, or not link at all
  • user preferences for --appdir, --binarydir, etc.

I feel like having the option to override the defaults is not a bad idea, since scripts can always specify them explicitly. To avoid scripts from hardcoding the default settings something like --appdir=CASK_DEFAULT can be made.

But based on what you said, I feel like a postinstall script that replaces linking can actually take are of this and wouldn't require Cask to change at all. Does Cask have any postinstall hooks or anything like that?

Also, what is the current way to deal with Cask-versioned apps that are updated through non-Cask methods?

@Govan
Copy link

Govan commented Mar 4, 2014

Doesn't work properly with launchers. A command needed to be built just to accommodate Alfred. Quicksilver treats Cask-installed symlinks as files (Open With doesn't work), and I assume a fix would not be straightforward.

One can add the Caskroom directory to the search paths for Alfred (and I suspect Quicksilver) instead of ~/Application to make the apps runnable again.

I realise this isn't directly related to resolving the issue, but it was the first problem I encountered with Cask and I suspect it'll be a pain-point for many adopters.

@szhu
Copy link
Contributor Author

szhu commented Mar 5, 2014

Thanks Govan. I realize this is adequate workaround for some people, but I have a few problems with this. In short, this doesn't work because /opt/… is ugly and because I have custom apps in ~/Applications. I'll elaborate below if it's not clear.


One minor problem is that Quicksilver displays paths to things, and /opt/… doesn't look very nice:

screen shot 2014-03-04 at 5 59 57 pm screen shot 2014-03-04 at 6 00 02 pm
before after

The bigger problem is that I need ~/Applications (or for me, /Users/Shared/Applications) in my search path. Not every app I install is mainstream enough to be included in Cask, and sometimes I make modifications to them that I would like to not be overridden. For those who think I'm some weird edge case user, here are some examples:

  • GitHub will crash when trying to install a helper tool unless it's moved outside the Caskroom.
  • Apple's Developer apps like Icon Composer and Quartz Debug can't be on Cask because downloading them requires an Apple Developer login.
  • Some other apps are not on Cask yet: Xee, Spark, YouView.

This means I have to include both paths in app launchers, so I'm left with this:
screen shot 2014-03-04 at 6 17 08 pm


My point here is the Cask makes too many assumptions about your setup and you're forced to choose between two extremes — either manage all your apps with Cask or face a barrage of duplicates. In fact, the more apps you do manage with Cask, the more duplicates you'll have!

If this were an inherent problem with OS X or Homebrew, I'd stop talking now. But I believe that this can be easily fixed with a Cask external command that will move installed apps outside the Caskroom (while still keeping track of them!). This is something I plan to make soon, and the only thing it might depend on is requiring app IDs in Cask formulae.

@alebcay
Copy link
Member

alebcay commented Mar 5, 2014

As aforementioned, adding the Caskroom path to Alfred, in particular, is pretty easy:

brew cask alfred link

(and with the latest Homebrew-Cask update, it's actually working now).

I think the problem you mentioned regarding duplicates plagues Homebrew and MacPorts as well. Homebrew encourages you to deal with it by putting /usr/local/bin at the front of your path, while MacPorts has port select to let you choose a version. I personally like MacPorts' approach better, since I can have three versions of gcc on my machine at once, rather than them getting symlinked over each other.

Taking a look at Homebrew-Cask's approach, there's no good way to swap symlinks that I can think of (unless you rename/make backups of existing symlinks and then rename/move them back during uninstallation). If you try to use MacPorts' method, you could let the user switch which app to use (with some select method or sorts), moving the inactive apps hopefully into somewhere where app launchers won't find them.

Also, there are Casks available for Xee and YouView at this point; I'm working on one for Spark.

@szhu
Copy link
Contributor Author

szhu commented Mar 5, 2014

Homebrew and other command line tool symlinks don't bother me as much, since symlinking is standard practice. It's not standard for OS X apps to be symlinked, and simply because of that, using symlinks is bound to break things.

In addition (and probably partially why it's nonstandard), it would be hard for app launchers and other tools that must keep an index to keep track of symlinks, especially when the referent changes (i.e., when Cask upgrades an app).

And I haven't brew updated in a few days so I didn't notice Xee and YouView. Thanks for adding them! By the way, can you also add Xee 2.2, the one that doesn't require my money?

@vitorgalvao
Copy link
Member

I don’t really feel saying “not every app I install is mainstream enough to be included in Cask” is a fair criticism. If there’s an app you want in homebrew-cask and it’s not here still, even if you do not want to add it yourself, opening a simple issue with a request will suffice. I’ve added (and seen other contributors submit) requested casks mere minutes after they’ve been asked for.

Regarding moving apps from the Caskroom to your Applications directory, it should be simple enough to do externally, and as I’ve pointed out on my previous comment. It has been done (maybe it does not work anymore, since it’s no longer maintained, but it worked well when I relied on it).

On another note, I hadn’t noticed that xee version is paid (and perhaps @alebcay hadn’t as well). I made the specific request for that version, as he had originally submitted the one you’re asking for. However, seeing as it is an older version, it should be included in caskroom versions.

I likely overlooked something here — why exactly are you having duplicates? Homebrew-cask does not force you to manage any of your apps with it, it stays out of the way of apps installed manually. As stated, it does not move your apps to /Applications in part due to ideology, and a lot of (most?) users prefer it like that. Yes, there are issues that come from that, but they are being solved. For example, some apps, when first opening them, will complain if they are not in /Applications — to those casks is usually added a command that will suppress that message, so the user never needs to be bothered with it. There are reasons for the current approach, both technical and ideological.

Again, you make good points but in some of your arguments it seems like you’re talking about what you wish homebrew-cask did, as opposed to what would be better for it to do. I urge you to not only try to push this change, but to expose the problems you encounter as project issues (as in github issues, like this one). You’re offering up your specific problems and one solution that you feel is the best; maybe it is not. If, however, you open new issues with those problems, you’ll have a number of eyes and minds on that problem that will try to solve it, which will in turn make the project better and solve your troubles, even if not applying your proposed solution.

Again, please realise there’s a reason for it to work the way it does. Will your solution solve some of the existing problems? Yes. Will it also cause new ones? Yes. This is not a simple change that can be made in a few lines and solve everything. It has to be considered and evaluated. You’ve exposed the troubles you’ve encountered, and proposed a solution. Believe that it is appreciated. This issue, however, is focused on that proposed method, instead of the problems. The next step is for you to open new issues in the appropriate place so we can look at them individually and solve them for you and every other user.

@alebcay
Copy link
Member

alebcay commented Mar 5, 2014

I've made a pull request in caskroom/versions for xee22.

@szhu
Copy link
Contributor Author

szhu commented Mar 5, 2014

Regarding apps that can't be on Cask, I see now that obscure apps can be on Cask too, and I'm impressed by the speed of the submission process. I'll stop talking about Xee and Spark and friends in this issue.

However, I stand by my point that apps with custom modifications and non-free licenses cannot be Cask-managed. This means that my ~/Applications will contain both Cask-managed and manually-installed apps.

When I talked about duplicates, I meant that Quicksilver will show two instances of the same app. I cannot remove the Caskroom one because it is the fully functional one, and I cannot remove the ~/Applications one because I have non-Cask apps in ~/Applications. It's probably Quicksilver's fault that it treats symlinks this way, but I think symlink support by OS X apps is disparate enough that fixing Quicksilver won't fix the entire problem.

Thanks for suggesting that I should probably raise issues about problems rather than proposed enhancements. (I only mentioned possible solutions because I'm used to thinking that complaining about issues without offering fixes is not a good way to do things, but I forget that this works differently.) The next time you'll hear from me about an enhancement for these problems will probably be when I actually make it.

Thanks to the discussion above, it looks like these are the only relevant problems. Thanks for helping me narrow this down.

  • No quick way to move apps out of the Caskroom (your script kind of does this but it's not very robust and can't be run after brew cask install, I think)
  • Casks (I understand this is an issue already but I can't find where)
  • Quicksilver handles symlinks badly

Finally, thanks for your extended replies, and for finding links to the issues I mentioned. It's much appreciated.

@vitorgalvao
Copy link
Member

I might be overlooking something again (there’s already so much text in this issue, that we’re bound to lose track of some things). Why do you say apps with non-free licenses cannot be “Cask-managed”? We have a bunch of commercial apps in the project. As long as you can insert a license on the version downloaded via homebrew-cask to make it full, it’s accepted. Furthermore, how would moving apps directly to /Applications change that, or help with apps with custom modifications? If it updated and replaced the version in /Applications, it’d overwrite your changes anyway. Custom modifications to apps would be very hard to manage since, by definition, custom modification are different for every user (it’s also a very niche need).

The duplication problem is a quicksilver issue, then, that’s an important detail. There’s no reason we shouldn’t look into it and try to tackle that as well, to provide a better experience. This is an example of a case where opening an issue would be much more beneficial than discussing it in this one. By doing that, you’re also getting the input of other users that might have insights into the problem.

I’ve never suggested you should “raise issues about problems rather than proposed enhancements”. My sentence is even bolded on my comment, where I clearly say “not only”, as in “you should do this in addition to”. The place where issues are raised is at the same time the place for proposing solutions. The point I’m trying to get across to you is that your solution is not an immediately viable option. You do not need to impose a fix, and you do not need to make one. What is asked of you is that you offer these issues for discussion appropriately. This is not a forum — problems are localised and discussions are contained, so we can address each case optimally. Look at the title of this issue — it’s a request/suggestion — contributors that do not care/do not have an opinion on it will likely not read through everything (or at all). Compare that to an issue titled “symlinking apps causes quicksilver to show duplicates”, where you expose not only the problem, but any other related detail — users that have gone through it (if there are any) will immediately be able to help, as will any number of other contributors that may have an insight on the problem.

By insisting on a solution that is not (at least currently) in line with the goals of the project, you are not solving your problem. By detailing your issues appropriately, you are (and not just for yourself). Maintain this issue, and let us discuss it, but at the same time expose each of the problems you encounter as separate issues, so we can solve them as well, even if by a different solution that is more in line with the project’s goals.

I’ve always tried to be cordial with you throughout this whole issue, while evaluating your points and explaining what works and doesn’t in tandem with the goals and philosophy for this project. If at any point you feel I’ve been unjust in any of my assessments, please feel free to be blunt about it.

@szhu
Copy link
Contributor Author

szhu commented Mar 5, 2014

I believe that apps included with Apple's hardware and graphics developer tools can't be distributed by Cask, since you need to log in with your Apple ID first.

I used Quicksilver as an example where symlinking isn't handled nicely, but I bet there are more such cases. As another example, symlinking creates an icon badge that can be obtrusive, especially when viewing 16×16 icons:
screen shot 2014-03-04 at 10 41 04 pm
What I'm getting at here is that the OS X GUI, unlike the command line, tends to treat symlinks as "not the real thing", and bet there are more examples of this.

Also, regardless of whether symlinking can be handled nicely, it could be beneficial to have an option to install apps in the same way they would manually be installed. This would make it more acceptable for users to forget which apps they installed via Cask. ("I want to get rid of this app … can I just trash this or do I have to cask uninstall? What was the formula name again?")

Having Cask installs be the same as manual installs would also make making custom modifications easier, since there could be a command (let's call it uncask) that tells cask to stop managing the app. Actually, this can probably be done even with symlinking, although it would be more complicated (since you have to move the app out of the caskroom before deleting the caskroom files).

Thanks for your advice regarding raising both issues and suggestions. I appear to misunderstood part of it again, and your clarification helps. And, just to be clear, I think you've been completely just and very helpful in your responses, so thanks again.

@vitorgalvao
Copy link
Member

We have a lot of text in this issue now, so it’s becoming a bit unlikely that new eyes will go through all of it to see the discussion. There’s a new issue where someone is offering to build this as an addition, so lets move the conversation there to see how we can actually do it, and get back to this if needed. Thank you for all the input.

@szhu
Copy link
Contributor Author

szhu commented Apr 18, 2014

That sounds like a good idea; thanks for linking to the new issue.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants