spiveeworks / HLink

Symlink management tool that allows powerful link structures without using any CLI or GUI.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

make relative externs work

spiveeworks opened this issue · comments

e.g. ./source/ -> dest/

make join start handling relative sources, (implemented)
add version of mark that simply adds "\n." or "." :->: "."
change mount to handle relative sources, or maybe a third kind of link is needed?

making mount add (".", path) to an EvalMap solves the mount issue without causing join/etc to break things

note that this would make it possible to create dependencies within a mount operation, e.g.

./source/ -> dest/
extern -> source/file

which, if reversed, causes issues.
the reverse can be made just as easily as the above layout, in fact join almost encourages you to reverse the above since it doesn't follow symlinks.

perhaps join should prepend its additions? I don't like it but it might turn out to encourage valid setups

alternatively I could detect invalid setups

perhaps instead of an alternate mark, I should make an alternate join specifically for pulling a .links through a symbolic link?

I think it would only pull the line specifying the link itself out of the file, the rest would remain?

I'm going to add a second version of Join, JoinLink, which is designed to behave well when pulling a .links through a symbolic link.

This means two things,
one is that it can be used in combination with MountRelative to create internal symlinks (i.e. relative sources will change to refer to the link being Joined)
the other is that it will be possible to Join a link whose target is inside another link, after that link has been added to the .links

i.e. the following

source/ -> dest/
$location/file -> source/file

should be possible to make without typing anything.

This means:

  1. Relative sources should be updated with respect to the link being joined
  2. If a line has a relative source and a relative destination then the relative destination should be updated with respect to the target of that link (for directories treat them as links to themselves)
  3. Otherwise relative destinations should be updated with respect to the link itself.
  4. Absolute sources and destinations including compressed paths should stay absolute.

So there are 6 situations that can occur in a .link being JoinLinked:

  1. . -> <relative>
  2. <relative> -> <relative>
  3. <absolute> -> <relative>
  4. . -> <absolute>
  5. <relative> -> <absolute>
  6. <absolute> -> <absolute>

no. 1 should become link/ -> target/<relative> because target -> target/<relative> is nonsensical.
no. 2 should become link/<relative> -> link/relative as:

  • target/<relative> -> target/<relative> can be achieved using a normal join,
  • target/<relative> -> link/<relative> can as well
  • link/<relative> -> target/<relative> can be achieved using MarkReverse (described later) via no. 3/4
    no. 3 should become <absolute> -> link/<relative> for similar reasons as apply to no. 2
    numbers 4-6 should all be link/... -> <absolute> although in some situations may become a relative path to the new root.

So the actual rules are:
Always use the link location for updating relative paths, with the exception of <a> -> <a>/<b>, i.e. when the destination is inside the source, in which case the target is used for updating the destination, and the link is used for updating the source.

By adding MarkReverse, which instead of adding <cd> to a .links, adds . -> <cd>, most internal link patterns (perhaps all?) become possible in combination with JoinLink.
MarkRelative may be useful still, though it is a compressed equivalent to MarkReverse.
I suspect I won't add MarkRelative simply to avoid clutter.