Skip to content
This repository has been archived by the owner on Oct 10, 2023. It is now read-only.

Add min max cli args #234

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ $ go build alizer.go

```sh
--port-detection {docker|compose|source} port detection strategy to use when detecting a port. Currently supported strategies are 'docker', 'compose' and 'source'. You can pass more strategies at the same time. They will be executed in order. By default Alizer will execute docker, compose and source.
--log {debug|info|warning} sets the logging level of the CLI. The arg accepts only 3 values [`debug`, `info`, `warning`]. The default value is `warning` and the logging level is `ErrorLevel`.
```

#### alizer devfile
Expand All @@ -55,6 +56,9 @@ $ go build alizer.go

```sh
--registry strings registry where to download the devfiles. Default value: https://registry.devfile.io
--log {debug|info|warning} sets the logging level of the CLI. The arg accepts only 3 values [`debug`, `info`, `warning`]. The default value is `warning` and the logging level is `ErrorLevel`.
--min-version strings the minimum SchemaVersion of the matched devfile(s). The minimum accepted value is `2.0.0`, otherwise an error is returned.
--max-version strings the maximum SchemaVersion of the matched devfile(s). The minimum accepted value is `2.0.0`, otherwise an error is returned.
```

### Library Package
Expand Down
2 changes: 1 addition & 1 deletion docs/proposals/support_22x_devfiles.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ filter := map[string]interface{} {
"max-version": "2.1.0",
"min-version": "2.0.0",
}
devfiles, err := recognizer.SelectDevFilesFromTypesWithArgs("myproject", devfiles, filter)
devfiles, err := recognizer.MatchDevfiles("myproject", devfiles, filter)
```

### model.DevfileType
Expand Down
1 change: 1 addition & 0 deletions go/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.19
require (
github.com/go-git/go-git/v5 v5.5.1
github.com/go-logr/logr v1.2.4
github.com/hashicorp/go-version v1.6.0
github.com/moby/buildkit v0.10.6
github.com/pkg/errors v0.9.1
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
Expand Down
2 changes: 2 additions & 0 deletions go/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
Expand Down
12 changes: 12 additions & 0 deletions go/pkg/apis/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,23 @@ type Component struct {
Ports []int
}

type Version struct {
SchemaVersion string
Default bool
Version string
}

type DevFileType struct {
Name string
Language string
ProjectType string
Tags []string
Versions []Version
}

type DevfileFilter struct {
MinVersion string
MaxVersion string
}

type ApplicationFileInfo struct {
Expand Down
92 changes: 79 additions & 13 deletions go/pkg/apis/recognizer/devfile_recognizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@ import (
"regexp"
"strings"

"github.com/hashicorp/go-version"
"github.com/redhat-developer/alizer/go/pkg/apis/model"
"github.com/redhat-developer/alizer/go/pkg/utils"
)

const MinimumAllowedVersion = "2.0.0"

func SelectDevFilesFromTypes(path string, devFileTypes []model.DevFileType) ([]int, error) {
alizerLogger := utils.GetOrCreateLogger()
ctx := context.Background()
Expand Down Expand Up @@ -102,15 +105,31 @@ func SelectDevFileUsingLanguagesFromTypes(languages []model.Language, devFileTyp
return devFilesIndexes[0], nil
}

func MatchDevfiles(path, url string, filter model.DevfileFilter) ([]model.DevFileType, error) {
alizerLogger := utils.GetOrCreateLogger()
alizerLogger.V(0).Info("Starting devfile matching")
alizerLogger.V(1).Info(fmt.Sprintf("Downloading devfiles from registry %s", url))
devFileTypesFromRegistry, err := downloadDevFileTypesFromRegistry(url, filter)
if err != nil {
return []model.DevFileType{}, err
}

return selectDevfiles(path, devFileTypesFromRegistry)
}

func SelectDevFilesFromRegistry(path string, url string) ([]model.DevFileType, error) {
alizerLogger := utils.GetOrCreateLogger()
alizerLogger.V(0).Info("Starting devfile matching")
alizerLogger.V(1).Info(fmt.Sprintf("Downloading devfiles from registry %s", url))
devFileTypesFromRegistry, err := downloadDevFileTypesFromRegistry(url)
devFileTypesFromRegistry, err := downloadDevFileTypesFromRegistry(url, model.DevfileFilter{MinVersion: "", MaxVersion: ""})
if err != nil {
return []model.DevFileType{}, err
}
alizerLogger.V(1).Info(fmt.Sprintf("Fetched %d devfiles", len(devFileTypesFromRegistry)))

return selectDevfiles(path, devFileTypesFromRegistry)
}

func selectDevfiles(path string, devFileTypesFromRegistry []model.DevFileType) ([]model.DevFileType, error) {
indexes, err := SelectDevFilesFromTypes(path, devFileTypesFromRegistry)
if err != nil {
return []model.DevFileType{}, err
Expand All @@ -122,10 +141,11 @@ func SelectDevFilesFromRegistry(path string, url string) ([]model.DevFileType, e
}

return devFileTypes, nil

}

func SelectDevFileFromRegistry(path string, url string) (model.DevFileType, error) {
devFileTypes, err := downloadDevFileTypesFromRegistry(url)
devFileTypes, err := downloadDevFileTypesFromRegistry(url, model.DevfileFilter{MinVersion: "", MaxVersion: ""})
if err != nil {
return model.DevFileType{}, err
}
Expand All @@ -137,17 +157,63 @@ func SelectDevFileFromRegistry(path string, url string) (model.DevFileType, erro
return devFileTypes[index], nil
}

func downloadDevFileTypesFromRegistry(url string) ([]model.DevFileType, error) {
url = adaptUrl(url)
// Get the data
resp, err := http.Get(url)
func GetUrlWithVersions(url, minVersion, maxVersion string) (string, error) {
minAllowedVersion, err := version.NewVersion(MinimumAllowedVersion)
if err != nil {
// retry by appending index to url
url = appendIndexPath(url)
resp, err = http.Get(url)
return "", nil
}

if minVersion != "" && maxVersion != "" {
minV, err := version.NewVersion(minVersion)
if err != nil {
return url, nil
}
maxV, err := version.NewVersion(maxVersion)
if err != nil {
return url, nil
}
if maxV.LessThan(minV) {
return "", fmt.Errorf("max-version cannot be lower than min-version")
}
if maxV.LessThan(minAllowedVersion) || minV.LessThan(minAllowedVersion) {
return "", fmt.Errorf("min and/or max version are lower than the minimum allowed version (2.0.0)")
}

return fmt.Sprintf("%s?minSchemaVersion=%s&maxSchemaVersion=%s", url, minVersion, maxVersion), nil
} else if minVersion != "" {
minV, err := version.NewVersion(minVersion)
if err != nil {
return "", nil
}
if minV.LessThan(minAllowedVersion) {
return "", fmt.Errorf("min version is lower than the minimum allowed version (2.0.0)")
}
return fmt.Sprintf("%s?minSchemaVersion=%s", url, minVersion), nil
} else if maxVersion != "" {
maxV, err := version.NewVersion(maxVersion)
if err != nil {
return []model.DevFileType{}, err
return "", nil
}
if maxV.LessThan(minAllowedVersion) {
return "", fmt.Errorf("max version is lower than the minimum allowed version (2.0.0)")
}
return fmt.Sprintf("%s?maxSchemaVersion=%s", url, maxVersion), nil
} else {
return url, nil
}
}

func downloadDevFileTypesFromRegistry(url string, filter model.DevfileFilter) ([]model.DevFileType, error) {
url = adaptUrl(url)
tmpUrl := appendIndexPath(url)
url, err := GetUrlWithVersions(tmpUrl, filter.MinVersion, filter.MaxVersion)
if err != nil {
return nil, err
}
// This value is set by the user in order to configure the registry
resp, err := http.Get(url) //nolint

Check failure

Code scanning / gosec

Potential HTTP request made with variable url

Potential HTTP request made with variable url
if err != nil {
return []model.DevFileType{}, err
}
defer func() error {
if err := resp.Body.Close(); err != nil {
Expand Down Expand Up @@ -177,9 +243,9 @@ func downloadDevFileTypesFromRegistry(url string) ([]model.DevFileType, error) {

func appendIndexPath(url string) string {
if strings.HasSuffix(url, "/") {
return url + "index"
return url + "v2index"
}
return url + "/index"
return url + "/v2index"
}

func adaptUrl(url string) string {
Expand Down
13 changes: 10 additions & 3 deletions go/pkg/cli/devfile/devfile.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package devfile

import (
"github.com/redhat-developer/alizer/go/pkg/apis/model"
"github.com/redhat-developer/alizer/go/pkg/apis/recognizer"
"github.com/redhat-developer/alizer/go/pkg/utils"
"github.com/spf13/cobra"
)

var logLevel, registry string
var logLevel, registry, minVersion, maxVersion string

func NewCmdDevfile() *cobra.Command {
devfileCmd := &cobra.Command{
Expand All @@ -17,6 +18,8 @@ func NewCmdDevfile() *cobra.Command {
Run: doSelectDevfile,
}
devfileCmd.Flags().StringVar(&logLevel, "log", "", "log level for alizer. Default value: error. Accepted values: [debug, info, warning]")
devfileCmd.Flags().StringVar(&minVersion, "min-version", "", "minimum version of devfile schemaVersion. Minimum allowed version: 2.0.0")
devfileCmd.Flags().StringVar(&maxVersion, "max-version", "", "maximum version of devfile schemaVersion. Minimum allowed version: 2.0.0")
devfileCmd.Flags().StringVarP(&registry, "registry", "r", "", "registry where to download the devfiles. Default value: https://registry.devfile.io")
return devfileCmd
}
Expand All @@ -27,12 +30,16 @@ func doSelectDevfile(cmd *cobra.Command, args []string) {
return
}
if registry == "" {
registry = "https://registry.devfile.io/index"
registry = "https://registry.devfile.io/"
}
err := utils.GenLogger(logLevel)
if err != nil {
utils.PrintWrongLoggingLevelMessage(cmd.Name())
return
}
utils.PrintPrettifyOutput(recognizer.SelectDevFilesFromRegistry(args[0], registry))
filter := model.DevfileFilter{
MinVersion: minVersion,
MaxVersion: maxVersion,
}
utils.PrintPrettifyOutput(recognizer.MatchDevfiles(args[0], registry, filter))
}
96 changes: 96 additions & 0 deletions go/test/apis/devfile_recognizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ package recognizer
* Red Hat, Inc.
******************************************************************************/
import (
"fmt"
"testing"

"github.com/redhat-developer/alizer/go/pkg/apis/model"
"github.com/redhat-developer/alizer/go/pkg/apis/recognizer"
"github.com/stretchr/testify/assert"
)

func TestDetectQuarkusDevfile(t *testing.T) {
Expand Down Expand Up @@ -133,6 +135,100 @@ func TestDetectLaravelDevfile(t *testing.T) {
detectDevFiles(t, "laravel", []string{"php-laravel"})
}

func TestGetUrlWithVersions(t *testing.T) {
tests := []struct {
name string
minVersion string
maxVersion string
testUrl string
expectedError error
expectedUrl string
}{
{

name: "Case 1: Url with valid min and max versions",
minVersion: "2.0.0",
maxVersion: "2.2.0",
testUrl: "http://localhost:5000/",
expectedError: nil,
},
{
name: "Case 2: Url with valid min version",
minVersion: "2.0.0",
maxVersion: "",
testUrl: "http://localhost:5000",
expectedError: nil,
},
{
name: "Case 3: Url with valid max version",
minVersion: "",
maxVersion: "2.2.0",
testUrl: "http://localhost:5000/",
expectedError: nil,
},
{
name: "Case 4: Url with max version lower than min version",
minVersion: "2.2.0",
maxVersion: "2.1.0",
testUrl: "http://localhost:5000/v2index",
expectedError: fmt.Errorf("max-version cannot be lower than min-version"),
},
{
name: "Case 5: Url with max version lower than minimum allowed version",
minVersion: "0.1.0",
maxVersion: "1.1.0",
testUrl: "http://localhost:5000/v2index",
expectedError: fmt.Errorf("min and/or max version are lower than the minimum allowed version (2.0.0)"),
},
{
name: "Case 6: Url with max version lower than minimum allowed version & minVersion",
minVersion: "2.1.0",
maxVersion: "1.1.0",
testUrl: "http://localhost:5000/v2index",
expectedError: fmt.Errorf("max-version cannot be lower than min-version"),
},
{
name: "Case 7: Url with min version lower than minimum allowed version",
minVersion: "1.1.0",
maxVersion: "",
testUrl: "http://localhost:5000/v2index",
expectedError: fmt.Errorf("min version is lower than the minimum allowed version (2.0.0)"),
},
{
name: "Case 8: Url with max version lower than minimum allowed version",
minVersion: "",
maxVersion: "1.1.0",
testUrl: "http://localhost:5000/v2index",
expectedError: fmt.Errorf("max version is lower than the minimum allowed version (2.0.0)"),
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := recognizer.GetUrlWithVersions(tt.testUrl, tt.minVersion, tt.maxVersion)
if err != nil {
assert.EqualValues(t, tt.expectedError, err)
} else {
assert.EqualValues(t, getExceptedVersionsUrl(tt.testUrl, tt.minVersion, tt.maxVersion, tt.expectedError), result)
}
})
}
}

func getExceptedVersionsUrl(url, minVersion, maxVersion string, err error) string {
if err != nil {
return ""
} else if minVersion != "" && maxVersion != "" {
return fmt.Sprintf("%s?minSchemaVersion=%s&maxSchemaVersion=%s", url, minVersion, maxVersion)
} else if minVersion != "" {
return fmt.Sprintf("%s?minSchemaVersion=%s", url, minVersion)
} else if maxVersion != "" {
return fmt.Sprintf("%s?maxSchemaVersion=%s", url, maxVersion)
} else {
return url
}
}

func detectDevFiles(t *testing.T, projectName string, devFilesName []string) {
detectDevFilesFunc := func(devFileTypes []model.DevFileType) ([]int, error) {
testingProjectPath := GetTestProjectPath(projectName)
Expand Down