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

Windows self-upgrade, does it work? #6706

Open
phadej opened this issue Apr 13, 2020 · 4 comments
Open

Windows self-upgrade, does it work? #6706

phadej opened this issue Apr 13, 2020 · 4 comments

Comments

@phadej
Copy link
Collaborator

phadej commented Apr 13, 2020

If I have cabal v2-install cabal in the past (with --install-method=copy) does cabal v2-install cabal works?

There is Distribution.Client.Win32SelfUpgrade, but it doesn't seem to be used in v2-install implementation. If things works without, that code could be deleted.

@emlautarom1
Copy link
Contributor

I tested the following:

> git clone https://github.com/haskell/cabal.git
> cd cabal\cabal-install
> cabal install exe:cabal

So far, this works as expected: cabal-install is built and placed in %APPDATA$\cabal\bin.
This means that the cabal-install 3.0.0.0 installed system-wide can build and install cabal-install 3.2.0.0 with no issues.

Now, the issue comes here:

> cd %APPDATA$\cabal\bin
> .\cabal.exe install cabal-install --overwrite-policy=always --install-method=copy

Here, I'm running the recently built cabal 3.2.0.0, no the system-wide one. This fails with the following error:

...
Copying 'cabal.exe' to 'C:\Users\Ryzen\AppData\Roaming\cabal\bin\cabal.exe'
C:\Users\Ryzen\AppData\Roaming\cabal\bin\cabal.exe: DeleteFile "\\\\?\\C:\\Users\\Ryzen\\AppData\\Roaming\\cabal\\bin\\cabal.exe": permission denied (Access is denied.)

So it seems like %APPDATA%\cabal\bin\cabal.exe can't overwrite itself while running, so you might say that cabal-install can't self-upgrade since it can't overwrite itself while running.

The current workaround would be to copy %APPDATA%\cabal\bin\cabal.exe to a different directory and then use it like .\cabal.exe install cabal-install --overwrite-policy=always --install-method=copy.

Note: Nevertheless I think that the code should be deleted since any solution would require some kind of custom hack.

I can think of three ways of dealing with this issue (upgrading cabal-install):

  • Keep the hack, try to make it work as best as possible

  • Add a new command to cabal like cabal upgrade and handle everything here (something like: copy the current cabal into a temp directory, download and build cabal-install and copy the executable to the original cabal-install folder). This could lead to user confusion: Does cabal upgrade upgrades my dependencies?. Also, how do we provide some kind of rollback to previous cabal-install versions?

  • Look into ghcup and making a rewrite in plain Haskell in order for it to work on Windows. This would allow Windows users to handle GHC and cabal versions from a single utility. This is how Rust handles rustc and cargo versions and works very well. So then upgrading cabal becomes as easy as ghcup update cabal. I think this would be the best approach but sadly also the hardest to implement.

Currently, I'm lacking free time but eventually, I would like to look into the third option.


System:

  • Windows 10 v1909
  • GHC 8.8.3
  • cabal-install: 3.0.0.0

@phadej
Copy link
Collaborator Author

phadej commented Apr 14, 2020

@emlautarom1 thanks for trying it out. This is what I was afraid of.

I think we can and should make a special case on Windows. There are two cases, when --install-method=copy or when we could and use symlink.

WIth symlinks I hope that it just works, as the new cabal executable is installed in the different place in the store.

With copy, As far as I understand Windows allows to get the location of running program.

  1. If that's the same location as where we would install an executable (possibleSelfUpgrade)
  2. do the trick.

As I'm looking more closely, it looks like possibleSelfUpgrade relies on win32selfupgrade command which I already removed. Yet, I think we should remove that functionality from v1-install and reinstantiate it into v2-install. We should be able to capture the flags v2-install was invoked to, to reinvoke our copy.

@emlautarom1
Copy link
Contributor

emlautarom1 commented Apr 14, 2020

As far as I know, symlinking does not work on Windows, so that should be discarded (At least, I never got it to work). I haven't looked into v1-commands, so I don't know how that handles the upgrading issue.

Could you briefly explain how this trick would work reliably on Windows? I mean:

  • The user wants/needs to upgrade cabal-install.
  • The user runs cabal install cabal-install (Let's assume that install-method = copy and overwrite-policy = always in the config file.
  • Then (?) ...

I'm a Windows-only user so having a reliable way of managing cabal-install (and GHC for that matter) is practically a must.


Edit: Correction, according to #6519 symlinking should be supported on Windows. Yet, it does not work on my machine (I have developer mode enabled). I'm sharing the output of running:

> pwd
C:\Users\Ryzen\Desktop
> .\cabal install -v3 cabal-install --install-method=symlink > log.txt

I'm running cabal-install v. 3.2.0.0 from my Desktop and the operation fails. Here it's the
Log File

@phadej
Copy link
Collaborator Author

phadej commented Apr 14, 2020

@emlautarom1 that feature is not in 3.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants