Skip to content

Validate pfx/dosdevices symlink after copy - #252

Open
shymega wants to merge 2 commits into
devfrom
shymega/validate-dosdevices-symlinks
Open

Validate pfx/dosdevices symlink after copy#252
shymega wants to merge 2 commits into
devfrom
shymega/validate-dosdevices-symlinks

Conversation

@shymega

@shymega shymega commented Mar 20, 2026

Copy link
Copy Markdown
Member

This PR adds validation for the special dosdevices folder on the Proton prefix.

@shymega
shymega requested a review from marvin1099 March 20, 2026 21:11
@shymega
shymega changed the base branch from main to dev March 20, 2026 23:36
@shymega
shymega force-pushed the shymega/validate-dosdevices-symlinks branch 5 times, most recently from 518329a to 285c2b2 Compare March 20, 2026 23:54
@stackrot

stackrot commented Mar 21, 2026

Copy link
Copy Markdown
Contributor

Heyo @shymega

Just had chance to go over this, couple notes:

Spotted that #251 was closed w/o merging but this PR mentions needing it merged first, so just need to sort below

  • pfx/dosdevices is still in the ignore list, so the directory never gets copied
  • The validation at wemod.py:567 is gated by if os.path.isdir(dosdevices), which will be False since the dir was skipped
  • No os.makedirs() call exists to create it

Smaller things:

  • assert gets stripped by python -O (wemod.py:578-579) so those would silently disappear. We don't use -O, but worth keeping in mind
  • create_symlink will silently do nothing if dst exists as a regular file rather than a symlink, the if os.path.islink(dst) guard just skips it with no error, probs not a big deal since they should always be sym's, but worth noting

@shymega

shymega commented Mar 21, 2026

Copy link
Copy Markdown
Member Author

@stackrot I think it'd be easier for me to see which parts you mean if you use the Code Review feature GitHub offers. We can then converse on threads on the Git hunks you select in the diff, and that'll work much better :-)

@shymega
shymega force-pushed the shymega/validate-dosdevices-symlinks branch 2 times, most recently from b1b4296 to 4b2ba2b Compare March 21, 2026 17:40
Comment thread src/wemod.py

@stackrot stackrot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh cool, didn't know that was a thing (I interact with github mostly through neovim haha)
It looks like you fixed the main issues I flagged.

I've left a comment on the other one (if I did it right), but it's very minor and probably won't come up.

@shymega
shymega force-pushed the shymega/validate-dosdevices-symlinks branch from 4b2ba2b to 65f0d31 Compare March 21, 2026 21:25
@shymega

shymega commented Mar 21, 2026

Copy link
Copy Markdown
Member Author

Oh cool, didn't know that was a thing (I interact with github mostly through neovim haha) It looks like you fixed the main issues I flagged.

I've left a comment on the other one (if I did it right), but it's very minor and probably won't come up.

Yeah, I did have a project I was working on to convert GitHub's UI to a NNTP based interface, so you could comment on PRs with email. Never got very farwith it.

I've fixed your review.

As for your other comments:

assert gets stripped by python -O (wemod.py:578-579) so those would silently disappear. We don't use -O, but worth keeping in mind

Yeah, we don't use that option, but yes, fair enough. The assert is more of a final check.

create_symlink will silently do nothing if dst exists as a regular file rather than a symlink, the if os.path.islink(dst) guard just skips it with no error, probs not a big deal since they should always be sym's, but worth noting

We could make it remove the file and replace it with a symlink, but I felt that was too destructive.

@shymega
shymega requested a review from stackrot March 21, 2026 21:27
@marvin1099

marvin1099 commented Mar 31, 2026

Copy link
Copy Markdown
Collaborator

@shymega did you test this then, if so then seems fine to merge.

  • after the "Yeeted from..." comment is removed.

@marvin1099 marvin1099 added the test me Added to PRs that look merge‑ready, but still clone and test the code to confirm expected behavior. label Mar 31, 2026
@shymega

shymega commented Mar 31, 2026

Copy link
Copy Markdown
Member Author

@shymega did you test this then, if so then seems fine to merge.

* after the "Yeeted from..." comment is removed.

The comment is to provide attribution to the snippet of Python I copied from a developer's site. I think we should keep it, but I can change the 'Yeeted from' to 'Taken from'

@marvin1099

Copy link
Copy Markdown
Collaborator

@shymega did you test this then, if so then seems fine to merge.

* after the "Yeeted from..." comment is removed.

The comment is to provide attribution to the snippet of Python I copied from a developer's site. I think we should keep it, but I can change the 'Yeeted from' to 'Taken from'

We can easly come up with a version like this, whiout knowing the code infact let me do it right now,

import os
import pathlib
import shutil
from typing import Union

