Skip to content

Commit

Permalink
Add ensure command (#65)
Browse files Browse the repository at this point in the history
* Add ensure command

Fixes: #57

* Add ensure command to README

* Fix formatting

Accoding to markdownlint rules: https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md

* Order commands in README according to help output (alphabetically)
  • Loading branch information
breml authored Mar 20, 2021
1 parent fafdf74 commit bade123
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 29 deletions.
43 changes: 21 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
# bin

Manages bin files downloaded from different sources

![bin](https://user-images.githubusercontent.com/1578458/87901619-ee629a80-ca2d-11ea-8609-8a8eb39801d2.gif)


## 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.
`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 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
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](https://brew.sh) was now supported in linux which almost
After I finished the first MVP, a friend pointed out that [brew](https://brew.sh) 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.
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 brainstrom about possibilities.
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 brainstrom about possibilities.

## Installing

Expand All @@ -30,39 +30,38 @@ be more than happy to brainstrom about possibilities.
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:

```
```shell
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
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:

```
```shell
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 install <repo> [path] # Downloads the latest binary and makes it executable
bin update [bin]... # Scans binaries and prompts for update
bin ls # List current binaries and it's versions
```shell
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 purge # Removes from the DB missing binaries
bin update [bin]... # Scans binaries and prompts for update
```

## FAQ

### 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.

### 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.
73 changes: 73 additions & 0 deletions cmd/ensure.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package cmd

import (
"fmt"
"os"

"github.com/apex/log"
"github.com/fatih/color"
"github.com/marcosnils/bin/pkg/config"
"github.com/marcosnils/bin/pkg/providers"
"github.com/spf13/cobra"
)

type ensureCmd struct {
cmd *cobra.Command
}

func newEnsureCmd() *ensureCmd {
root := &ensureCmd{}
// nolint: dupl
cmd := &cobra.Command{
Use: "ensure",
Aliases: []string{"e"},
Short: "Ensures that all binaries listed in the configuration are present",
SilenceUsage: true,
Args: cobra.MaximumNArgs(0),
SilenceErrors: true,
RunE: func(cmd *cobra.Command, args []string) error {
cfg := config.Get()
binsToProcess := cfg.Bins

// TODO: code smell here, this pretty much does
// the same thing as install logic. Refactor to
// use the same code in both places
for _, binCfg := range binsToProcess {
_, err := os.Stat(binCfg.Path)
if !os.IsNotExist(err) {
continue
}

p, err := providers.New(binCfg.URL, binCfg.Provider)
if err != nil {
return err
}

pResult, err := p.Fetch()
if err != nil {
return err
}

if err = saveToDisk(pResult, binCfg.Path, true); err != nil {
return fmt.Errorf("Error installing binary %w", err)
}

err = config.UpsertBinary(&config.Binary{
RemoteName: pResult.Name,
Path: binCfg.Path,
Version: pResult.Version,
Hash: fmt.Sprintf("%x", pResult.Hash.Sum(nil)),
URL: binCfg.URL,
})
if err != nil {
return err
}
log.Infof("Done ensuring %s to %s", binCfg.Path, color.GreenString(binCfg.Version))
}
return nil
},
}

root.cmd = cmd
return root
}
15 changes: 8 additions & 7 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ func Execute(version string, exit func(int), args []string) {

log.SetHandler(cli.Default)

//fmt.Println()
//defer fmt.Println()
// fmt.Println()
// defer fmt.Println()
newRootCmd(version, exit).Execute(args)
}

Expand All @@ -33,8 +33,8 @@ func (cmd *rootCmd) Execute(args []string) {
}

if err := cmd.cmd.Execute(); err != nil {
var code = 1
var msg = "command failed"
code := 1
msg := "command failed"
if eerr, ok := err.(*exitError); ok {
code = eerr.code
if eerr.details != "" {
Expand All @@ -53,10 +53,10 @@ type rootCmd struct {
}

func newRootCmd(version string, exit func(int)) *rootCmd {
var root = &rootCmd{
root := &rootCmd{
exit: exit,
}
var cmd = &cobra.Command{
cmd := &cobra.Command{
Use: "bin",
Short: "Effortless binary manager",
Version: version,
Expand All @@ -68,7 +68,7 @@ func newRootCmd(version string, exit func(int)) *rootCmd {
log.Debug("debug logs enabled")
}

//check and load config after handlers are configured
// check and load config after handlers are configured
err := config.CheckAndLoad()
if err != nil {
log.Fatalf("Error loading config file %v", err)
Expand All @@ -79,6 +79,7 @@ func newRootCmd(version string, exit func(int)) *rootCmd {
cmd.PersistentFlags().BoolVar(&root.debug, "debug", false, "Enable debug mode")
cmd.AddCommand(
newInstallCmd().cmd,
newEnsureCmd().cmd,
newUpdateCmd().cmd,
newRemoveCmd().cmd,
newListCmd().cmd,
Expand Down

0 comments on commit bade123

Please sign in to comment.