Skip to content

Commit

Permalink
Add regexp constraint support (#108)
Browse files Browse the repository at this point in the history
* add regexp constraint support #107
* update README for #107
* update cli help for #107

Signed-off-by: Denis Vaumoron <dvaumoron@gmail.com>
  • Loading branch information
dvaumoron authored Apr 23, 2024
1 parent 49c103a commit 934080c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 19 deletions.
21 changes: 10 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,11 @@ Without a parameter, the version to use is resolved automatically (see resolutio

If a parameter is passed, available options include:

- an exact [Semver 2.0.0](https://semver.org/) version string to install
- a [version constraint](https://opentofu.org/docs/language/expressions/version-constraints) string (checked against versions available at `<TOOL>_REMOTE` url)
- `latest`, `latest-stable` (old name of `latest`) or `latest-pre` (include unstable version), which are checked against versions available at `<TOOL>_REMOTE` url)
- `latest-allowed` or `min-required` to scan your IAC files to detect which version is maximally allowed or minimally required.
See [required_version](#required_version) docs.
- an exact [Semver 2.0.0](https://semver.org/) version string to install.
- a [version constraint](https://opentofu.org/docs/language/expressions/version-constraints) string (checked against versions available at `<TOOL>_REMOTE` url).
- `latest`, `latest-stable` (old name of `latest`) or `latest-pre` (include unstable version), which are checked against versions available at `<TOOL>_REMOTE` url.
- `latest:<re>` or `min:<re>` to get first version matching with `<re>` as a [regexp](https://github.com/google/re2/wiki/Syntax) after a descending or ascending version sort.
- `latest-allowed` or `min-required` to scan your IAC files to detect which version is maximally allowed or minimally required. See [required_version](#required_version) docs.

```console
tenv tofu install
Expand Down Expand Up @@ -258,12 +258,11 @@ Switch the default tool version to use (set in `TENV_ROOT/<TOOL>/version` file).

Available parameter options:

- an exact [Semver 2.0.0](https://semver.org/) version string to use
- a [version constraint](https://opentofu.org/docs/language/expressions/version-constraints) string (checked against versions available in TENV_ROOT directory)
- `latest`, `latest-stable` (old name of `latest`) or `latest-pre` (include unstable version), which are checked against versions available in TENV_ROOT directory
- `latest-allowed` or `min-required` to scan your IAC files to detect which version is maximally allowed or minimally required.

See [required_version](#required_version) docs.
- an exact [Semver 2.0.0](https://semver.org/) version string to use.
- a [version constraint](https://opentofu.org/docs/language/expressions/version-constraints) string (checked against versions available in TENV_ROOT directory).
- `latest`, `latest-stable` (old name of `latest`) or `latest-pre` (include unstable version), which are checked against versions available in TENV_ROOT directory.
- `latest:<re>` or `min:<re>` to get first version matching with `<re>` as a [regexp](https://github.com/google/re2/wiki/Syntax) after a descending or ascending version sort.
- `latest-allowed` or `min-required` to scan your IAC files to detect which version is maximally allowed or minimally required. See [required_version](#required_version) docs.

```console
tenv tofu use v1.6.0-beta5
Expand Down
7 changes: 4 additions & 3 deletions cmd/tenv/subcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@ If a parameter is passed, available options:
descBuilder.WriteString(params.remoteEnvName)
descBuilder.WriteString(" url)\n- latest, latest-stable or latest-pre (checked against version available at ")
descBuilder.WriteString(params.remoteEnvName)
descBuilder.WriteString(" url)\n- latest-allowed or min-required to scan your ")
descBuilder.WriteString(" url)\n- latest:<re> or min:<re> to get first version matching with <re> as a regexp after a version sort\n- latest-allowed or min-required to scan your ")
descBuilder.WriteString(versionManager.FolderName)
descBuilder.WriteString(" files to detect which version is maximally allowed or minimally required.")
descBuilder.WriteString(" files to detect which version is maximally allowed or minimally required")

installCmd := &cobra.Command{
Use: "install [version]",
Expand Down Expand Up @@ -324,9 +324,10 @@ Available parameter options:
- an exact Semver 2.0.0 version string to use
- a version constraint expression (checked against version available in TENV_ROOT directory)
- latest, latest-stable or latest-pre (checked against version available in TENV_ROOT directory)
- latest:<re> or min:<re> to get first version matching with <re> as a regexp after a version sort
- latest-allowed or min-required to scan your `)
descBuilder.WriteString(versionManager.FolderName)
descBuilder.WriteString(" files to detect which version is maximally allowed or minimally required.")
descBuilder.WriteString(" files to detect which version is maximally allowed or minimally required")

workingDir := false

Expand Down
29 changes: 24 additions & 5 deletions versionmanager/semantic/semantic.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
package semantic

import (
"regexp"
"strings"

"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-version"
"github.com/tofuutils/tenv/config"
Expand All @@ -33,6 +36,9 @@ const (
LatestStableKey = "latest-stable"
LatestKey = "latest"
MinRequiredKey = "min-required"

LatestPrefix = "latest:"
MinPrefix = "min:"
)

var TfPredicateReaders = []types.PredicateReader{readTfFiles} //nolint
Expand All @@ -56,12 +62,12 @@ func CmpVersion(v1Str string, v2Str string) int {

func ParsePredicate(behaviourOrConstraint string, displayName string, constraintInfo types.ConstraintInfo, predicateReaders []types.PredicateReader, conf *config.Config) (types.PredicateInfo, error) {
reverseOrder := true
switch behaviourOrConstraint {
case MinRequiredKey:
switch {
case behaviourOrConstraint == MinRequiredKey:
reverseOrder = false // start with older

fallthrough // same predicate retrieving
case LatestAllowedKey:
case behaviourOrConstraint == LatestAllowedKey:
for _, reader := range predicateReaders {
predicate, err := reader(constraintInfo, conf)
if err != nil {
Expand All @@ -75,10 +81,23 @@ func ParsePredicate(behaviourOrConstraint string, displayName string, constraint
conf.Displayer.Display(loghelper.Concat("No ", displayName, " version requirement found in project files, fallback to ", LatestKey, " strategy"))

fallthrough // fallback to latest
case LatestKey, LatestStableKey:
case behaviourOrConstraint == LatestKey, behaviourOrConstraint == LatestStableKey:
return types.PredicateInfo{Predicate: StableVersion, ReverseOrder: true}, nil
case LatestPreKey:
case behaviourOrConstraint == LatestPreKey:
return types.PredicateInfo{Predicate: alwaysTrue, ReverseOrder: true}, nil
case strings.HasPrefix(behaviourOrConstraint, MinPrefix):
reverseOrder = false // start with older

fallthrough // same behaviour
case strings.HasPrefix(behaviourOrConstraint, LatestPrefix):
conf.Displayer.Display("Use of regexp is discouraged, try version constraint instead")

re, err := regexp.Compile(behaviourOrConstraint[strings.Index(behaviourOrConstraint, ":")+1:])
if err != nil {
return types.PredicateInfo{}, err
}

return types.PredicateInfo{Predicate: re.MatchString, ReverseOrder: reverseOrder}, nil
default:
constraint, err := addDefaultConstraint(constraintInfo, conf, behaviourOrConstraint)
if err != nil {
Expand Down

0 comments on commit 934080c

Please sign in to comment.