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

Linking fails in .config is symlinked #2096

Closed
davewasmer opened this issue Nov 30, 2016 · 1 comment
Closed

Linking fails in .config is symlinked #2096

davewasmer opened this issue Nov 30, 2016 · 1 comment
Labels

Comments

@davewasmer
Copy link

davewasmer commented Nov 30, 2016

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
yarn link foo fails if ~/.config is a symlink.

If the current behavior is a bug, please provide the steps to reproduce.

$ ln -s ~/some/other/path/.config ~/.config
$ brew install yarn

$ cd foo && yarn link
yarn link v0.17.9
success Registered "foo".
info You can now run `yarn link "foo"` in the projects where you want to use this module and it will be used instead.
✨  Done in 0.07s.

$ cd ../bar && yarn link foo
yarn link v0.17.9
error No registered module found called "foo".
info Visit https://yarnpkg.com/en/docs/cli/link for documentation about this command.

What is the expected behavior?
The final command above should succeed in linking foo into bar. Or, if symlinking .config is not supported, it should warn on install or when the command runs.

Please mention your node.js, yarn and operating system version.
yarn 0.17.9
node 6.6.0
OS X 10.11.6


The problem seems to stem from the fact that utils/fs.js favors relative paths for symlinks when possible. This means that the symlink created in ~/.config/yarn/link/foo is a relative path, i.e. ../../../foo.

When the OS resolves this relative path though, it does so based on the real location of the symlink file itself. So rather than resolving relative to ~/.config/yarn/link, it resolves it relative to ~/some/other/path/.config (which is where the ~/.config symlink points to). This means the relative path is invalid. And Node's fs.exists() (used to detect if the link exists when running yarn link <pkg>) returns false if the file is a symlink whose destination does not exist.

Not sure if there are other benefits to keeping the symlink relative (the code I linked to above mentions something about maintaining links when things move). If the answer is simply that symlinked .config dirs are not supported, it would be nice if the install or link command at least warned that this will break yarn.

stefanpenner added a commit to stefanpenner/yarn that referenced this issue Jan 15, 2017
The following commit forces symlinks to be relative:
yarnpkg@36d73cc

This isn't ideal, although it enables some portability it breaks others.

For example, it is not uncommon for `$HOME/.config` itself to be be a
symlink:

`$HOME/.config` -> `$HOME/src/stefanpenner/dotfiles`

now when running `yarn link` inside `$HOME/src/ember-cli/ember-cli`

we end up running:
```js
path.relative('/Users/spenner/.config/yarn/link/ember-cli', '/Users/spenner/src/ember-cli/ember-cli');
=> '../../../src/ember-cli/ember-cli'
```

Which results in the link located at: `/Users/spenner/.config/yarn/link/ember-cli` pointing to
`/Users/spenner/.config/src/ember-cli/ember-cli` rather then `/Users/spenner/src/ember-cli/ember-cli`

One approach (the one this commit takes) is to reify the paths before
deriving the relative path.
@stefanpenner
Copy link
Contributor

stefanpenner commented Jan 15, 2017

I believe making all symlinks via the lib/utils/fs abstraction relative is problematic, there are work arounds. But it is quite unexpected, and not without issues/caveats.

Although the link can now survive some moves, the process of "making relative" forces disk location to be eagerly reified.

IMHO #94 should likely have been addressed in a targeted way, not making all symlinks relative.


An alternative may be to realpath the paths before constructing the relativePath -> #2454

stefanpenner added a commit to stefanpenner/yarn that referenced this issue Jan 15, 2017
The following commit forces symlinks to be relative: yarnpkg@36d73cc

This isn't ideal, although it enables some portability it breaks others. For example, it is not uncommon for `$HOME/.config` itself to be be a symlink: `$HOME/.config` -> `$HOME/src/stefanpenner/dotfiles`.

Now when running `yarn link` inside `$HOME/src/ember-cli/ember-cli` we end up with:
```js
path.relative('/Users/spenner/.config/yarn/link/ember-cli', '/Users/spenner/src/ember-cli/ember-cli');
=> '../../../src/ember-cli/ember-cli'
```

Which results in the link located at: `/Users/spenner/.config/yarn/link/ember-cli` pointing to
`/Users/spenner/.config/src/ember-cli/ember-cli` rather then `/Users/spenner/src/ember-cli/ember-cli`

This is because `/Users/spenner/.config` is actually a symlink pointing to `/Users/spenner/src/stefanpenner/dotfiles/.config/`

---

This PR provides mitigate the issue raised in yarnpkg#2096, but reifying the paths via `realpathSync` before deriving the relative path. This doesn't fix all issues, e.g. symlinks cannot be changed after this reification.
stefanpenner added a commit to stefanpenner/yarn that referenced this issue Jan 15, 2017
This makes yarn link work when $HOME/.config/yarn/link/ is itself a symlink.

----

The following commit forces symlinks to be relative: yarnpkg@36d73cc

This isn't ideal, although it enables some portability it breaks others. For example, it is not uncommon for `$HOME/.config` itself to be be a symlink: `$HOME/.config` -> `$HOME/src/stefanpenner/dotfiles`.

Now when running `yarn link` inside `$HOME/src/ember-cli/ember-cli` we end up with:
```js
path.relative('/Users/spenner/.config/yarn/link/ember-cli', '/Users/spenner/src/ember-cli/ember-cli');
=> '../../../src/ember-cli/ember-cli'
```

Which results in the link located at: `/Users/spenner/.config/yarn/link/ember-cli` pointing to
`/Users/spenner/.config/src/ember-cli/ember-cli` rather then `/Users/spenner/src/ember-cli/ember-cli`

This is because `/Users/spenner/.config` is actually a symlink pointing to `/Users/spenner/src/stefanpenner/dotfiles/.config/`

---

This PR provides mitigate the issue raised in yarnpkg#2096, but reifying the paths via `realpathSync` before deriving the relative path. This doesn't fix all issues, e.g. symlinks cannot be changed after this reification.
stefanpenner added a commit to stefanpenner/yarn that referenced this issue Jan 15, 2017
This makes yarn link work when $HOME/.config/yarn/link/ is itself a symlink.

----

The following commit forces symlinks to be relative:
yarnpkg@36d73cc

This isn't ideal, although it enables some portability it breaks others.
For example, it is not uncommon for `$HOME/.config` itself to be be a
symlink: `$HOME/.config` -> `$HOME/src/stefanpenner/dotfiles`.

Now when running `yarn link` inside `$HOME/src/ember-cli/ember-cli` we
end up with:

```js
path.relative('/Users/spenner/.config/yarn/link/ember-cli',
'/Users/spenner/src/ember-cli/ember-cli');
=> '../../../src/ember-cli/ember-cli'
```

Which results in the link located at:
`/Users/spenner/.config/yarn/link/ember-cli` pointing to
`/Users/spenner/.config/src/ember-cli/ember-cli` rather then
`/Users/spenner/src/ember-cli/ember-cli`

This is because `/Users/spenner/.config` is actually a symlink pointing
to `/Users/spenner/src/stefanpenner/dotfiles/.config/`

---

This PR provides mitigate the issue raised in yarnpkg#2096, but reifying the
paths via `realpathSync` before deriving the relative path. This doesn't
fix all issues, e.g. symlinks cannot be changed after this reification.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants