Skip to content

Commit

Permalink
Add min max cli args (#5)
Browse files Browse the repository at this point in the history
* Create dependabot.yml

Signed-off-by: thepetk <[email protected]>

* Update dependabot.yml

Signed-off-by: thepetk <[email protected]>

* Update realease.yaml (#2)

Signed-off-by: thepetk <[email protected]>

* adding proposal for dockerfile components (#3)

Signed-off-by: Michael Hoang <[email protected]>
Signed-off-by: thepetk <[email protected]>

* Merge all test resources (#6)

* Update test paths

Signed-off-by: thepetk <[email protected]>

* Update angular test resource

Signed-off-by: thepetk <[email protected]>

* Remove projectAngularjs

Signed-off-by: thepetk <[email protected]>

* Update containerfile test

Signed-off-by: thepetk <[email protected]>

* Update django test resources

Signed-off-by: thepetk <[email protected]>

* Update docker compose test resources

Signed-off-by: thepetk <[email protected]>

* Update tests for docker compose with ports

Signed-off-by: thepetk <[email protected]>

* Update test project dockerfile

Signed-off-by: thepetk <[email protected]>

* Update express js port tests

Signed-off-by: thepetk <[email protected]>

* Update flask port tests

Signed-off-by: thepetk <[email protected]>

* Update golang test resources

Signed-off-by: thepetk <[email protected]>

* Update jboss test resources

Signed-off-by: thepetk <[email protected]>

* Update laravel test resources

Signed-off-by: thepetk <[email protected]>

* Update test micronaut resources

Signed-off-by: thepetk <[email protected]>

* Update container docker file nested tests

Signed-off-by: thepetk <[email protected]>

* Update nuxt and next js tests

Signed-off-by: thepetk <[email protected]>

* Update port test for quarkus

Signed-off-by: thepetk <[email protected]>

* Update reactjs tests

Signed-off-by: thepetk <[email protected]>

* Remove port test project quarkus

Signed-off-by: thepetk <[email protected]>

* Update rest of port tests

Signed-off-by: thepetk <[email protected]>

* Fix issue with ip host go format

Signed-off-by: thepetk <[email protected]>

* Update test resources

Signed-off-by: thepetk <[email protected]>

* Finalize new component detection format

Signed-off-by: thepetk <[email protected]>

---------

Signed-off-by: thepetk <[email protected]>

* Run tidy

Signed-off-by: thepetk <[email protected]>

* Update devfile_recognizer and models

Signed-off-by: thepetk <[email protected]>

* Update cli

Signed-off-by: thepetk <[email protected]>

* Update docs

Signed-off-by: thepetk <[email protected]>

* Add test cases for versions cli args

Signed-off-by: thepetk <[email protected]>

* Fix sec alert

Signed-off-by: thepetk <[email protected]>

* Fix typo

Signed-off-by: thepetk <[email protected]>

---------

Signed-off-by: thepetk <[email protected]>
Signed-off-by: Michael Hoang <[email protected]>
Co-authored-by: Michael Hoang <[email protected]>
  • Loading branch information
thepetk and mike-hoang authored Jul 6, 2023
1 parent a0f1c3c commit e1434c1
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 17 deletions.
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
- package-ecosystem: "gomod" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ $ go build alizer.go
```

```sh
--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`.
--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.
```

Expand All @@ -53,7 +54,10 @@ $ go build alizer.go
```

```sh
--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`.
--registry strings registry where to download the devfiles. Default value: https://registry.devfile.io
--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.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.7.0
github.com/go-logr/logr v1.2.4
github.com/hashicorp/go-version v1.6.0
github.com/moby/buildkit v0.11.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.sum
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
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/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
Expand Down
11 changes: 11 additions & 0 deletions pkg/apis/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,24 @@ 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
}

type DevfileFilter struct {
MinVersion string
MaxVersion string
}

type ApplicationFileInfo struct {
Dir string
File string
Expand Down
92 changes: 79 additions & 13 deletions pkg/apis/recognizer/devfile_recognizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ import (

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

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 string, 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) // #nosec G107
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 pkg/cli/devfile/devfile.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package devfile

import (
"github.com/devfile/alizer/pkg/apis/model"
"github.com/devfile/alizer/pkg/apis/recognizer"
"github.com/devfile/alizer/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 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/devfile/alizer/pkg/apis/model"
"github.com/devfile/alizer/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

0 comments on commit e1434c1

Please sign in to comment.