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

Feature request: Make v up work on windows. #16184

Closed
bogen85 opened this issue Oct 24, 2022 · 7 comments · Fixed by #16348
Closed

Feature request: Make v up work on windows. #16184

bogen85 opened this issue Oct 24, 2022 · 7 comments · Fixed by #16348
Labels
Feature Request This issue is made to request a feature.

Comments

@bogen85
Copy link
Member

bogen85 commented Oct 24, 2022

v up does not work on windows.

I currently don't have access to windows to confirm this or to implement is feature.

This arose from a recent discussion in V's #help on discord.

TLDR: Windows won't allow a running executable to be rewritten.

Any changes for this feature request only apply to Windows, *nix flavors and distros don't need this feature, as v up already works for them.

This also does not apply to using v with WSL, as long as the v location is not on a regular Windows Filesystem.
WSL controlled mounts/directories should act like filesystems do on *nix flavors and distros.

The following are suggestions only. How it actually gets implemented is not he issue here.
However it is implemented it just needs to work given that 'Windows won't allow a running executable to be rewritten'.

What could be done to make this work.

  1. v up copies v somewhere else.
  2. That v is launched with an indication of what had happened. (possibly with something like v up --stage2)
  3. The first v quits.
  4. The stage2 v waits for the first v to quit.
  5. The second (stage2) continues the update as normal.
  6. Stage2 v quits.

Optional of what else could be done.

  1. Instead of quitting at the end in the above steps, run the new v asking it too delete the stage 2 v from above.
  2. Stage2 v quits.
  3. The new v waits for the now stale stage2 to quit.
  4. The new v deletes the stale stage2 v
  5. The new v quits.

Potential blockers

  1. The v be to updated is running in one or more REPL sessions.
  2. The v be to updated is in the middle of long build.
  3. The v be to updated is running doing something else.

If the Potential blockers are an issue, then the update stages must accommodate and handle that cleanly (or with applicable error message indicating what the problem.

@bogen85 bogen85 added the Feature Request This issue is made to request a feature. label Oct 24, 2022
@bogen85 bogen85 changed the title Feature request: Make v update work on windows. Feature request: Make v up work on windows. Oct 24, 2022
@bogen85
Copy link
Member Author

bogen85 commented Oct 24, 2022

Or, rather all the v stages, just have v up run a script to do the update, where the first thing the script does is wait for v to quit.

@Wajinn
Copy link

Wajinn commented Oct 26, 2022

It's not entirely clear, where is it coming from, that v up doesn't work on Windows. Possibly this statement, "Make v up work on windows", is very broad and doesn't come with specific errors. Does the title need to be redone? Also, could there be possibly something else at play for various people, like updates being blocked by their firewall?

For instance, on two computers that I tested v up with, they worked. Additionally, I do know from past experiences that making modifications or adding files into directories can cause partial or even complete v up failures. Like if you changed the contents of TCC or added new folders into the v directory. In those cases, in might be better to make a backup of the folder, then do a new git download of the repo.

@JalonSolov
Copy link
Contributor

v up can't really work on Windows, due to the way Windows locks running executables - the V executable can't be replaced since it started vup to do the update.

Sometimes it looks like it worked, but if you compare the hash before/after, it is the same. that's because v up is actually suppressing the error message that says it can't replace v.exe.

If it actually works for you somehow, it is a fluke that doesn't work on any Windows system I have tried in the past.

@bogen85
Copy link
Member Author

bogen85 commented Oct 26, 2022

v up can't really work on Windows, due to the way Windows locks running executables - the V executable can't be replaced since it started vup to do the update.

Agreed. It can't work as it is currently implemented on Windows.

Sometimes it looks like it worked, but if you compare the hash before/after, it is the same. that's because v up is actually suppressing the error message that says it can't replace v.exe.

That makes sense.

If it actually works for you somehow, it is a fluke that doesn't work on any Windows system I have tried in the past.

@Wajinn can you confirm it actually worked? Compare before and after hash?

@Wajinn
Copy link

Wajinn commented Nov 3, 2022

can you confirm it actually worked?

Yes, I took a Windows box from 0.3.1 to 0.3.2. So I'm not sure what the source of the original issue was, if the person is not using Windows. However, I don't see anything wrong with your feature request, just that other developers who are testing on Windows should probably chime in on what they think.

If you guys find some other ways to update v on Windows, I guess that's good. Keep in mind, a huge number of users and potential users will be on Windows.

>v up
Updating V...
V self compiling ...
V built successfully as executable "v.exe".
Current V version: V 0.3.2 54b6b43, timestamp: 2022-11-02 

I did initially have an interesting problem though, with fn.v. I had to delete the file, and then the update went smoothly. Not sure yet what that was all about.

>v up
Updating V...
From https://github.com/vlang/v
 * branch                master     -> FETCH_HEAD
error: Your local changes to the following files would be overwritten by merge:
        vlib/v/gen/c/fn.v
Please commit your changes or stash them before you merge.
Updating 992b50219..54b6b4392
Aborting

@rivy
Copy link
Contributor

rivy commented Nov 6, 2022

@bogen85 , @JalonSolov , ...

I ran into this when installing v today and then using v up.

The real blocker is that the v.exe executable file, when running, can't be deleted because the executable process itself holds an open file handle until execution is finished. This can be worked around with some simple alternate techniques.

I've got a local version of v up working on windows with just a few changes to make.bat.

I'll post a PR later tonight after my local CI runs finish.

rivy added a commit to rivy-fix/v that referenced this issue Nov 6, 2022
- use move semantics, instead of replace, for `v` executable updates
- fixes [vlang#16184](vlang#16184)

# [why]

`v up` updates the executable by directly calling `make.bat`, awaiting
the result, which keeps an open file handle to it's own executable file.
`make.bat` compiles and, crucially, attempts to directly replace that
`v` executable. But, in WinOS, files with open file handles cannot be
deleted/replaced, so the `make` then fails. The other key point is that,
although WinOS files with open file handles can't be deleted/replaced,
they _can be moved/renamed_.

Thus, the technique that most self-updating WinOS executables use is to
move the current executable to some alternate name (ie, *v_old.exe*) and
then move the newly updated executable to the original location (ie,
*v.exe*). The next invocation of the "original" executable will then run
the updated version.

Note, this technique also works correctly for direct invocations of `make.bat`.
@rivy
Copy link
Contributor

rivy commented Nov 6, 2022

PR #16348 fixing this is now posted.

spytheman pushed a commit that referenced this issue Nov 7, 2022
* .editorconfig: fix EOL for BAT files

* make.bat: fix use of `make.bat` from `v up`

- use move semantics, instead of replace, for `v` executable updates
- fixes [#16184](#16184)

# [why]

`v up` updates the executable by directly calling `make.bat`, awaiting
the result, which keeps an open file handle to it's own executable file.
`make.bat` compiles and, crucially, attempts to directly replace that
`v` executable. But, in WinOS, files with open file handles cannot be
deleted/replaced, so the `make` then fails. The other key point is that,
although WinOS files with open file handles can't be deleted/replaced,
they _can be moved/renamed_.

Thus, the technique that most self-updating WinOS executables use is to
move the current executable to some alternate name (ie, *v_old.exe*) and
then move the newly updated executable to the original location (ie,
*v.exe*). The next invocation of the "original" executable will then run
the updated version.

Note, this technique also works correctly for direct invocations of `make.bat`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature Request This issue is made to request a feature.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants