Giter VIP home page Giter VIP logo

bin's Introduction

bin

Manages binary files downloaded from different sources

bin

Rationale

bin started as an idea given the popularity of single binary releases due to the surge of languages like Go, Rust, Deno, etc which can easily produce dynamically and statically compiled binarines.

I found myself downloading binaries (or tarballs) directly from VCS (Github mostly) and then it was hard to keep control and update such dependencies whenever a new version was released. So, with the objective to solve that problem and also looking for something that will allow me to get the latest releases, I created bin. In addition to that, I was also looking for something that doesn't require sudo or root privileges to install these binaries as downloading, making them executable and storing it somewhere in your PATH would be sufficient.

After I finished the first MVP, a friend pointed out that brew was now supported in linux which almost made me abandon the project. After checking out brew (never been an osx user), I found it a bit bloated and seems to be doing way more than what I'm actually needing. So, I've decided to continue bin and hopefully add more features that could result useful to someone else.

If you find bin helpful and you have any ideas or suggestions, please create an issue here or send a PR and I'll be more than happy to brainstorm about possibilities.

Installing

  1. Download bin from the releases
  2. Run ./bin install github.com/marcosnils/bin so bin is managed by bin itself
  3. Run bin ls to make sure bin has been installed correctly. You can now remove the first file you downloaded.
  4. Enjoy!

Usage

Install a release from github with the following command:

bin install github.com/kubernetes-sigs/kind # installs latest Kind release

bin install github.com/kubernetes-sigs/kind/releases/tag/v0.8.0 # installs a specific release

bin install github.com/kubernetes-sigs/kind ~/bin/kind # installs latest on a specific path

You can install Docker images and use them as regular CLIs:

bin install docker://hashicorp/terraform:light # install the `light` tag for terraform

bin install docker://quay.io/calico/node # install the latest version of calico/node
bin ensure # Ensures that all binaries listed in the configuration are present
bin help # Help about any command
bin install <repo> [path] # Downloads the latest binary and makes it executable
bin list # List current binaries and it's versions
bin prune # Removes from the DB missing binaries
bin remove <bin>... # Deletes one or more binaries
bin update [bin]... # Scans binaries and prompts for update

FAQ

Can you give some example tools

Yes. Following list

There are some bugs and the code is not tested

I know... and that's not planning to change any time soon unless I start getting some contributions. I did this as a personal tool and I'll probably be fixing stuff and adding features as I personally need them. Contributions are welcome though and I'll be happy to discuss and review them.

I see releases on Github, but bin does not pick them up

At the moment, bin does only consider the latest release from Github according to the following definition:

The latest release is the most recent non-prerelease, non-draft release, sorted by the created_at attribute. The created_at attribute is the date of the commit used for the release, and not the date when the release was drafted or published.

You can however install a specific pre-release by specifying the URL for the pre-release, e.g. bin install https://github.com/bufbuild/buf/releases/tag/v0.40.0.

I used bin and I got rate limited by Github or want to access private repos, what can I do?

Create a Github personal access token by following the steps in this guide: Creating a personal access token. The access token used with bin does not need any scopes.

Create an environment variable named GITHUB_AUTH_TOKEN with the value of your newly created access token. For example in bash: export GITHUB_AUTH_TOKEN=<your_token_value>.

bin's People

Contributors

0xflotus avatar arush-sal avatar breml avatar cristiand391 avatar darkowlzz avatar ernesto27 avatar interpeix avatar korpa avatar loganlinn avatar marcosnils avatar matheuscscp avatar matipan avatar mbevc1 avatar psvo avatar rverst avatar sascha-andres avatar sirlatrom avatar speier avatar stavrospanakakis avatar yozachar avatar zacwolf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bin's Issues

Use plain repo name for binary

Installing bin using bin yields a binary called bin_0.0.1_Linux_x86_64. However, installing a binary from a docker image yields a script called e.g. terraform.

If it were possible to either strip the arch/os details from the downloaded binary name, or simply to use the last segment of the repo name, it would remove the need for renaming the binary after download, or for explicitly choosing the download path in the install command.

Validation (Signature and Checksum)

bin is a wonderful tool that increases security for lots of users, due to the ease of keeping tools up to date. Thanks!

Speaking of security - some tools offer checksums and or signatures on their release pages.
Checking those would be a very useful addition.

Of course, difficult to implement in detail, e.g. where to get the public key to validate signatures and such.
Still wanted to leave the idea here.

Feature Request: Optimized select for selecting the binary

When presenting the user a list of potential files to select the correct binary from, the following improvements could be applied to improve the user experience:

  • Filter files with extensions, that are most likely not executables or find the files with extensions, that are likely executables (e.g. .exe, .sh and of course no extension)
  • Filter by elements provided in the install url (e.g. repo name in the case of the github provider)
  • Evaluate FileInfo() information from header of archive (e.g. in tar and zip) to find files with executable bit set
  • Order by relevance
  • Inverse order, such that the files with the highest relevance are at the end of the list (and therefore closest to the prompt), this is especially important if the archive contains lots of files and the list might span even multiple pages).
  • Optional: add a fuzzy search like https://github.com/junegunn/fzf or https://github.com/ktr0731/go-fuzzyfinder

hashicorp provider doesn't work with vault

❯ bin install --debug https://releases.hashicorp.com/vault
   • debug logs enabled       
   • Download path set to /home/johann/bin
   • Getting latest release for vault
   ⨯ command failed            error=strconv.ParseInt: parsing "5.1": invalid syntax

Other Hashicorp binaries like terraform, consul, packer or nomad seem to work fine.

Idea: Extract static binary from docker image

A few projects don't release binaries but do release docker images. If it's a static standalone binary and it's on the PATH of a given docker image, we could potentially copy out the binary from the image.

Download Raw

Allow to install a file from a repository without releases.
Usefull for scripts.

Add hub.docker.com as a provider

Description

CLIs are sometimes provided as docker images and allow users to use the CLI without having to worry about installing the binary correct for their architecture.

Usability

Users of bin should be able to install docker images that represent CLIs if they were a regular binary that needs to be downloaded:

bin install hub.docker.com/r/hashicorp/terraform
terraform init

Bug: can't find correct asset for k3sup

Bin version: 0.5.2
OS: Ubuntu 20.04 x86_64

What happened: Trying to install k3sup results in bin wanting to grab the arm64 asset
How to reproduce: bin install github.com/alexellis/k3sup
Output:

$ bin install -f --debug github.com/alexellis/k3sup
   • debug logs enabled       
   • Config directory is: /home/abo/.config/bin
   • Download path set to /home/abo/.local/bin
   • Getting latest release for alexellis/k3sup
   • Removing k3sup.sha256 (URL https://github.com/alexellis/k3sup/releases/download/0.10.2/k3sup.sha256) with score 1 lower than 6
   • Removing k3sup.exe.sha256 (URL https://github.com/alexellis/k3sup/releases/download/0.10.2/k3sup.exe.sha256) with score 1 lower than 6
   • Removing k3sup.exe (URL https://github.com/alexellis/k3sup/releases/download/0.10.2/k3sup.exe) with score 1 lower than 6
   • Removing k3sup-darwin.sha256 (URL https://github.com/alexellis/k3sup/releases/download/0.10.2/k3sup-darwin.sha256) with score 1 lower than 6
   • Removing k3sup-darwin (URL https://github.com/alexellis/k3sup/releases/download/0.10.2/k3sup-darwin) with score 1 lower than 6
   • Removing k3sup-armhf.sha256 (URL https://github.com/alexellis/k3sup/releases/download/0.10.2/k3sup-armhf.sha256) with score 1 lower than 6
   • Removing k3sup-armhf (URL https://github.com/alexellis/k3sup/releases/download/0.10.2/k3sup-armhf) with score 1 lower than 6
   • Keeping k3sup-arm64.sha256 (URL https://github.com/alexellis/k3sup/releases/download/0.10.2/k3sup-arm64.sha256) with highest score 6
   • Keeping k3sup-arm64 (URL https://github.com/alexellis/k3sup/releases/download/0.10.2/k3sup-arm64) with highest score 6
   • Removing k3sup (URL https://github.com/alexellis/k3sup/releases/download/0.10.2/k3sup) with score 1 lower than 6

Multiple matches found, please select one:

 [1] k3sup-arm64
 [2] k3sup-arm64.sha256
 Select an option: 

The problem here is that the author of k3sup has chosen to leave out the arch from the name of the asset meant for Linux x86_64. Given that Linux x86_64 is likely to be the most common, would it be possible to have bin to fallback assets without a specified arch as being Linux x86_64?

Bug: bin remove leads to "corrupt" .bin/config.json file

I added 3 binaries with bin and then removed one of the binaries again with bin remove <binary>.
After this I had a look at the .bin/config.json file and I found, that the file still contains fragments of the removed tool like this:

{
    "default_path": "<redacted>/bin",
    "bins": {
        "<redacted>/bin/bin": {
            "path": "<redacted>/bin/bin",
            "remote_name": "bin",
            "version": "v0.4.0",
            "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
            "url": "github.com/marcosnils/bin",
            "provider": "github"
        },
        "<redacted>/bin/bit": {
            "path": "<redacted>/bin/bit",
            "remote_name": "bit",
            "version": "v1.0.4",
            "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
            "url": "https://github.com/chriswalz/bit/releases/tag/v1.0.4",
            "provider": ""
        }
    }
}
 "<redacted>/bin/syncthing": {
            "path": "<redacted>/bin/syncthing",
            "remote_name": "syncthing",
            "version": "v1.14.0",
            "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
            "url": "github.com/syncthing/syncthing",
            "provider": "github"
        }
    }
}

To me, it looks like the the content of the config file is not reset before the changed config file is written back to disk.

func write() error {

Additionally, I feel like the permissions for this file should not default to 0666 but something more restricted, e.g. 0600 or 0640.

Feature Request: Treating additional args as stdin inputs and coding options arguments as cobra [--]flags

To be able to use Bin in a fully automated "batch" way, I'd like to introduce changes to implement passing option choices as additional arguments.

Currently, arguments seem to be handled in a context-specific way.

Example: Bin install {source} {installdir}
i.e., there's code in /cmd/install.go:48-58 that queries for an additional arg to use as the installdir.

It would be trivial to use this same approach for handling "option choices" by lopping over additional args to treat as the value to use in lieu of a prompt.

It would just have to be assumed that the user provides the arguments in the order they would otherwise be prompted in.

Thoughts?

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

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.

Improvements for headless use

It would be great to have a non-interactive mode where bin does not prompt.

I'm starting to role out bin to all my machines headlessly, using ansible (bin installation, self management and update; bin install example).

Here it is difficult to install some binaries because of the prompt. This could be worked around with, e.g. echo 4 | bin install .....
But update all managed binaries it is impossible because of different prompts.

So basically I'd love to have two features:

  • Choosing a binary or binaries via a parameter (that can be passed multiple times for multiple binaries), that evaluates a regex
  • Storing this parameter in config.json, so it can be evaluated again to make headless udpates possible.

Examples:

Bug: Problem identifying correct release with multiple different releases

Scenario:

abo@ernest:~$ bin install github.com/kubernetes-sigs/kustomize
   • Getting latest release for kubernetes-sigs/kustomize
   ⨯ command failed            error=Could not find any compatible files
abo@ernest:~$ bin install https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv4.1.2
   • Getting kustomize/v4.1.2 release for kubernetes-sigs/kustomize
   • Starting download of https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v4.1.2/kustomize_v4.1.2_linux_amd64.tar.gz
4.97 MiB / 4.97 MiB [-------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 5.74 MiB p/s 1s
   • Copying for kustomize@kustomize/v4.1.2 into /home/abo/.local/bin/kustomize
   • Done installing kustomize kustomize/v4.1.2
abo@ernest:~$ bin update kustomize
   • /home/abo/.local/bin/kustomize kustomize/v4.1.2 -> kyaml/v0.10.19 (https://github.com/kubernetes-sigs/kustomize/releases/tag/kyaml/v0.10.19)

So bin runs into problems when a repo releases multiple different things, which is fair I guess.
Anything we can do to make it possible to install releases from such repos?

Add GitLab provider

I started working on a GitLab provider but failed when I got to the point of actually downloading the binary from a private project. Turns out they don't have the same access control on release assets as on the rest of their API.

I created this issue on GitLab and when/if it gets resolved I will open a PR for GitLab if that is welcome.

https://gitlab.com/gitlab-org/gitlab/-/issues/232704

Bug: bin install github.com/xo/usql installes Windows binary on Linux

When I install github.com/xo/usql on my Linux machine, I get the windows binary installed.

$ bin install github.com/xo/usql
   • Getting latest release for xo/usql
   • Starting download of https://github.com/xo/usql/releases/download/v0.8.2/usql-0.8.2-windows-amd64.zip
14.88 MiB / 14.88 MiB [----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 9.88 MiB p/s 1s
   • Copying for [email protected] into <redacted>/bin/usql.exe
   • Done installing usql.exe v0.8.2

This raises two issues:

  1. I think bin should never install a binary, which can be ruled out by not matching the OS or the ARCH. If bin is not able to find a matching archive, it should fail instead.
  2. bin does not yet support bz2 or bzip2 archives

Bug: bin install -f fails if the target file is not present

In the help text of bin install, the -f flag has the following description:

Force the installation even if the file already exists

Based on this description I would expect the installation to be successful regardless of the fact, if the target is present or not.
In my opinion, this would also match with the commonly known behavior of -f in other tools, e.g. rm -f or cp -f.

This is currently not the case. I get the following error:

⨯ command failed            error=Error installing binary: remove <redacted>/bin/cue: no such file or directory

The root cause for this error is in

err := os.Remove(path)

Feature Request: bin update check mode

I would like to have a check mode (or dry run mode) for the update command. The command should exit with non 0 exit code, if there are updated version found for any installed binary. If no updates are found, the exit code would be 0 and no output would be printed.

This command I would like to execute on a regular basis (e.g. cron or init of my shell).

Bonus: In order to prevent too frequent requests to e.g. the github API, bin could have an option in the config file, how long bin does cache the results from this check update command. This would allow to run the check update command on every init of my shell (these can happen quite frequently, whenever I open a new pane/window in tmux).

Feature request: add a new flag to bypass prompt

I usually run bin update --dry-run, and then pick one binary to update bin update <binary> which ask me to confirm to continue.

I know this prompt helps to avoid updating binaries by accident, but if I'm providing an arg I would like to pass a flag (maybe --yes | -y?) to bypass it.

[Enhancement proposal] Automatically filter out hash files from assets

Example:

$ bin install github.com/docker/compose
   • Getting latest release for docker/compose

Multiple matches found, please select one:

 [1] docker-compose-Linux-x86_64
 [2] docker-compose-Linux-x86_64.sha256
 Select an option:

It should be a fairly easy enhancement to filter out assets ending in .sha256 or .md5 as they are very unlikely to be the assets we want to download and install.

Default path autoconfigure doesn't work

I've just downloaded bin and when I run for the first time I get

⟩ ./bin

Pick a default download dir:

 [1] blah..
 [2] blah..
 [3] ...
 [4] ...
 [5] ...
 Select an option: 5
panic: interface conversion: interface {} is options.LiteralStringer, not string

Same behaviour when delete ~/.bin/config.json

self update

$ bin update                                                                                                           
   • /home/pablo/bin/bin v0.2.1 -> v0.5.1 (https://github.com/marcosnils/bin/releases/tag/v0.5.1)

Do you want to continue? [Y/n] y
   • Getting v0.5.1 release for marcosnils/bin
   • Starting download of https://github.com/marcosnils/bin/releases/download/v0.5.1/bin_0.5.1_Linux_x86_64
13.85 MiB / 13.85 MiB [----------------------------------------------------------------------------------------------------] 100.00% 322.38 KiB p/s 44s
   ⨯ command failed            error=Error installing binary open /home/pablo/bin/bin: text file busy

Bug: bin fails to install github.com/Yash-Handa/logo-ls on Linux

When I try to install github.com/Yash-Handa/logo-ls with:

$ bin install github.com/Yash-Handa/logo-ls
   • Getting latest release for Yash-Handa/logo-ls                                                                                                                                                                                            
   • Starting download of https://github.com/Yash-Handa/logo-ls/releases/download/v1.3.7/logo-ls_Linux_x86_64.tar.gz                                                                                                                          
2.84 MiB / 2.84 MiB [-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 38.54 MiB p/s 0s
                                                                                                                                                                                                                                              
Multiple matches found, please select one:                                                                                                                                                                                                    
                                                                                                                                                                                                                                              
 [1] logo-ls_linux_x86_64/logo-ls.1.gz                                                                                                                                                                                                        
 [2] logo-ls_linux_x86_64/logo-ls                                                                                                                                                                                                             
 [3] logo-ls_linux_x86_64/help.md                                                                                                                                                                                                             
 [4] logo-ls_linux_x86_64/license            
 Select an option: 2                            
   • Copying for [email protected] into <redacted>/bin/logo-ls
   • Done installing logo-ls v1.3.7

and I select the correct file (2), I only get an empty file named logo-ls.
bin selects the correct file to download and presents the correct files, with one small difference:
When I open the respective .tar.gz, I see, that the folder is named logo-ls_Linux_x86_64, but bin presents the folder as logo-ls_linux_x85_64 (all in lower case).

Idea: Parse GitLab release description markdown for links

This idea presumes the merging of #17.

Several projects I've found on GitLab that use the Releases feature don't fill out the Asset Links but instead put links straight in the description markdown.

Example:

... [Linux amd64](https://gitlab.com/davidjpeacock/kurly/-/jobs/artifacts/master/raw/artifacts/linux-amd64/kurly-linux-amd64.tar.gz?job=compile) ...

Using e.g. github.com/yuin/goldmark we could parse the markdown looking for links and add them to the list of asset links, maybe only if no proper asset links were found.

This diff would find such links:

diff --git a/go.mod b/go.mod
index f13da26..6cf0b7d 100644
--- a/go.mod
+++ b/go.mod
@@ -23,6 +23,7 @@ require (
        github.com/opencontainers/image-spec v1.0.1 // indirect
        github.com/spf13/cobra v1.0.0
        github.com/xanzy/go-gitlab v0.33.0
+       github.com/yuin/goldmark v1.2.0
        golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288
        golang.org/x/sys v0.0.0-20191026070338-33540a1f6037
        gopkg.in/VividCortex/ewma.v1 v1.1.1 // indirect
diff --git a/pkg/providers/gitlab.go b/pkg/providers/gitlab.go
index 889125f..352a605 100644
--- a/pkg/providers/gitlab.go
+++ b/pkg/providers/gitlab.go
@@ -16,6 +16,9 @@ import (
        "github.com/h2non/filetype/matchers"
        "github.com/marcosnils/bin/pkg/assets"
        "github.com/xanzy/go-gitlab"
+       "github.com/yuin/goldmark"
+       goldast "github.com/yuin/goldmark/ast"
+       "github.com/yuin/goldmark/text"
 )
 
 type gitLab struct {
@@ -68,6 +71,24 @@ func (g *gitLab) Fetch() (*File, error) {
        for _, link := range release.Assets.Links {
                candidates = append(candidates, &assets.Asset{Name: link.Name, URL: link.URL})
        }
+
+       node := goldmark.DefaultParser().Parse(text.NewReader([]byte(release.Description)))
+       walker := func(n goldast.Node, entering bool) (goldast.WalkStatus, error) {
+               if !entering {
+                       return goldast.WalkContinue, nil
+               }
+               if n.Type() == goldast.TypeInline && n.Kind() == goldast.KindLink {
+                       link := n.(*goldast.Link)
+                       name := string(link.Title)
+                       url := string(link.Destination)
+                       candidates = append(candidates, &assets.Asset{Name: name, URL: url})
+               }
+               return goldast.WalkContinue, nil
+       }
+       if err := goldast.Walk(node, walker); err != nil {
+               return nil, err
+       }
+
        gf, err := assets.FilterAssets(g.repo, candidates)
 
        if err != nil {

Problem with container accepting stdin data

Hi, I have tried to have running the tool described here:
https://www.attosol.com/using-docker-for-distributing-command-line-tools/

The install works fine:
$ bin install docker://attosol/dot2png

… but the utility can't be executed as described in the aforementioned article:
$ cat file.dot | dot2png > file.png
the input device is not a TTY

If called as described, it works fine:
$ cat file.dot | docker run --rm -i attosol/dot2png > file.png

Perhaps the problem is that there is no standard for executing dockerized command line tools (?)

Thanks in advance… 

Update fails

[I] bin update
   • /home/andrewrynhard/workspace/bin/clusterctl v0.3.10 -> v0.3.11 

Do you want to continue? [Y/n] y
   ⨯ command failed            error=Command aborted

Feature Request: Add a possibility to install missing binaries

I would like to have the possibility to copy the .bin/config.json to an other system, download bin and run something like bin ensure to download and install all the binaries listed in .bin/config.json (in the version specified).

Currently, bin list is able to detect missing binaries, but from what I can tell, there is no way to fix the broken state.

Remove incorrectly downloaded binaries

If download gets interrupted somehow (cmd + c or whatever), a corrupted file will be created in the FS.

We should probably download the file to a tmp dir and then move it to the final path once finished.

Bad arch

i try install Cura on Linux x86_64

 bin install https://github.com/Ultimaker/Cura --debug  
   • debug logs enabled       
   • Download path set to /home/pablo/bin
   • Getting latest release for Ultimaker/Cura
   • Keeping ultimaker_cura-4.7.1-win64.msi (URL https://github.com/Ultimaker/Cura/releases/download/4.7.1/Ultimaker_Cura-4.7.1-win64.msi) with highest score 10
   • Checking binary from https://github.com/Ultimaker/Cura/releases/download/4.7.1/Ultimaker_Cura-4.7.1-win64.msi
   • Starting download of https://github.com/Ultimaker/Cura/releases/download/4.7.1/Ultimaker_Cura-4.7.1-win64.msi

Cura does not provide x86_64, instead it provides Appimage.

Expected:

  • if not exist release for your arch and are available AppImage ask if install this.
  • dont install win64 on Linux.

Print usage when no command is supplied.

Bin should print its usage info when executed without any command.

Expected behavior:

$ bin
Effortless binary manager

Usage:
  bin [command]

Available Commands:
  help        Help about any command
  install     Installs the specified project
  list        List binaries managed by bin
  prune       Prunes binaries that no longer exist in the system
  remove      Removes binaries managed by bin
  update      Updates one or multiple binaries managed by bin

Flags:
      --debug     Enable debug mode
  -h, --help      help for bin
  -v, --version   version for bin

Use "bin [command] --help" for more information about a command.

Observed Behavior:

$ bin 

 Path   Version         URL     Status

OS/Arch: Linux/x86
Bin version:

bin version 0.2.0
commit: 1e4d59085ecfa8dd0558d237407382eda76c5d3c
built at: 2020-08-09T15:41:51Z
built by: goreleaser

Feature Request: EXTRACT ALL option for archive (zip/tar/gz/etc) releases

Currently, if a release is in the form of an archive, Bin just lists all the files in the archive and prompts for which (single) file you wish to extract.

I would like to submit a pull request to implement a choice zero (extract all) when a release is an archive file (zip/tar/etc).

Looks like that is handled in: /pkg/assets/assets.go:343-353?

To implement an "Option 0" I would also like to propose the following change to /options/options.go

func SelectWithOptionZero(msg string, optzero string, opts []fmt.Stringer) (interface{}, error){}

…vs going down the interface{} route to "overload" the existing Select function. Just easier for backwards compatibility.

Thoughts?

Check TODO's in the code

We've left a bunch of TODO's in the code while creating bin. Eventually we'll move them to it's own issues as we'll probably have to discuss about them for the moment, the best way to contribute y to check the comments in the code.

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

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.

Originally posted by @breml in #71 (comment)

Update fails if confirmation prompt is given anything except Y

Observed Behaviour:
When trying to update a binary bin prompts for a confirmation as below:

   • /home/arush/go/bin/bin v0.0.1 -> v0.0.2 

Do you want to continue? [Y/n]

If anything except Y if given as a response the prompt fails/exist.

Expected Behaviour:

Apart from Y the other valid response should be y, yes, Yes, YES, or i.e just pressing the enter key.

Allow to update binaries using only the binary name

The way I'm currently updating single binaries is by doing bin update $(which <program>). Even though it's quite nice, I think the UX can be improved by just doing bin update <program>. This shouldn't be difficult to do since the update command could perform this check automatically.

Feature Request: Asset search

Hello,

i really like your project :)
It would be nice if it is possible to specify the binary that i want to download from a group of release assets.

e.g.:
https://github.com/CrunchyData/postgres-operator/releases
There are some assets:

pgo
pgo-bash-completion
...
postgres-operator.4.5.0.tar.gz

That want i want is just to install pgo and pgo-bash-completion.

What do you think of a new cli flag called --regex-search

bin install https://github.com/CrunchyData/postgres-operator --regex-search "^pgo$" ~/.local/bin/pgo
bin install https://github.com/CrunchyData/postgres-operator --regex-search "^pgo-bash" ~/.local/completions/pgo-bash-completion

Best regards

Stefan

Refactor archive recognition

Currently each provider's Fetch function deal with archives on their own, i.e. they test for specific expected archive types which seems redundant.

Feature Request: support pre releases

Currently pre releases are filtered out by bin when checking for releases on Github.

The feature request is to provide an opt-in feature for the user to also use pre releases for install, ensure and update.

Followup to #84.
Releated to #50.

Bug: bin is not able to locate releases on Github for bufbuild/buf

I tried to install with the following command:

$ bin install github.com/bufbuild/buf
   • Getting latest release for bufbuild/buf
   ⨯ command failed            error=GET https://api.github.com/repos/bufbuild/buf/releases/latest: 404 Not Found []

But there are clearly releases available on https://github.com/bufbuild/buf/releases
I have not yet investigated, where bin is failing.

I am using the latest build:

$ bin --version
bin version 0.5.0
commit: 7cec71d7c1b77e3db749c010630a8c36122e2801
built at: 2021-03-24T04:11:25Z
built by: goreleaser

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.