Skip to content
This repository has been archived by the owner on Mar 8, 2022. It is now read-only.

implement gofish switch [food] [version] #7

Open
bacongobbler opened this issue Apr 2, 2018 · 12 comments
Open

implement gofish switch [food] [version] #7

bacongobbler opened this issue Apr 2, 2018 · 12 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@bacongobbler
Copy link
Contributor

change versions from the current release to an older release.

@bacongobbler bacongobbler added enhancement New feature or request good first issue Good for newcomers labels Apr 11, 2018
@bacongobbler bacongobbler changed the title implement fish switch [food] [version] implement gofish switch [food] [version] Apr 14, 2018
@notlmn
Copy link
Contributor

notlmn commented Apr 21, 2018

I don't know if this happens only for Windows but, gofish install <fish-name> moves binaries to C:\ProgramData\bin instead of creating a symlink to the files in barrel/<fish-name>/<fish-version>/.

Even the Powershell script used to install gofish moves gofish.exe to bin.

@bacongobbler
Copy link
Contributor Author

Yeah this is intentional. Only administrators can create symlinks on Windows :(

@notlmn
Copy link
Contributor

notlmn commented Apr 21, 2018

Can you try creating a symbolic link (which should work in Windows 10 build >= 1703), and then fallback to creating a regular shortcut (.lnk file)?

I know lnk files are not standard, limited to only Windows, and dirty to implement, but this should be done to make switching work!?

@bacongobbler
Copy link
Contributor Author

bacongobbler commented Apr 24, 2018

We do that already. See

// SymlinkWithFallback attempts to symlink a file or directory, but falls back to a move operation
// in the event of the user not having the required privileges to create the symlink.
func SymlinkWithFallback(oldname, newname string) (err error) {
err = os.Symlink(oldname, newname)
if runtime.GOOS == "windows" {
// If creating the symlink fails on Windows because the user
// does not have the required privileges, ignore the error and
// fall back to renaming the file.
//
// ERROR_PRIVILEGE_NOT_HELD is 0x522:
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms681385(v=vs.85).aspx
if lerr, ok := err.(*os.LinkError); ok && lerr.Err == syscall.Errno(0x522) {
err = os.Rename(oldname, newname)
}
}
return
}

The only way for symlinks to work properly on Windows is to run your terminal as an administrator. If if fails (such as when running NOT as administrator), we fall back to os.Rename.

@bacongobbler
Copy link
Contributor Author

for example, here's how it looks when running gofish install minikube as an administrator vs as a regular user:

PS C:\WINDOWS\system32> gofish install minikube
==> Installing minikube...
🐠  minikube 0.26.1: installed in 156.0548ms
PS C:\WINDOWS\system32> ls C:\ProgramData\bin


    Directory: C:\ProgramData\bin


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        4/24/2018   7:09 AM       53996032 draft.exe
-a----        4/20/2018  11:49 PM        7806464 gofish.exe
-a----        4/21/2018   6:49 AM        7806464 gofish.exe.rotten
-a----         3/9/2018   2:50 PM       64267776 helm.exe
-a----        4/24/2018  12:43 PM       14301184 kubectl.exe
-a---l        4/24/2018  12:53 PM              0 minikube.exe

As you can see, minikube.exe is now a symlink. When running as an unprivileged user gofish will just move the file to the desired location.

@bacongobbler
Copy link
Contributor Author

bacongobbler commented Apr 24, 2018

Oh... I missed the part of your comment where you mentioned creating Shortcuts instead. Sorry!

Shortcuts won't work because we're also allowing users to symlink more than just executables from the package. For example, one may want to symlink manpages to share/man/, lib files to lib/, configuration in etc/ etc. The same applies to Windows users, though the names may be different.

@notlmn
Copy link
Contributor

notlmn commented Apr 24, 2018

FYI, scoop completely depends on shortcuts.

For example, try installing node. The node installation directory has shortcuts to other directories, and the current version is maintained by using a shortcut named "current" that points to different folders.

@mschwrz
Copy link

mschwrz commented Jul 3, 2019

I would like to give this a try, if no one picked it yet.

@bacongobbler
Copy link
Contributor Author

feel free!

@mschwrz
Copy link

mschwrz commented Jul 5, 2019

To make this work, we need to either provide fish-food for every version we want to install or we need to inject the version, that should be installed, into the lua-script and check if that version exists.
@bacongobbler Which solution do you prefer or do you got any other suggestions on this?

@bacongobbler
Copy link
Contributor Author

bacongobbler commented Jul 5, 2019

There's two train of thoughts:

  1. consider switching to an apt-style repository architecture #130 proposes switching to an apt-style backend, which handles multiple versions of the same package hosted from the same repository. Given how long apt's repository API has been used in production, this appears at first glance to be the better long-term model.
  2. The alternative is to design a versioning system within the git repository similar to Homebrew (in other words, your first idea). @tyrken had an interesting idea in his comment in #130. This could mean less overall work, however I'm concerned about its long-term design especially considering proposals like https://github.com/fishworks/fish-food/issues/1 and Handling dependencies #25

I'm not fond of the idea that the version should be injected into the lua script on-the-fly. That breaks the shasum check, and it also breaks the assumption that the metadata within the lua script is immutable (i.e. for use cases like when we want to check the package signatory via GPG).

I'm personally leaning towards switching out the backend to replicate apt's repository API. However, I haven't had much time to spend taking a look into the spec and how we'd go about implementing such and API (as well as how existing apt repositories are set up today).

@bacongobbler
Copy link
Contributor Author

Okay. I've had a look at a ton of new package managers out there today. Most appear to be following the pattern described in #130, so I'm going to look into how we can accommodate that workflow. I'm looking to implement this for the next release (0.14.0).

Once that's done, gofish switch should be a very quick and simple implementation should someone wish to work on that.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

3 participants