Skip to content

Commit

Permalink
support multiple args for local
Browse files Browse the repository at this point in the history
  • Loading branch information
leucos committed Jun 27, 2024
1 parent bb293b3 commit aa0f5d2
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 34 deletions.
38 changes: 32 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ The last binary you'll ever install.
- [Version selection process](#version-selection-process)
- [Install versions form .binenv.lock](#install-versions-form-binenvlock)
- [Example](#example-1)
- [Selecting versions using environment variables](#selecting-versions-using-environment-variables)
- [Example](#example-2)
- [Adding versions to `.binenv.lock`](#adding-versions-to-binenvlock)
- [Environment variables](#environment-variables)
- [Removing binenv stuff](#removing-binenv-stuff)
- [Status](#status)
Expand Down Expand Up @@ -503,7 +502,7 @@ For this, it will check for a `.binenv.lock` file in the current directory.

If none is found, it will check in the parent folder. No lock file ? Check in
parent folder again. this process continues until `binenv` reaches your home
directory.
directory (or `/` if run in global mode).

If no version requirements are found at this point, `binenv` will use the last
non-prerelease version installed.
Expand All @@ -530,7 +529,32 @@ fetching hadolint version 1.16.3 100% |█████████████
$
```

## Selecting versions using environment variables
### Adding versions to `.binenv.lock`

To populate the `.binenv.lock` file in the current directory, you can use the
`local` command with the distributions and versions you want to add.

For instance:

```bash
binenv local kubectl 1.30.0 helmfile 0.126.0
```

Note that this will update the `.binenv.lock` file and not replace it, so the
command above is equivalent to:

```bash
binenv local kubectl 1.30.0
binenv local helmfile 0.126.0
```

and produce the following `.binenv.lock` file:

```bash
kubectl=1.30.0


### Selecting versions using environment variables

_Introduced in v0.17.0_

Expand All @@ -542,7 +566,7 @@ When an environment variable with this name exists, binenv will use the `=`
operator to look for an exact match for that constraint and will ignore the
contents of the `.binenv.lock` file if it exists.

### Example
#### Example

```bash
$ cat .binenv.lock
Expand All @@ -557,11 +581,13 @@ version.BuildInfo{Version:"v3.6.3", GitCommit:"d506314abfb5d21419df8c7e7e6801237

## Environment variables

Two other environment variables exist:
Other environment variables exists to control `binenv` behavior:

- `BINENV_GLOBAL`: forces `binenv` to run un global mode (same as `-g`); see
[SYSTEM.md](./SYSTEM.md) for more information on this mode.
- `BINENV_VERBOSE`: same as `-v`
- `BASH_COMP_DEBUG_FILE`: if set, will write debug information for bash
completion to this file

## Removing binenv stuff

Expand Down
3 changes: 1 addition & 2 deletions cmd/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ func localCmd(a *app.App) *cobra.Command {
Short: "Sets local required versions for distributions.",
Long: `This will write the specified version in ".binenv.lock" file in the current directory.
Any previously constraint used in this file for the distribution will be removed, and an exact match ('=') will be used.`,
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
a.Local(args[0], args[1])
a.Local(args...)
},
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
switch len(args) % 2 {
Expand Down
76 changes: 50 additions & 26 deletions internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -522,30 +522,22 @@ func (a *App) uninstall(dist, version string) error {
}

// Local sets the locally used version for application
func (a *App) Local(distribution, version string) error {
func (a *App) Local(specs ...string) error {
var (
mode os.FileMode = 0640
matched = false
errored = false
lines []string
newlines []string
)

if a.global {
mode = 0644
}

versions := a.GetInstalledVersionsFor(distribution)

// Check if distribution is managed by us
if versions == nil {
a.logger.Error().Msgf("no versions found for %q; is it installed ?", distribution)
if len(specs)%2 != 0 && len(specs) != 1 {
a.logger.Error().Msg("invalid number of arguments (must have distribution and version pairs")
os.Exit(1)
}

// Check if version is available
if !stringInSlice(version, versions) {
a.logger.Error().Msgf("version %q for %q is not installed. Please run `binenv install %s %s`.", version, distribution, distribution, version)
os.Exit(1)
if a.global {
mode = 0644
}

// Open local .binenv.lock if exists or create
Expand All @@ -565,20 +557,53 @@ func (a *App) Local(distribution, version string) error {
// Replace or create entry for distribution
lines = strings.Split(string(input), "\n")

for _, line := range lines {
switch {
case line == "":
continue
case strings.HasPrefix(line, distribution+"="):
matched = true
newlines = append(newlines, fmt.Sprintf("%s=%s", distribution, version))
default:
newlines = append(newlines, line)
for i := 0; i < len(specs); i += 2 {
distribution := specs[i]
version := specs[i+1]

versions := a.GetInstalledVersionsFor(distribution)

// Check if distribution is managed by us
if versions == nil {
a.logger.Error().Msgf("no versions found for %q; is it installed ?", distribution)
errored = true
}

// Check if version is available
if !stringInSlice(version, versions) {
a.logger.Error().Msgf("version %q for %q is not installed. Please run `binenv install %s %s`.", version, distribution, distribution, version)
errored = true
}

for i, line := range lines {
switch {
// Keep empty lines for now
case line == "":
continue
// Keep comments (howevere they will be Sort-packed at the top of the file)
case strings.HasPrefix(line, "#"):
continue
case strings.HasPrefix(line, distribution+"="):
matched = true
lines[i] = fmt.Sprintf("%s=%s", distribution, version)
}
}

if !matched {
lines = append(lines, fmt.Sprintf("%s=%s", distribution, version))
}
}

if errored {
os.Exit(1)
}

if !matched {
newlines = append(newlines, fmt.Sprintf("%s=%s", distribution, version))
// Remove empty lines
for _, line := range lines {
if line == "" {
continue
}
newlines = append(newlines, line)
}

// Sort lines
Expand All @@ -591,7 +616,6 @@ func (a *App) Local(distribution, version string) error {
os.Exit(1)
}

// a.logger.Fatal().Msg("not implemented yet")
return nil
}

Expand Down

0 comments on commit aa0f5d2

Please sign in to comment.