def safe_symlink(src: Union[str, pathlib.Path],
                 dst: Union[str, pathlib.Path],
                 *, replace: bool = True) -> None:
    """
    Create a symlink from *src* to *dst*, handling existing files,
    directories, or incorrect symlinks.

    Parameters
    ----------
    src : path‑like
        Existing file or directory that should become the link target.
    dst : path‑like
        Desired location of the symlink.
    replace : bool, default True
        If True, conflicting ``dst`` objects are removed before linking.
        If False, a conflict raises ``OSError``.
    """
    src_path = pathlib.Path(src).resolve()
    dst_path = pathlib.Path(dst)

    if not src_path.exists():
        raise FileNotFoundError(f"Source does not exist: {src_path}")

    # Handle existing destination
    if dst_path.lexists():                     # true for files, dirs, or symlinks
        if dst_path.is_symlink():
            # Correct symlink – nothing to do
            if dst_path.resolve() == src_path:
                return
            # Wrong target
            if not replace:
                raise OSError(f"Symlink {dst_path} points to {dst_path.resolve()}, "
                              f"expected {src_path}")
            dst_path.unlink()                  # remove incorrect link
        else:
            # File or directory
            if not replace:
                raise OSError(f"{dst_path} exists and is not a symlink")
            if dst_path.is_dir():
                shutil.rmtree(dst_path)        # delete whole directory tree
            else:
                dst_path.unlink()              # delete regular file

    # Create link
    os.symlink(src_path, dst_path)

There we go independent and in dosn't even replace correct links.

@shymega

shymega commented Mar 31, 2026

Copy link
Copy Markdown
Member Author

I suppose we could use that. Seems a bit overly complex for our needs, but I'll integrate it when I get a moment.

@marvin1099

Copy link
Copy Markdown
Collaborator

wemod.py:578-579

We should probably not use an assert if we wanna ship a binary then this check should not be skipped.
We can just test and exit with error / log as usual.

Also the z drive is not a necessity, i don't think we need to check that one.
The z drive is mapped to "linux /" on some wine setups, but not all have and it works without it, so i don't think is needed, am I wrong?

Also for the create_symlink changes a made a merge request (#257).
But feel free to manually add it it you don't wanna marge like that.

@shymega

shymega commented May 1, 2026 via email

Copy link
Copy Markdown
Member Author

@marvin1099

marvin1099 commented May 1, 2026

Copy link
Copy Markdown
Collaborator

But we don't ship a binary, so I see no harm in keeping an assert.

Just wanted to future proof.
Asserts are meant for checks that dont need to be checked after compile is used.
So since this is a always needs completion check the assert is offplace.
Thats what o think anyway.

Hm... we don't want unexpected behaviour, but equally I know of no
Proton implementation that /doesn't/ map Z: to "/". Do you have
examples?

Just regular wine.
I actually prefer using wemod without proton.
With lutris, wine is way faster then proton.
In steam you can't use wine but as soon as you go outside of steam using wine directly works well.
Plus I dont think any code relies on drive z to be there so is it not unneeded.

@shymega
shymega force-pushed the shymega/validate-dosdevices-symlinks branch from 65f0d31 to 67b691c Compare May 2, 2026 22:42
@shymega

shymega commented May 4, 2026 via email

Copy link
Copy Markdown
Member Author

@marvin1099

Copy link
Copy Markdown
Collaborator

I'm surprised at this. I've never seen Wine not map Z: to the host's root filesystem. Can you provide a screenshot of DIR Z: from a Wine shell?

Must be in older wine versions.
The newest one seems to map Z:/ to root.
I do remember wine not doing this in older versions.
I usually saw the wrappers (like bottles) make this Z:/ drive.
But seems that this is in fact now default, not sure since when.
I usualy creata wine prefixes like this "WINEPREFIX=/new/path wine hostname"
and that didn't create a Z:/ mapping in older versions.
Since that seems to be included now that check would be fine.
But the ting is i did not see any coude of ours using "Z:/".
Why add that check if we dont use "Z:/", I'm i wrong?

@shymega

shymega commented May 8, 2026

Copy link
Copy Markdown
Member Author

I'm surprised at this. I've never seen Wine not map Z: to the host's root filesystem. Can you provide a screenshot of DIR Z: from a Wine shell?

Must be in older wine versions. The newest one seems to map Z:/ to root. I do remember wine not doing this in older versions. I usually saw the wrappers (like bottles) make this Z:/ drive. But seems that this is in fact now default, not sure since when. I usualy creata wine prefixes like this "WINEPREFIX=/new/path wine hostname" and that didn't create a Z:/ mapping in older versions. Since that seems to be included now that check would be fine. But the ting is i did not see any coude of ours using "Z:/". Why add that check if we dont use "Z:/", I'm i wrong?

I'm almost certain Wine has always mapped Z: to /. I don't think wrappers have done that for it. I remember using Wine back in 2008, and it did it then too.

Are you thinking of the z: link in dosdevices? I wonder if we're thinking of two different things.

I think we need the Z: check, as we call wand.bat from Z: - it's not in the C: drive.

@marvin1099

Copy link
Copy Markdown
Collaborator

I think we need the Z: check, as we call wand.bat from Z: - it's not in the C: drive.

True, completly missed that one
Never mind then.

@shymega
shymega force-pushed the shymega/validate-dosdevices-symlinks branch 2 times, most recently from a0b5690 to 65f0d31 Compare May 14, 2026 23:35
shymega and others added 2 commits May 15, 2026 21:04
Inspired by #251, and derives some code from that, therefore:

Co-authored-by: Connor Field <connor@connorfield.com>
@shymega
shymega force-pushed the shymega/validate-dosdevices-symlinks branch from 65f0d31 to 6c9d41d Compare May 15, 2026 20:05
@marvin1099 marvin1099 added pickup for v2 pickup or re-examine task or change in v2 and removed test me Added to PRs that look merge‑ready, but still clone and test the code to confirm expected behavior. labels Jul 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pickup for v2 pickup or re-examine task or change in v2

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants