quicksilver / Quicksilver

Quicksilver Project Source
http://qsapp.com
Apache License 2.0
2.73k stars 285 forks source link

Symlinked sources aren't updated when target changes #2758

Closed toonn closed 2 years ago

toonn commented 2 years ago

Before submitting your bug report, please confirm you have completed the following steps

Bug description

Selecting a symbolic link as a source in the catalog resolves it to the absolute path. Manually editing the Catalog.plist doesn't help either, it doesn't seem to work at all (using ~/symlink/Applications).

Steps to reproduce

  1. Add a symlinked directory as a source.
  2. Scan the source.
  3. Change the symlinks target.
  4. Observe QS not updating the source.

Expected behavior

When the target changes the source should be rescanned.

MacOS Version

Other

Quicksilver Version

1.6.0

Relevant Plugins

No response

Crash Logs or Spindump

No response

Screenshots

No response

Additional info

I'm on macOS 10.13.6 High Sierra. And no, I did not actually run the latest version of QS, I don't think my version of macOS is supported anymore, if that's not the case then there was another reason I chose to stick to 1.6.0.

Please don't close this issue because of the old system and QS versions though because some of the people in #2459 are probably running the latest system and QS.

My usecase for this is I install software using the nix package manager. It symlinks a generation into my home directory but it keeps older generations around. Since QS only looks at the absolute path it keeps searching the old generation.

As a workaround I use home-manager and then link to all the apps installed by it (in ~/.nix-profile/Applications) from ~/ApplicationsNix. The idea is that you can point Quicksilver to that directory because it's not a symlink. However, checking my catalog sources I can only find /Applications and ~/Applicationsand running apps, the latter might be why I haven't noticed it not working.

The linking's done using the following snippet:

{
  home.activation.linkApps = config.lib.dag.entryAfter [ "writeBoundary" ]
    (pkgs.stdenv.lib.strings.optionalString pkgs.stdenv.isDarwin
      ''
        for app in $HOME/.nix-profile/Applications/*.app;
        do ln -sf $app $HOME/ApplicationsNix;
        done
      '');
}
pjrobertson commented 2 years ago

Thanks for re-creating the bug report. It's possible that this was fixed in a more recent version of Quicksilver.

I'm still not able to test this full though. Can you please edit the above post and update the 'Steps to reproduce' section.

Specifically: how are you creating the symlink in the first place? how are you adding a symlinked folder to Quicksilver? how are you changing the symlink target?

toonn commented 2 years ago
  1. ln -s some/source my-source-link
  2. In QS settings select Catalog, then add a file and folder scanner and choose my-source-link
  3. Rescan sources, apps from some/source should show up now.
  4. ln -sf some/other/source my-source-link
  5. Rescan sources, apps from some/source still show up.
n8henrie commented 2 years ago

@pjrobertson -- do you have / use nix (or guix or something similar)? It seems like that's the use case in question and may be somewhat hard to conceptualize unless you've used it. There are tons of constantly updating symlinks that determine your environment (and allow for trivial rollbacks and other interesting features). I'm a nix novice so hopefully I'm not explaining things too poorly.

So for me:

$ stat ~/.nix-profile
  File: /Users/n8henrie/.nix-profile -> /nix/var/nix/profiles/per-user/n8henrie/profile
  Size: 47              Blocks: 0          IO Block: 4096   symbolic link
Device: 1,17    Inode: 58821664    Links: 1
Access: (0755/lrwxr-xr-x)  Uid: (  501/n8henrie)   Gid: (   20/   staff)
Access: 2021-11-02 08:29:26.649986378 -0600
Modify: 2021-11-02 08:29:26.649986378 -0600
Change: 2021-11-02 08:29:26.650151626 -0600
 Birth: 2021-11-02 08:29:26.649986378 -0600
$ realpath ~/.nix-profile
/nix/store/0hggqnn0k6vnyy17hpywa7xg4sqdlf7l-user-environment
$ nix-env -iA nixpkgs.hello
installing 'hello-2.12'
these 3 paths will be fetched (0.15 MiB download, 0.97 MiB unpacked):
  /nix/store/0fyfc4qyk6cxdcvij9bi3lnq7p1xn2nr-libobjc-11.0.0
  /nix/store/2d945lscszphcdaynvifii4klnifbh63-apple-framework-CoreFoundation-11.0.0
  /nix/store/ws6rbnp9z3ga4v58j4qja0lypr1rrh8f-hello-2.12
copying path '/nix/store/0fyfc4qyk6cxdcvij9bi3lnq7p1xn2nr-libobjc-11.0.0' from 'https://cache.nixos.org'...
copying path '/nix/store/2d945lscszphcdaynvifii4klnifbh63-apple-framework-CoreFoundation-11.0.0' from 'https://cache.nixos.org'...
copying path '/nix/store/ws6rbnp9z3ga4v58j4qja0lypr1rrh8f-hello-2.12' from 'https://cache.nixos.org'...
building '/nix/store/abm7lwffgyxpcgd069rz7zj92w2lr12g-user-environment.drv'...
$ realpath ~/.nix-profile
/nix/store/x6s1nzwr60nwiba4rqffjx54wgqyl7i1-user-environment

The important part is that just installing a package changes my ~/.nix-profile symlink, which facilitates things like:

$ nix-env --rollback
switching profile from version 6 to 5

which just changes the symlink back and my environment is back to where I started.

This is kind of difficult in Quicksilver because adding anything to the catalog resolves the symlink during the process of adding it to the catalog.

So for example, if I try to add ~/.nix-profile/Library (or .../Applications as per above), whenever I go to catalog, hit the + button, then navigate to ~/.nix-profile, MacOS has already resolved ~/.nix-profile to /nix/store/....

This is undesirable behavior, because what @toonn wants is for Quicksilver to keep ~/.nix-profile/Library in the catalog, and scan "whatever it links to right now."

Does that make sense?

Same problem if I try select ~/.nix-profile/Library from the CLI and use the "add to catalog" action:

EDIT: Actually this seems to work. Another reply in process.

$ qs ~/.nix-profile/Library
Screen Shot 2022-05-02 at 14 27 16

@toonn -- can you try something? I don't use nix enough to really know if this would work, but try the following:~

EDIT: Skip this

  1. Back up ~/Library/Application Support/Quicksilver/Catalog.plist
  2. Add a relevant nix directory to your catalog, such as ~/.nix-profile/Applications, using the usual interface
  3. Open ~/Library/Application Support/Quicksilver/Catalog.plist in your favorite editor, search for /nix/store, and you should fine the entry you just added, e.g.:
    <key>path</key>
    <string>/nix/store/wc486slv44h6zm9fjv8zkq42b3rdrdn6-nix-2.5pre20211007_844dd90/Applications</string>
  4. Manually edit /nix/store/... -> ~/.nix-profile/Applications

Does that work? Make sure you select the appropriate options in the catalog editor (such as including children, depth, etc). It seems to work for me with a very simple test, but I might be missing something.

n8henrie commented 2 years ago

I was wrong, it looks like adding the symlink via the "Add to Catalog" option works as expected and resolves this issue for me -- sorry I hadn't initially tested as thoroughly.

@toonn @Jurek-Raben can you try below and see if this works?

  1. Select the catalog entry in question in Quicksilver. It should show the little black arrow indicating that QS knows it's a symlink, like in my screenshot above.
  2. Use the "Add to Catalog" action
  3. Adjust your options in the QS Catalog preferences (depth, contents, etc).
  4. Verify that it seems to be working

For me, this process appropriately leaves e.g. ~/.nix-profile/Library as the path in the QS preferences:

$ grep nix ~/Library/Application\ Support/Quicksilver/Catalog.plist
                                <string>/Users/n8henrie/.nix-profile/Library</string>

I think the problem arises when using the + to add the item in the Catalog Preferences interface, because MacOS (not QS) resolves the symlink before it ever gets to QS.

toonn commented 2 years ago

I can't seem to navigate to a hidden directory unfortunately, so I can't select ~/.nix-profile or anything in it to run the "Add to Catalog" action on.

Note that I have tried to manually edit the Catalog plist, I am of course stuck on an older version so it may very well be possible this is fixed in newer versions.

n8henrie commented 2 years ago

I can't seem to navigate to a hidden directory unfortunately, so I can't select ~/.nix-profile or anything in it to run the "Add to Catalog" action on.

Two options:

EDIT: I recommend the first approach, the qs tool is handy!

toonn commented 2 years ago

Toggling visibility of hidden files and folders when selecting the source doesn't help because Finder (presumably) still resolves the symlinked path.

I don't seem to have a qs binary and can't find it in the QuickSilver.app either. Can't seem to find mention of it on the site or through searches either. How could I go about installing it? Maybe it's just not included in 1.6.0?

n8henrie commented 2 years ago

I don't seem to have a qs binary and can't find it in the QuickSilver.app either

See above: "install the Quicksilver command line tool"

https://qsapp.com/manual/plugins/commandlinetool/

10.13 should be fine

You'll need to install the plugin, then go to prefs -> general -> command line tool -> install

But you don't need to go through this, you should also just be able to put the path into your first pane in text mode.

For example, with my setup:

  1. Use . to enter text mode
  2. Type in ~/.nix-profile/Library (or in your case .../Applications)
  3. Note that the background image turns into a folder, showing that QS recognizes this as a path that exists on my filesystem
  4. Hit tab to resolve the text into the file object and advance to the actions pane
  5. Add to catalog
  6. Return
toonn commented 2 years ago

With those detailed (thank you!) instructions I managed to go through the steps. The path does get added to the Catalog just fine. However, no results from inside the path are added in the list of matches. I think that confirms that this doesn't work in 1.6.0 but that it has been, at least somewhat, fixed in later versions.

The file picker resolving symlinks remains an outstanding problem though, IIRC?

n8henrie commented 2 years ago

However, no results from inside the path are added in the list of matches.

Huh, let's walk through an example case just to be sure. Were you able to install the QS command-line tool? I'll use it for this example. I've also downgraded to QS 1.6.0 for this test.

Yes, I think I can reproduce your issue now:

#!/usr/bin/env bash

set -Eeuf -o pipefail

# cd to a temporary directory
cd "$(mktemp -d)"

mkdir -p ./why/hello
echo "quicksilver rocks!" > ./why/hello/friend.txt

/bin/ln -s "${PWD}"/why/hello ./there

/usr/bin/readlink ./there
ls -ld ./there
cat ./there/friend.txt

qs ./there

At this point, QS has the there ~directory~ symlink selected. I choose "Add to catalog," select "include contents" -> "source contents," but it doesn't add there/friend.txt to the catalog. I can into there and it sees friend.txt, so I know the link is correct. Increasing the depth doesn't help, nor does rescanning the catalog, relaunching QS, or enabling the "descend in bundles" option.

If I update the symlink to point elsewhere, it updates properly in Quicksilver (without me having to change anything in the catalog):

$ /bin/ln -shf /Applications /var/folders/kb/tw_lp_xd2_bbv0hqk4m0bvt80000gn/T/tmp.paNiEAWvLU/there
$ ls -l /var/folders/kb/tw_lp_xd2_bbv0hqk4m0bvt80000gn/T/tmp.paNiEAWvLU/there
lrwxr-xr-x 1 n8henrie staff 13 May  9 08:51 /var/folders/kb/tw_lp_xd2_bbv0hqk4m0bvt80000gn/T/tmp.paNiEAWvLU/there -> /Applications
Screen Shot 2022-05-09 at 08 52 50

The file picker resolving symlinks remains an outstanding problem though, IIRC?

Not sure but I think this is a MacOS issue, and probably not something we can or want to change -- AFAIK QS is just using the system filepicker dialog, which is what is resolving the symlink (which may be desirable behavior in many cases, since most of the time symlinks aren't going to be changing around frequently as in nix). For this fairly niche case, I'd say that using QS -> Add to Catalog is a reasonable workaround.

So I guess currently the issue that one can either:

toonn commented 2 years ago

@n8henrie, thank you for the detailed double checking. From what you said earlier this all works in the latest QS though, right? So I don't expect anything to be done about it in 1.6.x.

With regards to the file picker resolving symlinks. I wouldn't be surprised if it's not easily worked around but it would be nice if there's easily discoverable documentation or some form of warning that it does indeed resolve symlinks.

n8henrie commented 2 years ago

From what you said earlier this all works in the latest QS though, right?

No, as I noted above[^1], even with QS 2.1.0, a symlinked directory's contents are not included in my catalog. However, Quicksilver with faithfully follow a symlink even if it moves / changes, so I think for the nix use-case you may still be fine.

For example, on my system, ~/.nix-profile is a symlink

$ nix-shell -p bash --command 'stat ~/.nix-profile'
  File: /Users/n8henrie/.nix-profile -> /nix/var/nix/profiles/per-user/n8henrie/profile
  Size: 47              Blocks: 0          IO Block: 4096   symbolic link
Device: 1,14    Inode: 58821664    Links: 1
Access: (0755/lrwxr-xr-x)  Uid: (  501/n8henrie)   Gid: (   20/   staff)
Access: 2021-11-02 08:29:26.649986378 -0600
Modify: 2021-11-02 08:29:26.649986378 -0600
Change: 2021-11-02 08:29:26.650151626 -0600
 Birth: 2021-11-02 08:29:26.649986378 -0600

So I can add ~/.nix-profile to my QS catalog: qs ~/.nix-profileAdd to Catalog. After which I can find nix-profile, and arrow-in in order to access its contents. ~/.nix-profile should remain in my catalog irrespective of where that symlink points.

The contents of ~/.nix-profile do not appear in my catalog -- I have to arrow in.

Some of the contents of ~/.nix-profile are not symlinks, and some are. For example, Library is a symlink, and bin is not:

$ nix-shell -p bash --command 'stat ~/.nix-profile/Library'
  File: /Users/n8henrie/.nix-profile/Library -> /nix/store/wc486slv44h6zm9fjv8zkq42b3rdrdn6-nix-2.5pre20211007_844dd90/Library
  Size: 78              Blocks: 0          IO Block: 4096   symbolic link
Device: 1,18    Inode: 3279808     Links: 1
Access: (0755/lrwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/   wheel)
Access: 2022-05-02 14:18:45.000000000 -0600
Modify: 1969-12-31 17:00:01.000000000 -0700
Change: 2022-05-02 14:18:45.143996129 -0600
 Birth: 1969-12-31 17:00:01.000000000 -0700
$ nix-shell -p bash --command 'stat ~/.nix-profile/bin'
  File: /Users/n8henrie/.nix-profile/bin
  Size: 576             Blocks: 0          IO Block: 4096   directory
Device: 1,18    Inode: 3279684     Links: 18
Access: (0555/dr-xr-xr-x)  Uid: (    0/    root)   Gid: (    0/   wheel)
Access: 2022-05-02 14:18:45.000000000 -0600
Modify: 1969-12-31 17:00:01.000000000 -0700
Change: 2022-05-02 14:18:45.143568832 -0600
 Birth: 1969-12-31 17:00:01.000000000 -0700

This means that I should be able to add ~/.nix-profile/bin to QS, and its contents will be added (and indeed this is the case -- again, because bin is not a symlink, but a directory):

$ grep 'nix-profile/bin' /Users/n8henrie/Library/Application\ Support/Quicksilver/Catalog.plist
<string>/Users/n8henrie/.nix-profile/bin</string>

After a little testing, it looks like this will continue to work even if ~/.nix-profile changes, as long as it still has a bin subdirectory that is a real directory (and not a symlink).

~/.nix-profile/Library, on the other hand, is a symlink, so adding it to QS does not add its contents to the catalog.

It may be a reasonable enhancement to have QS index the contents of catalog sources that are themselves symlinks, which I think would resolve this issue.

it would be nice if there's easily discoverable documentation or some form of warning that it does indeed resolve symlinks

Again, this is MacOS resolving the symlink[^2], not QS: https://www.apple.com/feedback/. As we've shown, QS does not resolve the symlink when you do things through QS, only when you use the Finder dialog. (Here is a similar issue with Alfred: https://www.alfredforum.com/topic/4604-directory-symlinks-resolved-in-search-scope/).

[^1]: > the contents of the symlinked directory are currently not added to QS using this approach [^2]: For example, in Safari: O to open the file picker dialog, G to open the "go to path" box, type in ~/.nix-profile/Library, hit . Then click the bar at the to of the screen that says Library to show your actual path -- you are in the resolved path, not in ~/.nix-profile.

toonn commented 2 years ago

Thank you for clarifying again. So the issue is indeed still current. And IMO a bug though opinions might differ about this.

Re the file picker, I understand 100% that this is an unfortunate design decision by Apple. That does not change my request to make this information easily found somewhere, since it's confusing and going through the settings to add paths to the catalog is the most obvious way to do so. Not to mention that you need to navigate there to specify more detailed settings about catalog entries anyway. Having some documentation to be found when someone searches for "QS resolves symlinks" or similar would be a great way to find out it's not actually QS doing the resolving and to inform the user of alternative ways to achieve the same goal, like the "Add to Catalog..." action or the qs utility.

I think the file picker might actually be configurable in this regard but it would require testing. The NSOpenPanel class has a resolvesAliases boolean flag, which defaults to true and toggles resolving of aliases. Now, I know aliases are distinct from symlinks but it might be worth a shot to see if it changes the behavior for symlinks too. If the current behavior ends up being preferred for aliases after all (again, subjective desirability) the current handling could be mimicked by QS because aliases are recognisable as distinct from symlinks.

n8henrie commented 2 years ago

Thanks for the info re: NSOpenPanel; this seems to be one of the functions of interest:

https://github.com/quicksilver/Quicksilver/blob/0acf25c25e383a1837392852d51322584e2ccfb3/Quicksilver/PlugIns-Main/QSCorePlugIn/Code/QSFileSystemObjectSource.m#L271

Setting openPanel.resolvesAliases = false;, setting a breakpoint, and choosing ~/.nix-profile/Library/LaunchDaemons/ doesn't look encouraging:

(lldb) po [[openPanel URL] path]
/nix/store/wc486slv44h6zm9fjv8zkq42b3rdrdn6-nix-2.5pre20211007_844dd90/Library/LaunchDaemons

Maybe I did that wrong though ¯\_(ツ)_/¯

Having some documentation to be found when someone searches for "QS resolves symlinks"

I think this is a fair point, though I think the priority will be fairly low. In the meantime we can point people to this issue -- I appreciate your time and feedback! Perhaps could go into the FAQ / Troubleshooting part of the manual, (which I think we should also reconcile it with the similar section in the Wiki at some point).

This seems particularly salient for nix users, but for better or worse the intersection of QS and nix users seems to be pretty small -- the only hits for nix in all of the issues seem to be this and the issue closed in favor of this one :)