RaphGL / Tuckr

Super powered replacement for GNU Stow
GNU General Public License v3.0
134 stars 10 forks source link

Attempting to symlink into a non-existing shared directory causes unintended conflicts #31

Open Jasha10 opened 2 months ago

Jasha10 commented 2 months ago

At the head commit https://github.com/RaphGL/Tuckr/commit/ee3c2bdaa865d791dfff9430ff009591c6063a03 I'm getting a compilation error on windows:

> cargo check                                          141 08/21/2024 01:28:34 PM
    Checking tuckr v0.9.1 (C:\Users\Jasha\dev\Tuckr)
error[E0382]: borrow of moved value: `f`
  --> src\symlinks.rs:44:33
   |
22 | fn symlink_file(f: PathBuf) {
   |                 - move occurs because `f` has type `PathBuf`, which does not implement the `Copy` trait
23 |     let src_path = f;
   |                    - value moved here
...
44 |                 let result = if f.is_dir() {
   |                                 ^^^^^^^^^^ value borrowed here after move
   |
   = note: borrow occurs due to deref coercion to `Path`
help: consider cloning the value if the performance cost is acceptable
   |
23 |     let src_path = f.clone();
   |                     ++++++++

For more information about this error, try `rustc --explain E0382`.
error: could not compile `tuckr` (bin "tuckr") due to 1 previous error
RaphGL commented 2 months ago

oof, guess I'll have to install windows to make sure things are working again as intended. Thanks for the heads up

RaphGL commented 2 months ago

So today I went to develop tuckr on windows and try to spot where things are going wrong. I've fixed this error and some others causing tuckr to not function as intended on windows.

Right now tuckr is usable on windows and works as intended. but I'm getting some false positive conflicts (they don't actually show up when you run tuckr status <group>). So I'll have to dive in and see why that's happening, so I won't close this issue just yet.

RaphGL commented 2 months ago

After debugging for a little bit I found out that the reason why conflicts happen on windows is because I'm attempting to symlink a bunch of dotfiles within a .config directory without it already existing on windows and tuckr does not create directories that are shared amongst different dotfile groups.

so this fixed it for me:

mkdir .config

I'll be looking into converting shared directories from symlinks to standalone directories to fix this issue.

RaphGL commented 1 month ago

I've been thinking about this issue and the most performant way to do this without introducing a horrible O(n^2) type performance penalty by comparing every single path in the validation cache seems to be to outright change the data structure/approach used.

I'll be conducting a big(???) change of the validation portion of the program where instead of using a HashMap for the caching/validating the dotfiles, I'll instead create a tree data structure that mimics the file system's, where each node is something akin to this:

struct TreeNode {
  path: Dotfile,
   shared: bool,
  nodes: Vec<Box<TreeNode>>,
}

So instead of separating everything by group all dotfiles are stored in a single source of truth "file system". The program will detect when a parent is shared by more than one dotfile group by doing something like this:

if parent.any(|child| child.path.group != parent.path.group) {
  parent.shared = true;
}

If the node is shared, it means it should be created instead of being a symlinked directory.


So far I haven't found a tree data structure that fits what I wanna do so potentially I'll be writing my own data structure for this. If I can I'll try to make it cache friendly by allocating everything contiguously.

Also since this requires quite a bit of changes to make the symlinking process more accurate, I'll refrain from shipping this into the following 0.10.0 release and push it to the next release.