Skip to content

Windows fails on dangling symlinks #10

@vweevers

Description

@vweevers

Symlinking failed for me, because linklocal uses a relative path for symlinking. So called "dangling symlinks" are not supported by Windows. From the nodejs docs:

fs.symlink(srcpath, dstpath, [type], callback)

Note that Windows junction points require the destination path to be absolute. When using 'junction', the destination argument will automatically be normalized to absolute path.

Reading that, you'd think the dstpath argument is normalized (which would mean the link name). What the docs mean to say is that the srcpath (the target) is normalized (see footnote below). However, this target seems to be normalized relative to the working directory - not relative to the link's parent directory like it should:

man ln

Symbolic links can hold arbitrary text; if later resolved, a relative link is interpreted in relation to its parent directory.

Example

A package.json in C:\project lists the dependency file:local-dependency. If I run linklocal link (within C:\project), it calls fs.symlink("..\local-dependency", "C:\project\node_modules\local-dependency"), and the target is normalized to C:\local-dependency. Should be C:\project\local-dependency.

This might be a node.js issue. As a test, if I change L285 from

var from = link.from
var to = path.relative(path.dirname(link.from), link.to)
fs.symlink(to, from, 'junction', ..`

to..

fs.symlink(link.to, link.from, 'junction', ..

.. then it works, because the paths in link are absolute. In conclusion: am I right in thinking this is a node.js issue, although linklocal could probably fix it with a workaround?

Footnote

I'm not the only one who's confused by the order of arguments for a symlink. Some think in "source vs destination", others in "target vs link name" - and cognitively, a "source" is not a "target". Even worse, there's the perspective of "destination vs link".

The unix command is ln -s $target $link_name, or ln -s $source $destination, similar to copy: cp $source $destination. The function signature in the node.js documentation is has the same naming: symlink(srcpath, destpath). However, the signature in the node source is symlink(destination, path). That destination argument (meaning the target) is normalized. Linklocal calls the function with symlink(to, from). Where to is the target and from is the link name. The opposite of "source vs destination". May I suggest, in any case, to change these variable names?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions