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: Support for Linux distro packages like deb or rpm #71

Open
breml opened this issue Mar 20, 2021 · 7 comments
Open

Feature Request: Support for Linux distro packages like deb or rpm #71

breml opened this issue Mar 20, 2021 · 7 comments
Labels
question Further information is requested

Comments

@breml
Copy link
Collaborator

breml commented Mar 20, 2021

Some tools offer releases also as .deb, .rpm or similar Linux distribution packages additional to the releases packages as .zip or .tar.gz. Often the Linux distribution specific package has some additional benefits like the installation of man pages or default configuration files. Therefore in some cases I would prefer to install the Linux distribution package.

But with these packages I currently suffer from the same problem as with the direct installation of binaries, that is, I don't have an easy way of tracking updates these packages.

Therefore it would be beneficial, if bin could fill this gap as well. I think bin would be suited for this use case, because it already "knows" how to handle github releases and finding the correct packages. Also it is able to compare the local version with the remote ones.

The only thing that is missing is, a provider to install such packages. For this to work, the current behavior would need to be changed, because the installation is no longer just copying the selected file to the correct location, but saving the file temporarily and let an other tool perform the installation.

@sirlatrom sirlatrom added the question Further information is requested label Mar 20, 2021
@marcosnils
Copy link
Owner

marcosnils commented Mar 20, 2021

But with these packages I currently suffer from the same problem as with the direct installation of binaries, that is, I don't have an easy way of tracking updates these packages.

Well if you install rpm or deb files with apt / yum you can easily keep track of those packages right? Not sure what the pain point really is here though..

Usually for projects that generate rpm and deb bundles they usually also publish them in corresponding PPA / YUM repos. Not sure if this is something that's worth adding to bin. However, let's leave this issue open to open it up for discussion.

Therefore it would be beneficial, if bin could fill this gap as well. I think bin would be suited for this use case, because it already "knows" how to handle github releases and finding the correct packages. Also it is able to compare the local version with the remote ones.

Still not understanding what the use-case would be...

@breml
Copy link
Collaborator Author

breml commented Mar 21, 2021

But with these packages I currently suffer from the same problem as with the direct installation of binaries, that is, I don't have an easy way of tracking updates these packages.

Well if you install rpm or deb files with apt / yum you can easily keep track of those packages right? Not sure what the pain point really is here though..

I do not agree with you on this topic. I am not talking about installing an deb / rpm via a official or inofficial repository nor about using some sort of ppa.
What I am talking about is installing a plain rpm / deb file e.g. from https://github.com/rclone/rclone/releases/tag/v1.54.1
If I install the deb file on my ubuntu, this tool will never get updates and I have to check for updates manually. While there are other archives available as well, the user experience is not the same, because the deb does install the man pages as well, while installing it with bin does not (which renders some parts of the help useless).

Usually for projects that generate rpm and deb bundles they usually also publish them in corresponding PPA / YUM repos. Not sure if this is something that's worth adding to bin. However, let's leave this issue open to open it up for discussion.

I think it is worth mentioning, that a lot (if not most) of the Go based releases are created by https://github.com/goreleaser/goreleaser, which does support the creation of deb and rpm packages. The process of providing just the deb / rpm packages as releases on Github is an easy thing to do with goreleaser. And unfortunately, most of them do not provide a PPA.

The main reason, why I like bin is, it gives me an easy way of tracking updates for the tools I install this way and I would like to extend this feature to deb and rpm.

Therefore it would be beneficial, if bin could fill this gap as well. I think bin would be suited for this use case, because it already "knows" how to handle github releases and finding the correct packages. Also it is able to compare the local version with the remote ones.

Still not understanding what the use-case would be...

The use case is: install and keep up to date deb and rpm which are released on Github release page only (without PPA or other repository).

@breml
Copy link
Collaborator Author

breml commented Mar 21, 2021

Here some additional examples I currently install by using the deb packages and that I would like to have an easy way of keeping track of updates:

Just to give some examples. In some cases, switching to an other archive type would be possible, in some cases, this is not possible.

I guess, I could even life with a solution, which only keeps track of the downloaded version of the deb / rpm and the installation would be an additional manual step, because installing deb / rpm does need root permissions and this is currently out of scope for bin.

@marcosnils
Copy link
Owner

I guess, I could even life with a solution, which only keeps track of the downloaded version of the deb / rpm and the installation would be an additional manual step, because installing deb / rpm does need root permissions and this is currently out of scope for bin.

I see your point and I agree it's not bin responsibility to install those packages as well but we can do something to help the user keep track of updates since we already do that for stand alone binaries.

I have some ideas / questions that it'd be nice to discuss before moving forward with that

Q: How do we add a feature to let users select a file regardless bin automatic selection? i.e if I do bin install https://github.com/profclems/glab/ it'll automatically pick the tar.gz file since it's the "correct one" from the automatic selection process. At one point I thought we could add something like bin install --filter '*.deb' <url> to make it more powerfull, since if your filter returns a single candidate, the "install/download" process can continue as usual

I: An idea to implement is to allow configuring bin to run specific commands after a specific extension has been downloaded. Since we don't want bin to handle installation, we could just add a hooks system that just calls dpkg -i <file> after it's done downloading it.

@breml
Copy link
Collaborator Author

breml commented Mar 21, 2021

I have some ideas / questions that it'd be nice to discuss before moving forward with that

I am happy to discuss this.

Q: How do we add a feature to let users select a file regardless bin automatic selection? i.e if I do bin install https://github.com/profclems/glab/ it'll automatically pick the tar.gz file since it's the "correct one" from the automatic selection process. At one point I thought we could add something like bin install --filter '*.deb' <url> to make it more powerfull, since if your filter returns a single candidate, the "install/download" process can continue as usual

I mentioned in #53 (comment), that I started to implement my own tool, before I discovered bin. In this tool I offered the user an option in the config file, where the user has the possibility to define a priority list of archive types. In this list, as an ubuntu user I would place deb at the beginning of the list whereas I would completely omit rpm. Normally I prefer compressed tar over zip, so I would put the tar extensions before zip in the list.

Just today I had the situation, where bin offered me the tar.gz and the zip as options, because the author of said tool offers both possibilities. But in this case I do not want to select manually, the tools should just pick based on my priorities (in this particular case, there is likely no difference at all for the result).

I: An idea to implement is to allow configuring bin to run specific commands after a specific extension has been downloaded. Since we don't want bin to handle installation, we could just add a hooks system that just calls dpkg -i <file> after it's done downloading it.

For this use case, I assume we would need a different target folder for the download, because I would prefer not to have the *.deb files downloaded to my ~/bin folder. But we need to persist these files somewhere in order to let the post-download-script pick up the file and install it.

@breml
Copy link
Collaborator Author

breml commented Mar 23, 2021

I did some thinking about this. I understand, that the initial idea of bin is defined in the README.md as follows:

bin started as an idea given the popularity of single binary releases ...

So currently the scope is limited to single binary releases. Nevertheless I would like to propose a slight extension of the current code structure, which would allow for easier addition of other use cases like support for extracting the full content of archives (#53) and deb / rpm (#71, this issue).

As I understand bin, it has roughly the following process for the install, update and ensure commands:

┌──────────────────┐
│                  │
│      Start       │ (mainly for the commands install, update and ensure)
│                  │
└────────┬─────────┘
         │
         │resolve Provider
         │
┌────────▼─────────┐
│                  │
│     Provider     │ (like today, select the provider based on characteristics of the URL)
│                  │
└────────┬─────────┘
         │
         │list
         │
┌────────▼─────────┐
│                  │
│    Candidates    │
│                  │
└────────┬─────────┘
         │
         │filter / select (automatically by Arch, OS, Version, prefered Archive type; manually)
         │
┌────────▼─────────┐
│                  │
│     Target       │
│                  │
└────────┬─────────┘
         │
         │get
         │
┌────────▼─────────┐
│                  │
│     Archive      │ (regular archives like zip, tar.gz, but also "archives" like single executable, deb or rpm)
│                  │
└────────┬─────────┘
         │
         │unarchive
         │
┌────────▼─────────┐
│                  │
│     Content      │ (maybe this could be implemented as in memory io/fs.FS)
│                  │
└────────┬─────────┘
         │
         │process / install (this could mean different things depending on user selection or type of archive)
         │
┌────────▼─────────┐
│                  │
│       End        │
│                  │
└──────────────────┘

Some parts are already abstracted pretty well (e.g. support for different providers, support for different archive types), some parts are currently not abstracted at all (e.g. saveToDisk).
If we could agree some easy to implement interfaces, several different implementations could life next to each other and the user would have the possibility to select the outcome he would like to have.

So for the stages mentioned above I propose interfaces like this (the interfaces might not yet be complete):

type Provider interface {
  List() ([]assets.Asset, error)
  Get(asset.Asset) (io.Reader, error)
}

// Filter work like middlewares and are therefore chainable,
// the result is an ordered list of assets.Asset, where the asset.Asset with the highest priority has index 0.
// So there could be strict filters, that remove non matching items from the list or even
// a manual filter, which just returns a list with one (the maually selected) item.
type Filter func([]assets.Asset) []assets.Asset

// Archive converts a io.Reader to a fs.FS (more specific testing/fstest.MemFS). For a zip archive, the fs.FS contains all files.
// For an executable binary, the fs.FS just contains a single file, the executable binary it self.
// The same would apply for deb / rpm files, because we do not unarchive these files in bin
// but pass them "as is" to the next stage.
type Archive interface {
  Unarchive(io.Reader) (fs.FS, error)
}

// Install functions take a fs.FS and perform the actual installation to disk.
// For the current behavior of bin, this boils down to selecting the binary executable
// and copy it to the target directory. For a different implementation of Install this could
// mean, to save the whole content of the fs.FS to an other target directory
// and only link the binary to the binaries directory. For deb / rpm, this would store
// the content of the fs.FS to a temporary folder and launch dpkg or rpm for the
// installation.
//
// Eventually, the install command could be wrapped with "middlewares" as well, which
// would allow to filter the content of the fs.FS (e.g. automatically exclude files or manually
// select the files, that should get installed.
type Install func(fs.FS) error

I am pretty sure, the signatures of the functions are not yet correct nor the interfaces complete. But I hope to provide some thoughts how bin could be evolved further.

I look forward to your thoughts.

Repository owner deleted a comment from luis33338 Mar 26, 2021
Repository owner deleted a comment from luis33338 Mar 26, 2021
Repository owner deleted a comment from luis33338 Mar 26, 2021
Repository owner deleted a comment from luis33338 Mar 26, 2021
@pataquets
Copy link

Dropping as suggestion Github's gh CLI extension:
redraw/gh-install: install GitHub release binaries from the CLI interactively

I mainly use bin and find it the easiest method.
However, where bin does not work, I fall back to gh install.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants