Recognize devfile.yml and .devfile.yml as Devfiles (#7130)

This commit is contained in:
Armel Soro
2023-12-01 12:10:19 +01:00
committed by GitHub
parent 15f663f12a
commit 0f2103e7d7
70 changed files with 1152 additions and 418 deletions

4
go.mod
View File

@@ -9,8 +9,8 @@ require (
github.com/Xuanwo/go-locale v1.1.0 github.com/Xuanwo/go-locale v1.1.0
github.com/blang/semver v3.5.1+incompatible github.com/blang/semver v3.5.1+incompatible
github.com/devfile/alizer v1.2.1 github.com/devfile/alizer v1.2.1
github.com/devfile/api/v2 v2.2.1-alpha.0.20230413012049-a6c32fca0dbd github.com/devfile/api/v2 v2.2.1
github.com/devfile/library/v2 v2.2.1-0.20230524160049-04a8b3fc66c0 github.com/devfile/library/v2 v2.2.2-0.20231102090733-57a7da8b8392
github.com/devfile/registry-support/index/generator v0.0.0-20230322155332-33914affc83b github.com/devfile/registry-support/index/generator v0.0.0-20230322155332-33914affc83b
github.com/devfile/registry-support/registry-library v0.0.0-20221201200738-19293ac0b8ab github.com/devfile/registry-support/registry-library v0.0.0-20221201200738-19293ac0b8ab
github.com/fatih/color v1.15.0 github.com/fatih/color v1.15.0

8
go.sum generated
View File

@@ -367,13 +367,13 @@ github.com/devfile/alizer v1.2.1/go.mod h1:kRCsbXuzCwXIbnSR4xpVZDr8Pl8j01rl+gPfk
github.com/devfile/api/v2 v2.0.0-20211021164004-dabee4e633ed/go.mod h1:d99eTN6QxgzihOOFyOZA+VpUyD4Q1pYRYHZ/ci9J96Q= github.com/devfile/api/v2 v2.0.0-20211021164004-dabee4e633ed/go.mod h1:d99eTN6QxgzihOOFyOZA+VpUyD4Q1pYRYHZ/ci9J96Q=
github.com/devfile/api/v2 v2.0.0-20220117162434-6e6e6a8bc14c/go.mod h1:d99eTN6QxgzihOOFyOZA+VpUyD4Q1pYRYHZ/ci9J96Q= github.com/devfile/api/v2 v2.0.0-20220117162434-6e6e6a8bc14c/go.mod h1:d99eTN6QxgzihOOFyOZA+VpUyD4Q1pYRYHZ/ci9J96Q=
github.com/devfile/api/v2 v2.2.0/go.mod h1:dN7xFrOVG+iPqn4UKGibXLd5oVsdE8XyK9OEb5JL3aI= github.com/devfile/api/v2 v2.2.0/go.mod h1:dN7xFrOVG+iPqn4UKGibXLd5oVsdE8XyK9OEb5JL3aI=
github.com/devfile/api/v2 v2.2.1-alpha.0.20230413012049-a6c32fca0dbd h1:HpGR728CfB6BB9ZuFtQb0UeTIYNFgpuGsuoMOJNMUTM= github.com/devfile/api/v2 v2.2.1 h1:VSX297YqY4C4j4uhn7M0RdZeBaeWqyVi4NnagzEmxu0=
github.com/devfile/api/v2 v2.2.1-alpha.0.20230413012049-a6c32fca0dbd/go.mod h1:qp8jcw12y1JdCsxjK/7LJ7uWaJOxcY1s2LUk5PhbkbM= github.com/devfile/api/v2 v2.2.1/go.mod h1:qp8jcw12y1JdCsxjK/7LJ7uWaJOxcY1s2LUk5PhbkbM=
github.com/devfile/library v1.2.1-0.20211104222135-49d635cb492f/go.mod h1:uFZZdTuRqA68FVe/JoJHP92CgINyQkyWnM2Qyiim+50= github.com/devfile/library v1.2.1-0.20211104222135-49d635cb492f/go.mod h1:uFZZdTuRqA68FVe/JoJHP92CgINyQkyWnM2Qyiim+50=
github.com/devfile/library v1.2.1-0.20220308191614-f0f7e11b17de/go.mod h1:GSPfJaBg0+bBjBHbwBE5aerJLH6tWGQu2q2rHYd9czM= github.com/devfile/library v1.2.1-0.20220308191614-f0f7e11b17de/go.mod h1:GSPfJaBg0+bBjBHbwBE5aerJLH6tWGQu2q2rHYd9czM=
github.com/devfile/library/v2 v2.0.1/go.mod h1:paJ0PARAVy0br13VpBEQ4fO3rZVDxWtooQ29+23PNBk= github.com/devfile/library/v2 v2.0.1/go.mod h1:paJ0PARAVy0br13VpBEQ4fO3rZVDxWtooQ29+23PNBk=
github.com/devfile/library/v2 v2.2.1-0.20230524160049-04a8b3fc66c0 h1:cZPTQyQqZD6zTbrNhS5MU1j/tE+kyDIOgYqeBCu+2to= github.com/devfile/library/v2 v2.2.2-0.20231102090733-57a7da8b8392 h1:UotSxx8+XmqZCoo1cTA9T80Zyxq40Cc3zmO++aepeA4=
github.com/devfile/library/v2 v2.2.1-0.20230524160049-04a8b3fc66c0/go.mod h1:7oEhkC6GW6OKmAP8HbxbaQ+nFbnACQuU7anYhJroltQ= github.com/devfile/library/v2 v2.2.2-0.20231102090733-57a7da8b8392/go.mod h1:WiAmCfdTLHk9Nzn/JMmRZK6Qv8e2GmnI5hE6kA2GgAA=
github.com/devfile/registry-support/index/generator v0.0.0-20220222194908-7a90a4214f3e/go.mod h1:iRPBxs+ZjfLEduVXpCCIOzdD2588Zv9OCs/CcXMcCCY= github.com/devfile/registry-support/index/generator v0.0.0-20220222194908-7a90a4214f3e/go.mod h1:iRPBxs+ZjfLEduVXpCCIOzdD2588Zv9OCs/CcXMcCCY=
github.com/devfile/registry-support/index/generator v0.0.0-20220527155645-8328a8a883be/go.mod h1:1fyDJL+fPHtcrYA6yjSVWeLmXmjCNth0d5Rq1rvtryc= github.com/devfile/registry-support/index/generator v0.0.0-20220527155645-8328a8a883be/go.mod h1:1fyDJL+fPHtcrYA6yjSVWeLmXmjCNth0d5Rq1rvtryc=
github.com/devfile/registry-support/index/generator v0.0.0-20221018203505-df96d34d4273/go.mod h1:ZJnaSLjTKCvGJhWmYgQoQ1O3g78qBe4Va6ZugLmi4dE= github.com/devfile/registry-support/index/generator v0.0.0-20221018203505-df96d34d4273/go.mod h1:ZJnaSLjTKCvGJhWmYgQoQ1O3g78qBe4Va6ZugLmi4dE=

View File

@@ -24,7 +24,7 @@ func (o *DevfileState) GetContent() (DevfileContent, error) {
if err != nil { if err != nil {
return DevfileContent{}, errors.New("error writing file") return DevfileContent{}, errors.New("error writing file")
} }
result, err := o.FS.ReadFile("/devfile.yaml") result, err := o.FS.ReadFile(o.Devfile.Ctx.GetAbsPath())
if err != nil { if err != nil {
return DevfileContent{}, errors.New("error reading file") return DevfileContent{}, errors.New("error reading file")
} }

View File

@@ -9,6 +9,7 @@ import (
"github.com/devfile/library/v2/pkg/devfile/parser" "github.com/devfile/library/v2/pkg/devfile/parser"
context "github.com/devfile/library/v2/pkg/devfile/parser/context" context "github.com/devfile/library/v2/pkg/devfile/parser/context"
"github.com/devfile/library/v2/pkg/testingutil/filesystem" "github.com/devfile/library/v2/pkg/testingutil/filesystem"
. "github.com/redhat-developer/odo/pkg/apiserver-gen/go" . "github.com/redhat-developer/odo/pkg/apiserver-gen/go"
"k8s.io/utils/pointer" "k8s.io/utils/pointer"
@@ -42,7 +43,7 @@ func (o *DevfileState) SetDevfileContent(content string) (DevfileContent, error)
return DevfileContent{}, fmt.Errorf("error parsing devfile YAML: %w", err) return DevfileContent{}, fmt.Errorf("error parsing devfile YAML: %w", err)
} }
o.Devfile = devfile o.Devfile = devfile
o.Devfile.Ctx = context.FakeContext(o.FS, "/devfile.yaml") o.Devfile.Ctx = context.FakeContext(o.FS, o.Devfile.Ctx.GetAbsPath())
return o.GetContent() return o.GetContent()
} }

View File

@@ -8,8 +8,8 @@ import (
"github.com/redhat-developer/odo/pkg/util" "github.com/redhat-developer/odo/pkg/util"
) )
// possibleDevfileNames contains possivle devfile name that should be checked in the context dir. // possibleDevfileNames contains possible devfile name that should be checked in the context dir.
var possibleDevfileNames = [...]string{"devfile.yaml", ".devfile.yaml"} var possibleDevfileNames = [...]string{"devfile.yaml", ".devfile.yaml", "devfile.yml", ".devfile.yml"}
// DevfileFilenamesProvider checks if the context dir contains devfile with possible names from possibleDevfileNames variable, // DevfileFilenamesProvider checks if the context dir contains devfile with possible names from possibleDevfileNames variable,
// else it returns "devfile.yaml" as default value. // else it returns "devfile.yaml" as default value.

View File

@@ -230,32 +230,57 @@ var _ = Describe("odo describe component command tests", func() {
}) })
}) })
When("renaming to hide devfile.yaml file", Label(label), func() { for _, devfileName := range []string{".devfile.yaml", "devfile.yml", ".devfile.yml"} {
devfileName := devfileName
When(fmt.Sprintf("renaming devfile.yaml into a recognized file name: %s", devfileName), Label(label), func() {
BeforeEach(func() {
err := os.Rename("devfile.yaml", devfileName)
Expect(err).NotTo(HaveOccurred())
})
It("should describe the component in the current directory using the acceptable devfile filename", func() {
By("running with json output", func() {
res := helper.Cmd("odo", "describe", "component", "-o", "json").ShouldPass()
stdout, stderr := res.Out(), res.Err()
Expect(helper.IsJSON(stdout)).To(BeTrue())
Expect(stderr).To(BeEmpty())
checkDevfileJSONDescription(stdout, devfileName)
helper.JsonPathContentIs(stdout, "runningIn", "")
helper.JsonPathContentIs(stdout, "devForwardedPorts", "")
helper.JsonPathDoesNotExist(stdout, "runningOn") // Deprecated
helper.JsonPathDoesNotExist(stdout, "platform")
})
By("running with default output", func() {
res := helper.Cmd("odo", "describe", "component").ShouldPass()
stdout := res.Out()
checkDevfileDescription(stdout, false)
Expect(stdout).To(ContainSubstring("Running in: None"))
Expect(stdout).ToNot(ContainSubstring("Forwarded ports"))
Expect(stdout).ToNot(ContainSubstring("Running on:"))
})
})
})
}
When("renaming devfile.yaml into a non-recognized file name", Label(label), func() {
BeforeEach(func() { BeforeEach(func() {
err := os.Rename("devfile.yaml", ".devfile.yaml") err := os.Rename("devfile.yaml", "some-random-file-as-devfile")
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
}) })
It("should describe the component in the current directory using the hidden devfile", func() { It("should not describe the component in the current directory using the acceptable devfile filename", func() {
By("running with json output", func() { By("running with json output", func() {
res := helper.Cmd("odo", "describe", "component", "-o", "json").ShouldPass() res := helper.Cmd("odo", "describe", "component", "-o", "json").ShouldFail()
stdout, stderr := res.Out(), res.Err() stdout, stderr := res.Out(), res.Err()
Expect(helper.IsJSON(stdout)).To(BeTrue()) Expect(helper.IsJSON(stderr)).To(BeTrue())
Expect(stderr).To(BeEmpty()) Expect(stdout).To(BeEmpty())
checkDevfileJSONDescription(stdout, ".devfile.yaml") helper.JsonPathContentContain(stderr, "message", "The current directory does not represent an odo component")
helper.JsonPathContentIs(stdout, "runningIn", "")
helper.JsonPathContentIs(stdout, "devForwardedPorts", "")
helper.JsonPathDoesNotExist(stdout, "runningOn") // Deprecated
helper.JsonPathDoesNotExist(stdout, "platform")
}) })
By("running with default output", func() { By("running with default output", func() {
res := helper.Cmd("odo", "describe", "component").ShouldPass() _, stderr := helper.Cmd("odo", "describe", "component").ShouldFail().OutAndErr()
stdout := res.Out() Expect(stderr).Should(ContainSubstring("The current directory does not represent an odo component"))
checkDevfileDescription(stdout, false)
Expect(stdout).To(ContainSubstring("Running in: None"))
Expect(stdout).ToNot(ContainSubstring("Forwarded ports"))
Expect(stdout).ToNot(ContainSubstring("Running on:"))
}) })
}) })
}) })

View File

@@ -43,7 +43,7 @@ var _ = Describe("odo devfile init command tests", func() {
label := label label := label
var _ = Context("label "+label, Label(label), func() { var _ = Context("label "+label, Label(label), func() {
It("should fail", func() { It("odo init should fail", func() {
By("running odo init with incomplete flags", func() { By("running odo init with incomplete flags", func() {
helper.Cmd("odo", "init", "--name", "aname").ShouldFail() helper.Cmd("odo", "init", "--name", "aname").ShouldFail()
}) })
@@ -76,25 +76,19 @@ var _ = Describe("odo devfile init command tests", func() {
By("using an invalid devfile name", func() { By("using an invalid devfile name", func() {
helper.Cmd("odo", "init", "--name", "aname", "--devfile", "invalid").ShouldFail() helper.Cmd("odo", "init", "--name", "aname", "--devfile", "invalid").ShouldFail()
}) })
By("running odo init in a directory containing a devfile.yaml", func() {
helper.CopyExampleDevFile(
filepath.Join("source", "devfiles", "nodejs", "devfile-registry.yaml"),
filepath.Join(commonVar.Context, "devfile.yaml"),
"")
defer os.Remove(filepath.Join(commonVar.Context, "devfile.yaml"))
err := helper.Cmd("odo", "init").ShouldFail().Err()
Expect(err).To(ContainSubstring("a devfile already exists in the current directory"))
})
By("running odo init in a directory containing a .devfile.yaml", func() { for _, devfileName := range []string{"devfile.yaml", ".devfile.yaml", "devfile.yml", ".devfile.yml"} {
helper.CopyExampleDevFile( devfileName := devfileName
filepath.Join("source", "devfiles", "nodejs", "devfile-registry.yaml"), By("running odo init in a directory containing a "+devfileName, func() {
filepath.Join(commonVar.Context, ".devfile.yaml"), helper.CopyExampleDevFile(
"") filepath.Join("source", "devfiles", "nodejs", "devfile-registry.yaml"),
defer helper.DeleteFile(filepath.Join(commonVar.Context, ".devfile.yaml")) filepath.Join(commonVar.Context, devfileName),
err := helper.Cmd("odo", "init").ShouldFail().Err() "")
Expect(err).To(ContainSubstring("a devfile already exists in the current directory")) defer os.Remove(filepath.Join(commonVar.Context, devfileName))
}) err := helper.Cmd("odo", "init").ShouldFail().Err()
Expect(err).To(ContainSubstring("a devfile already exists in the current directory"))
})
}
By("running odo init with wrong local file path given to --devfile-path", func() { By("running odo init with wrong local file path given to --devfile-path", func() {
err := helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", "/some/path/devfile.yaml").ShouldFail().Err() err := helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", "/some/path/devfile.yaml").ShouldFail().Err()

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
// Component that allows the developer to add a configured container into their devworkspace // Component that allows the developer to add a configured container into their devworkspace

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
import attributes "github.com/devfile/api/v2/pkg/attributes" import attributes "github.com/devfile/api/v2/pkg/attributes"

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
// ImageType describes the type of image. // ImageType describes the type of image.

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
// DockerfileSrcType describes the type of // DockerfileSrcType describes the type of

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
// K8sLikeComponentLocationType describes the type of // K8sLikeComponentLocationType describes the type of

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
type PluginComponent struct { type PluginComponent struct {

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
// Component that allows the developer to declare and configure a volume into their devworkspace // Component that allows the developer to declare and configure a volume into their devworkspace

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
// Hub marks this type as a conversion hub. // Hub marks this type as a conversion hub.

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
// Hub marks this type as a conversion hub. // Hub marks this type as a conversion hub.

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
import attributes "github.com/devfile/api/v2/pkg/attributes" import attributes "github.com/devfile/api/v2/pkg/attributes"

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
import ( import (

View File

@@ -1,6 +1,22 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package v1alpha2 contains API Schema definitions for the org v1alpha2 API group // Package v1alpha2 contains API Schema definitions for the org v1alpha2 API group
// +k8s:deepcopy-gen=package,register // +k8s:deepcopy-gen=package,register
// +k8s:openapi-gen=true // +k8s:openapi-gen=true
// +groupName=workspace.devfile.io // +groupName=workspace.devfile.io
// +devfile:jsonschema:version=2.2.1-alpha // +devfile:jsonschema:version=2.2.1
package v1alpha2 package v1alpha2

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
import "github.com/devfile/api/v2/pkg/attributes" import "github.com/devfile/api/v2/pkg/attributes"

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
type Events struct { type Events struct {

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
// ImportReferenceType describes the type of location // ImportReferenceType describes the type of location

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
// Keyed is expected to be implemented by the elements of the devfile top-level lists // Keyed is expected to be implemented by the elements of the devfile top-level lists

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
// +kubebuilder:validation:Enum=replace;delete // +kubebuilder:validation:Enum=replace;delete

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
// +k8s:deepcopy-gen=false // +k8s:deepcopy-gen=false

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
type Parent struct { type Parent struct {

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// NOTE: Boilerplate only. Ignore this file. // NOTE: Boilerplate only. Ignore this file.
// Package v1alpha2 contains API Schema definitions for the org v1alpha2 API group // Package v1alpha2 contains API Schema definitions for the org v1alpha2 API group

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
// +k8s:deepcopy-gen=false // +k8s:deepcopy-gen=false

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1alpha2 package v1alpha2
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package attributes package attributes
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package attributes package attributes
import "fmt" import "fmt"

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package devfile package devfile
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package overriding package overriding
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package overriding package overriding
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package overriding package overriding
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package overriding package overriding
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package unions package unions
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package validation package validation
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package validation package validation
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package validation package validation
import "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" import "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package validation package validation
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package validation package validation
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package validation package validation
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package validation package validation
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package variables package variables
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package variables package variables
// checkForInvalidError checks for InvalidKeysError and stores the key in the map // checkForInvalidError checks for InvalidKeysError and stores the key in the map

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package variables package variables
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package variables package variables
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package variables package variables
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package variables package variables
import ( import (

View File

@@ -1,3 +1,19 @@
//
//
// Copyright Red Hat
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package variables package variables
import ( import (

View File

@@ -16,11 +16,7 @@
package parser package parser
import ( import (
"fmt"
"net/url" "net/url"
"os"
"path/filepath"
"strings"
"github.com/devfile/library/v2/pkg/testingutil/filesystem" "github.com/devfile/library/v2/pkg/testingutil/filesystem"
"github.com/devfile/library/v2/pkg/util" "github.com/devfile/library/v2/pkg/util"
@@ -36,7 +32,10 @@ type DevfileCtx struct {
// absolute path of devfile // absolute path of devfile
absPath string absPath string
// relative path of devfile // relative path of devfile.
// It can also be a relative or absolute path to a folder containing one or more devfiles,
// in which case the library will try to pick an existing one, based on the following priority order:
// devfile.yaml > .devfile.yaml > devfile.yml > .devfile.yml
relPath string relPath string
// raw content of the devfile // raw content of the devfile
@@ -96,23 +95,16 @@ func (d *DevfileCtx) populateDevfile() (err error) {
// Populate fills the DevfileCtx struct with relevant context info // Populate fills the DevfileCtx struct with relevant context info
func (d *DevfileCtx) Populate() (err error) { func (d *DevfileCtx) Populate() (err error) {
if !strings.HasSuffix(d.relPath, ".yaml") { d.relPath, err = lookupDevfileFromPath(d.fs, d.relPath)
if _, err := os.Stat(filepath.Join(d.relPath, "devfile.yaml")); os.IsNotExist(err) { if err != nil {
if _, err := os.Stat(filepath.Join(d.relPath, ".devfile.yaml")); os.IsNotExist(err) { return err
return fmt.Errorf("the provided path is not a valid yaml filepath, and devfile.yaml or .devfile.yaml not found in the provided path : %s", d.relPath)
} else {
d.relPath = filepath.Join(d.relPath, ".devfile.yaml")
}
} else {
d.relPath = filepath.Join(d.relPath, "devfile.yaml")
}
} }
if err := d.SetAbsPath(); err != nil { if err = d.SetAbsPath(); err != nil {
return err return err
} }
klog.V(4).Infof("absolute devfile path: '%s'", d.absPath) klog.V(4).Infof("absolute devfile path: '%s'", d.absPath)
// Read and save devfile content // Read and save devfile content
if err := d.SetDevfileContent(); err != nil { if err = d.SetDevfileContent(); err != nil {
return err return err
} }
return d.populateDevfile() return d.populateDevfile()

View File

@@ -0,0 +1,64 @@
//
// Copyright Red Hat, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package parser
import (
"errors"
"fmt"
"io/fs"
"path/filepath"
"strings"
"github.com/devfile/library/v2/pkg/testingutil/filesystem"
)
// possibleDevfileNames contains possible filenames for a devfile.
// Those are checked in this priority order from a given context dir.
var possibleDevfileNames = []string{
"devfile.yaml",
".devfile.yaml",
"devfile.yml",
".devfile.yml",
}
// lookupDevfileFromPath returns the file path to use as devfile filename, by looking at the relative path specified in relPath.
// If relPath is not a directory, it is returned as is.
// For backward compatibility, if relPath is a directory, it will try to detect the first existing devfile filename under relPath,
// based on the list of possible devfile filenames defined in the sorted possibleDevfileNames.
// It returns any error found while interacting with the filesystem, or if no file was found from the list of possible devfile names.
func lookupDevfileFromPath(fsys filesystem.Filesystem, relPath string) (string, error) {
stat, err := fsys.Stat(relPath)
if err != nil {
return "", err
}
if !stat.IsDir() {
return relPath, nil
}
for _, possibleDevfileName := range possibleDevfileNames {
p := filepath.Join(relPath, possibleDevfileName)
if _, err = fsys.Stat(p); errors.Is(err, fs.ErrNotExist) {
continue
}
return p, nil
}
return "", fmt.Errorf(
"the provided path is not a valid yaml filepath, and no possible devfile could be found in the provided path : %s. Possible filenames for a devfile: %s",
relPath,
strings.Join(possibleDevfileNames, ", "))
}

View File

@@ -1,5 +1,5 @@
// //
// Copyright 2022-2023 Red Hat, Inc. // Copyright Red Hat
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.

View File

@@ -19,8 +19,6 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/devfile/library/v2/pkg/git"
"github.com/hashicorp/go-multierror"
"io/ioutil" "io/ioutil"
"net/url" "net/url"
"os" "os"
@@ -46,57 +44,6 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// downloadGitRepoResources is exposed as a global variable for the purpose of running mock tests
var downloadGitRepoResources = func(url string, destDir string, httpTimeout *int, token string) error {
var returnedErr error
if util.IsGitProviderRepo(url) {
gitUrl, err := git.NewGitUrlWithURL(url)
if err != nil {
return err
}
if !gitUrl.IsFile || gitUrl.Revision == "" || !strings.Contains(gitUrl.Path, OutputDevfileYamlPath) {
return fmt.Errorf("error getting devfile from url: failed to retrieve %s", url)
}
stackDir, err := os.MkdirTemp("", fmt.Sprintf("git-resources"))
if err != nil {
return fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
}
defer func(path string) {
err := os.RemoveAll(path)
if err != nil {
returnedErr = multierror.Append(returnedErr, err)
}
}(stackDir)
if !gitUrl.IsPublic(httpTimeout) {
err = gitUrl.SetToken(token, httpTimeout)
if err != nil {
returnedErr = multierror.Append(returnedErr, err)
return returnedErr
}
}
err = gitUrl.CloneGitRepo(stackDir)
if err != nil {
returnedErr = multierror.Append(returnedErr, err)
return returnedErr
}
dir := path.Dir(path.Join(stackDir, gitUrl.Path))
err = git.CopyAllDirFiles(dir, destDir)
if err != nil {
returnedErr = multierror.Append(returnedErr, err)
return returnedErr
}
}
return nil
}
// ParseDevfile func validates the devfile integrity. // ParseDevfile func validates the devfile integrity.
// Creates devfile context and runtime objects // Creates devfile context and runtime objects
func parseDevfile(d DevfileObj, resolveCtx *resolutionContextTree, tool resolverTools, flattenedDevfile bool) (DevfileObj, error) { func parseDevfile(d DevfileObj, resolveCtx *resolutionContextTree, tool resolverTools, flattenedDevfile bool) (DevfileObj, error) {
@@ -133,7 +80,10 @@ func parseDevfile(d DevfileObj, resolveCtx *resolutionContextTree, tool resolver
// ParserArgs is the struct to pass into parser functions which contains required info for parsing devfile. // ParserArgs is the struct to pass into parser functions which contains required info for parsing devfile.
// It accepts devfile path, devfile URL or devfile content in []byte format. // It accepts devfile path, devfile URL or devfile content in []byte format.
type ParserArgs struct { type ParserArgs struct {
// Path is a relative or absolute devfile path. // Path is a relative or absolute devfile path on disk.
// It can also be a relative or absolute path to a folder containing one or more devfiles,
// in which case the library will try to pick an existing one, based on the following priority order:
// devfile.yaml > .devfile.yaml > devfile.yml > .devfile.yml
Path string Path string
// URL is the URL address of the specific devfile. // URL is the URL address of the specific devfile.
URL string URL string
@@ -167,6 +117,10 @@ type ParserArgs struct {
// ImageNamesAsSelector sets the information that will be used to handle image names as selectors when parsing the Devfile. // ImageNamesAsSelector sets the information that will be used to handle image names as selectors when parsing the Devfile.
// Not setting this field or setting it to nil disables the logic of handling image names as selectors. // Not setting this field or setting it to nil disables the logic of handling image names as selectors.
ImageNamesAsSelector *ImageSelectorArgs ImageNamesAsSelector *ImageSelectorArgs
// DownloadGitResources downloads the resources from Git repository if true
DownloadGitResources *bool
// DevfileUtilsClient exposes the interface for mock implementation.
DevfileUtilsClient DevfileUtils
} }
// ImageSelectorArgs defines the structure to leverage for using image names as selectors after parsing the Devfile. // ImageSelectorArgs defines the structure to leverage for using image names as selectors after parsing the Devfile.
@@ -214,12 +168,23 @@ func ParseDevfile(args ParserArgs) (d DevfileObj, err error) {
d.Ctx.SetToken(args.Token) d.Ctx.SetToken(args.Token)
} }
if args.DevfileUtilsClient == nil {
args.DevfileUtilsClient = NewDevfileUtilsClient()
}
downloadGitResources := true
if args.DownloadGitResources != nil {
downloadGitResources = *args.DownloadGitResources
}
tool := resolverTools{ tool := resolverTools{
defaultNamespace: args.DefaultNamespace, defaultNamespace: args.DefaultNamespace,
registryURLs: args.RegistryURLs, registryURLs: args.RegistryURLs,
context: args.Context, context: args.Context,
k8sClient: args.K8sClient, k8sClient: args.K8sClient,
httpTimeout: args.HTTPTimeout, httpTimeout: args.HTTPTimeout,
downloadGitResources: downloadGitResources,
devfileUtilsClient: args.DevfileUtilsClient,
} }
flattenedDevfile := true flattenedDevfile := true
@@ -273,6 +238,10 @@ type resolverTools struct {
k8sClient client.Client k8sClient client.Client
// httpTimeout is the timeout value in seconds passed in from the client. // httpTimeout is the timeout value in seconds passed in from the client.
httpTimeout *int httpTimeout *int
// downloadGitResources downloads the resources from Git repository if true
downloadGitResources bool
// devfileUtilsClient exposes the Git Interface to be able to use mock implementation.
devfileUtilsClient DevfileUtils
} }
func populateAndParseDevfile(d DevfileObj, resolveCtx *resolutionContextTree, tool resolverTools, flattenedDevfile bool) (DevfileObj, error) { func populateAndParseDevfile(d DevfileObj, resolveCtx *resolutionContextTree, tool resolverTools, flattenedDevfile bool) (DevfileObj, error) {
@@ -522,10 +491,12 @@ func parseFromURI(importReference v1.ImportReference, curDevfileCtx devfileCtx.D
d.Ctx.SetToken(token) d.Ctx.SetToken(token)
} }
destDir := path.Dir(curDevfileCtx.GetAbsPath()) if tool.downloadGitResources {
err = downloadGitRepoResources(newUri, destDir, tool.httpTimeout, token) destDir := path.Dir(curDevfileCtx.GetAbsPath())
if err != nil { err = tool.devfileUtilsClient.DownloadGitRepoResources(newUri, destDir, token)
return DevfileObj{}, err if err != nil {
return DevfileObj{}, err
}
} }
} }
importReference.Uri = newUri importReference.Uri = newUri

View File

@@ -0,0 +1,75 @@
//
// Copyright 2023 Red Hat, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package parser
import (
"fmt"
"github.com/devfile/library/v2/pkg/util"
"os"
"strings"
)
type MockDevfileUtilsClient struct {
ParentURLAlias string // Specify a valid git URL as an alias if using a localhost HTTP server in order to pass validation.
MockGitURL util.MockGitUrl
GitTestToken string // Mock Git token. Specify the string "valid-token" for the mock CloneGitRepo to pass
}
func NewMockDevfileUtilsClient() MockDevfileUtilsClient {
return MockDevfileUtilsClient{}
}
func (gc MockDevfileUtilsClient) DownloadGitRepoResources(url string, destDir string, token string) error {
//the url parameter that gets passed in will be the localhost IP of the test server, so it will fail all the validation checks. We will use the global testURL variable instead
//skip the Git Provider check since it'll fail
if util.IsGitProviderRepo(gc.ParentURLAlias) {
// this converts the test git URL to a mock URL
mockGitUrl := gc.MockGitURL
mockGitUrl.Token = gc.GitTestToken
if !mockGitUrl.IsFile || mockGitUrl.Revision == "" || !strings.Contains(mockGitUrl.Path, OutputDevfileYamlPath) {
return fmt.Errorf("error getting devfile from url: failed to retrieve %s", url+"/"+mockGitUrl.Path)
}
stackDir, err := os.MkdirTemp("", fmt.Sprintf("git-resources"))
if err != nil {
return fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
}
defer func(path string) {
err := os.RemoveAll(path)
if err != nil {
err = fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
}
}(stackDir)
err = mockGitUrl.CloneGitRepo(stackDir)
if err != nil {
return err
}
err = util.CopyAllDirFiles(stackDir, destDir)
if err != nil {
return err
}
} else {
return fmt.Errorf("Failed to download resources from parent devfile. Unsupported Git Provider for %s ", gc.ParentURLAlias)
}
return nil
}

View File

@@ -1,5 +1,5 @@
// //
// Copyright 2022 Red Hat, Inc. // Copyright 2022-2023 Red Hat, Inc.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@@ -17,13 +17,75 @@ package parser
import ( import (
"fmt" "fmt"
"github.com/devfile/library/v2/pkg/util"
"github.com/hashicorp/go-multierror"
"os"
"path"
"reflect" "reflect"
"strings"
devfilev1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" devfilev1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/devfile/library/v2/pkg/devfile/parser/data" "github.com/devfile/library/v2/pkg/devfile/parser/data"
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common" "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
) )
type DevfileUtilsClient struct {
}
func NewDevfileUtilsClient() DevfileUtilsClient {
return DevfileUtilsClient{}
}
type DevfileUtils interface {
DownloadGitRepoResources(url string, destDir string, token string) error
}
// DownloadGitRepoResources mock implementation of the real method.
func (gc DevfileUtilsClient) DownloadGitRepoResources(url string, destDir string, token string) error {
var returnedErr error
if util.IsGitProviderRepo(url) {
gitUrl, err := util.NewGitURL(url, token)
if err != nil {
return err
}
if !gitUrl.IsFile || gitUrl.Revision == "" || !strings.Contains(gitUrl.Path, OutputDevfileYamlPath) {
return fmt.Errorf("error getting devfile from url: failed to retrieve %s", url)
}
stackDir, err := os.MkdirTemp("", fmt.Sprintf("git-resources"))
if err != nil {
return fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err)
}
defer func(path string) {
err := os.RemoveAll(path)
if err != nil {
returnedErr = multierror.Append(returnedErr, err)
}
}(stackDir)
gitUrl.Token = token
err = gitUrl.CloneGitRepo(stackDir)
if err != nil {
returnedErr = multierror.Append(returnedErr, err)
return returnedErr
}
dir := path.Dir(path.Join(stackDir, gitUrl.Path))
err = util.CopyAllDirFiles(dir, destDir)
if err != nil {
returnedErr = multierror.Append(returnedErr, err)
return returnedErr
}
} else {
return fmt.Errorf("Failed to download resources from parent devfile. Unsupported Git Provider for %s ", url)
}
return nil
}
// GetDeployComponents gets the default deploy command associated components // GetDeployComponents gets the default deploy command associated components
func GetDeployComponents(devfileData data.DevfileData) (map[string]string, error) { func GetDeployComponents(devfileData data.DevfileData) (map[string]string, error) {
deployCommandFilter := common.DevfileOptions{ deployCommandFilter := common.DevfileOptions{

View File

@@ -26,7 +26,7 @@ import (
"k8s.io/klog" "k8s.io/klog"
) )
// WriteYamlDevfile creates a devfile.yaml file // WriteYamlDevfile writes the content of the Devfile data to its absolute path on the filesystem.
func (d *DevfileObj) WriteYamlDevfile() error { func (d *DevfileObj) WriteYamlDevfile() error {
// Check kubernetes components, and restore original uri content // Check kubernetes components, and restore original uri content
@@ -41,7 +41,7 @@ func (d *DevfileObj) WriteYamlDevfile() error {
if err != nil { if err != nil {
return errors.Wrapf(err, "failed to marshal devfile object into yaml") return errors.Wrapf(err, "failed to marshal devfile object into yaml")
} }
// Write to devfile.yaml // Write to the absolute path
fs := d.Ctx.GetFs() fs := d.Ctx.GetFs()
if fs == nil { if fs == nil {
fs = filesystem.DefaultFs{} fs = filesystem.DefaultFs{}
@@ -52,7 +52,7 @@ func (d *DevfileObj) WriteYamlDevfile() error {
} }
// Successful // Successful
klog.V(2).Infof("devfile yaml created at: '%s'", OutputDevfileYamlPath) klog.V(2).Infof("devfile written to: '%s'", d.Ctx.GetAbsPath())
return nil return nil
} }

View File

@@ -1,260 +0,0 @@
//
// Copyright 2023 Red Hat, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package git
import (
"fmt"
"github.com/devfile/library/v2/pkg/testingutil/filesystem"
"github.com/gregjones/httpcache"
"github.com/gregjones/httpcache/diskcache"
"github.com/pkg/errors"
"io"
"io/ioutil"
"k8s.io/klog"
"net/http"
"net/url"
"os"
"path"
"path/filepath"
"time"
)
const (
HTTPRequestResponseTimeout = 30 * time.Second // HTTPRequestTimeout configures timeout of all HTTP requests
)
// httpCacheDir determines directory where odo will cache HTTP responses
var httpCacheDir = filepath.Join(os.TempDir(), "odohttpcache")
// HTTPRequestParams holds parameters of forming http request
type HTTPRequestParams struct {
URL string
Token string
Timeout *int
TelemetryClientName string //optional client name for telemetry
}
// HTTPGetRequest gets resource contents given URL and token (if applicable)
// cacheFor determines how long the response should be cached (in minutes), 0 for no caching
func HTTPGetRequest(request HTTPRequestParams, cacheFor int) ([]byte, error) {
// Build http request
req, err := http.NewRequest("GET", request.URL, nil)
if err != nil {
return nil, err
}
if request.Token != "" {
bearer := "Bearer " + request.Token
req.Header.Add("Authorization", bearer)
}
//add the telemetry client name
req.Header.Add("Client", request.TelemetryClientName)
overriddenTimeout := HTTPRequestResponseTimeout
timeout := request.Timeout
if timeout != nil {
//if value is invalid, the default will be used
if *timeout > 0 {
//convert timeout to seconds
overriddenTimeout = time.Duration(*timeout) * time.Second
klog.V(4).Infof("HTTP request and response timeout overridden value is %v ", overriddenTimeout)
} else {
klog.V(4).Infof("Invalid httpTimeout is passed in, using default value")
}
}
httpClient := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
ResponseHeaderTimeout: overriddenTimeout,
},
Timeout: overriddenTimeout,
}
klog.V(4).Infof("HTTPGetRequest: %s", req.URL.String())
if cacheFor > 0 {
// if there is an error during cache setup we show warning and continue without using cache
cacheError := false
httpCacheTime := time.Duration(cacheFor) * time.Minute
// make sure that cache directory exists
err = os.MkdirAll(httpCacheDir, 0750)
if err != nil {
cacheError = true
klog.WarningDepth(4, "Unable to setup cache: ", err)
}
err = cleanHttpCache(httpCacheDir, httpCacheTime)
if err != nil {
cacheError = true
klog.WarningDepth(4, "Unable to clean up cache directory: ", err)
}
if !cacheError {
httpClient.Transport = httpcache.NewTransport(diskcache.New(httpCacheDir))
klog.V(4).Infof("Response will be cached in %s for %s", httpCacheDir, httpCacheTime)
} else {
klog.V(4).Info("Response won't be cached.")
}
}
resp, err := httpClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.Header.Get(httpcache.XFromCache) != "" {
klog.V(4).Infof("Cached response used.")
}
// We have a non 1xx / 2xx status, return an error
if (resp.StatusCode - 300) > 0 {
return nil, errors.Errorf("failed to retrieve %s, %v: %s", request.URL, resp.StatusCode, http.StatusText(resp.StatusCode))
}
// Process http response
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return bytes, err
}
// ValidateURL validates the URL
func ValidateURL(sourceURL string) error {
u, err := url.Parse(sourceURL)
if err != nil {
return err
}
if len(u.Host) == 0 || len(u.Scheme) == 0 {
return errors.New("URL is invalid")
}
return nil
}
// cleanHttpCache checks cacheDir and deletes all files that were modified more than cacheTime back
func cleanHttpCache(cacheDir string, cacheTime time.Duration) error {
cacheFiles, err := ioutil.ReadDir(cacheDir)
if err != nil {
return err
}
for _, f := range cacheFiles {
if f.ModTime().Add(cacheTime).Before(time.Now()) {
klog.V(4).Infof("Removing cache file %s, because it is older than %s", f.Name(), cacheTime.String())
err := os.Remove(filepath.Join(cacheDir, f.Name()))
if err != nil {
return err
}
}
}
return nil
}
// CheckPathExists checks if a path exists or not
func CheckPathExists(path string) bool {
return checkPathExistsOnFS(path, filesystem.DefaultFs{})
}
func checkPathExistsOnFS(path string, fs filesystem.Filesystem) bool {
if _, err := fs.Stat(path); !os.IsNotExist(err) {
// path to file does exist
return true
}
klog.V(4).Infof("path %s doesn't exist, skipping it", path)
return false
}
// CopyAllDirFiles recursively copies a source directory to a destination directory
func CopyAllDirFiles(srcDir, destDir string) error {
return copyAllDirFilesOnFS(srcDir, destDir, filesystem.DefaultFs{})
}
func copyAllDirFilesOnFS(srcDir, destDir string, fs filesystem.Filesystem) error {
var info os.FileInfo
files, err := fs.ReadDir(srcDir)
if err != nil {
return errors.Wrapf(err, "failed reading dir %v", srcDir)
}
for _, file := range files {
srcPath := path.Join(srcDir, file.Name())
destPath := path.Join(destDir, file.Name())
if file.IsDir() {
if info, err = fs.Stat(srcPath); err != nil {
return err
}
if err = fs.MkdirAll(destPath, info.Mode()); err != nil {
return err
}
if err = copyAllDirFilesOnFS(srcPath, destPath, fs); err != nil {
return err
}
} else {
if file.Name() == "devfile.yaml" {
continue
}
// Only copy files that do not exist in the destination directory
if !checkPathExistsOnFS(destPath, fs) {
if err := copyFileOnFs(srcPath, destPath, fs); err != nil {
return errors.Wrapf(err, "failed to copy %s to %s", srcPath, destPath)
}
}
}
}
return nil
}
// copied from: https://github.com/devfile/registry-support/blob/main/index/generator/library/util.go
func copyFileOnFs(src, dst string, fs filesystem.Filesystem) error {
var err error
var srcinfo os.FileInfo
srcfd, err := fs.Open(src)
if err != nil {
return err
}
defer func() {
if e := srcfd.Close(); e != nil {
fmt.Printf("err occurred while closing file: %v", e)
}
}()
dstfd, err := fs.Create(dst)
if err != nil {
return err
}
defer func() {
if e := dstfd.Close(); e != nil {
fmt.Printf("err occurred while closing file: %v", e)
}
}()
if _, err = io.Copy(dstfd, srcfd); err != nil {
return err
}
if srcinfo, err = fs.Stat(src); err != nil {
return err
}
return fs.Chmod(dst, srcinfo.Mode())
}

View File

@@ -28,9 +28,13 @@ type FakeK8sClient struct {
client.Client // To satisfy interface; override all used methods client.Client // To satisfy interface; override all used methods
DevWorkspaceResources map[string]v1alpha2.DevWorkspaceTemplate DevWorkspaceResources map[string]v1alpha2.DevWorkspaceTemplate
Errors map[string]string Errors map[string]string
ExpectedNamespace string
} }
func (client *FakeK8sClient) Get(_ context.Context, namespacedName client.ObjectKey, obj client.Object, _ ...client.GetOption) error { func (client *FakeK8sClient) Get(_ context.Context, namespacedName client.ObjectKey, obj client.Object, _ ...client.GetOption) error {
if client.ExpectedNamespace != "" && client.ExpectedNamespace != namespacedName.Namespace {
return fmt.Errorf("expected namespace %s, got %s", client.ExpectedNamespace, namespacedName.Namespace)
}
template, ok := obj.(*v1alpha2.DevWorkspaceTemplate) template, ok := obj.(*v1alpha2.DevWorkspaceTemplate)
if !ok { if !ok {
return fmt.Errorf("called Get() in fake client with non-DevWorkspaceTemplate") return fmt.Errorf("called Get() in fake client with non-DevWorkspaceTemplate")

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package git package util
import ( import (
"fmt" "fmt"
@@ -38,10 +38,20 @@ type GitUrl struct {
Repo string // name of the repo Repo string // name of the repo
Revision string // branch name, tag name, or commit id Revision string // branch name, tag name, or commit id
Path string // path to a directory or file in the repo Path string // path to a directory or file in the repo
token string // authenticates private repo actions for parent devfiles Token string // authenticates private repo actions for parent devfiles
IsFile bool // defines if the URL points to a file in the repo IsFile bool // defines if the URL points to a file in the repo
} }
// NewGitURL NewGitUrl creates a GitUrl from a string url and token. Will eventually replace NewGitUrlWithURL
func NewGitURL(url string, token string) (*GitUrl, error) {
gitUrl, err := ParseGitUrl(url)
if err != nil {
return &gitUrl, err
}
gitUrl.Token = token
return &gitUrl, nil
}
// NewGitUrlWithURL NewGitUrl creates a GitUrl from a string url // NewGitUrlWithURL NewGitUrl creates a GitUrl from a string url
func NewGitUrlWithURL(url string) (GitUrl, error) { func NewGitUrlWithURL(url string) (GitUrl, error) {
gitUrl, err := ParseGitUrl(url) gitUrl, err := ParseGitUrl(url)
@@ -83,7 +93,7 @@ func ParseGitUrl(fullUrl string) (GitUrl, error) {
} }
func (g *GitUrl) GetToken() string { func (g *GitUrl) GetToken() string {
return g.token return g.Token
} }
type CommandType string type CommandType string
@@ -300,18 +310,20 @@ func (g *GitUrl) parseBitbucketUrl(url *url.URL) error {
// SetToken validates the token with a get request to the repo before setting the token // SetToken validates the token with a get request to the repo before setting the token
// Defaults token to empty on failure. // Defaults token to empty on failure.
// Deprecated. Avoid using since this will cause rate limiting issues
func (g *GitUrl) SetToken(token string, httpTimeout *int) error { func (g *GitUrl) SetToken(token string, httpTimeout *int) error {
err := g.validateToken(HTTPRequestParams{Token: token, Timeout: httpTimeout}) err := g.validateToken(HTTPRequestParams{Token: token, Timeout: httpTimeout})
if err != nil { if err != nil {
g.token = "" g.Token = ""
return fmt.Errorf("failed to set token. error: %v", err) return fmt.Errorf("failed to set token. error: %v", err)
} }
g.token = token g.Token = token
return nil return nil
} }
// IsPublic checks if the GitUrl is public with a get request to the repo using an empty token // IsPublic checks if the GitUrl is public with a get request to the repo using an empty token
// Returns true if the request succeeds // Returns true if the request succeeds
// Deprecated. Avoid using since this will cause rate limiting issues
func (g *GitUrl) IsPublic(httpTimeout *int) bool { func (g *GitUrl) IsPublic(httpTimeout *int) bool {
err := g.validateToken(HTTPRequestParams{Token: "", Timeout: httpTimeout}) err := g.validateToken(HTTPRequestParams{Token: "", Timeout: httpTimeout})
if err != nil { if err != nil {

View File

@@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package git package util
import ( import (
"fmt" "fmt"
@@ -29,12 +29,12 @@ type MockGitUrl struct {
Repo string // name of the repo Repo string // name of the repo
Revision string // branch name, tag name, or commit id Revision string // branch name, tag name, or commit id
Path string // path to a directory or file in the repo Path string // path to a directory or file in the repo
token string // used for authenticating a private repo Token string // used for authenticating a private repo
IsFile bool // defines if the URL points to a file in the repo IsFile bool // defines if the URL points to a file in the repo
} }
func (m *MockGitUrl) GetToken() string { func (m *MockGitUrl) GetToken() string {
return m.token return m.Token
} }
var mockExecute = func(baseDir string, cmd CommandType, args ...string) ([]byte, error) { var mockExecute = func(baseDir string, cmd CommandType, args ...string) ([]byte, error) {
@@ -131,7 +131,7 @@ func (m *MockGitUrl) CloneGitRepo(destDir string) error {
} }
func (m *MockGitUrl) SetToken(token string) error { func (m *MockGitUrl) SetToken(token string) error {
m.token = token m.Token = token
return nil return nil
} }

View File

@@ -21,9 +21,10 @@ import (
"bytes" "bytes"
"crypto/rand" "crypto/rand"
"fmt" "fmt"
"github.com/devfile/library/v2/pkg/git"
gitpkg "github.com/go-git/go-git/v5" gitpkg "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing"
"github.com/gregjones/httpcache"
"github.com/gregjones/httpcache/diskcache"
"io" "io"
"io/ioutil" "io/ioutil"
"math/big" "math/big"
@@ -47,8 +48,6 @@ import (
"github.com/devfile/library/v2/pkg/testingutil/filesystem" "github.com/devfile/library/v2/pkg/testingutil/filesystem"
"github.com/fatih/color" "github.com/fatih/color"
"github.com/gobwas/glob" "github.com/gobwas/glob"
"github.com/gregjones/httpcache"
"github.com/gregjones/httpcache/diskcache"
"github.com/pkg/errors" "github.com/pkg/errors"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
@@ -887,8 +886,8 @@ func ConvertGitSSHRemoteToHTTPS(remote string) string {
// IsGitProviderRepo checks if the url matches a repo from a supported git provider // IsGitProviderRepo checks if the url matches a repo from a supported git provider
func IsGitProviderRepo(url string) bool { func IsGitProviderRepo(url string) bool {
if strings.Contains(url, git.RawGitHubHost) || strings.Contains(url, git.GitHubHost) || if strings.Contains(url, RawGitHubHost) || strings.Contains(url, GitHubHost) ||
strings.Contains(url, git.GitLabHost) || strings.Contains(url, git.BitbucketHost) { strings.Contains(url, GitLabHost) || strings.Contains(url, BitbucketHost) {
return true return true
} }
return false return false
@@ -1100,11 +1099,11 @@ func DownloadInMemory(params HTTPRequestParams) ([]byte, error) {
ResponseHeaderTimeout: HTTPRequestResponseTimeout, ResponseHeaderTimeout: HTTPRequestResponseTimeout,
}, Timeout: HTTPRequestResponseTimeout} }, Timeout: HTTPRequestResponseTimeout}
var g git.GitUrl var g GitUrl
var err error var err error
if IsGitProviderRepo(params.URL) { if IsGitProviderRepo(params.URL) {
g, err = git.NewGitUrlWithURL(params.URL) g, err = NewGitUrlWithURL(params.URL)
if err != nil { if err != nil {
return nil, errors.Errorf("failed to parse git repo. error: %v", err) return nil, errors.Errorf("failed to parse git repo. error: %v", err)
} }
@@ -1113,7 +1112,7 @@ func DownloadInMemory(params HTTPRequestParams) ([]byte, error) {
return downloadInMemoryWithClient(params, httpClient, g) return downloadInMemoryWithClient(params, httpClient, g)
} }
func downloadInMemoryWithClient(params HTTPRequestParams, httpClient HTTPClient, g git.GitUrl) ([]byte, error) { func downloadInMemoryWithClient(params HTTPRequestParams, httpClient HTTPClient, g GitUrl) ([]byte, error) {
var url string var url string
url = params.URL url = params.URL
req, err := http.NewRequest("GET", url, nil) req, err := http.NewRequest("GET", url, nil)
@@ -1127,12 +1126,8 @@ func downloadInMemoryWithClient(params HTTPRequestParams, httpClient HTTPClient,
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !g.IsPublic(params.Timeout) {
// check that the token is valid before adding to the header if params.Token != "" {
err = g.SetToken(params.Token, params.Timeout)
if err != nil {
return nil, err
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", params.Token)) req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", params.Token))
} }
} }

5
vendor/modules.txt generated vendored
View File

@@ -164,7 +164,7 @@ github.com/devfile/alizer/pkg/apis/recognizer
github.com/devfile/alizer/pkg/schema github.com/devfile/alizer/pkg/schema
github.com/devfile/alizer/pkg/utils github.com/devfile/alizer/pkg/utils
github.com/devfile/alizer/pkg/utils/langfiles github.com/devfile/alizer/pkg/utils/langfiles
# github.com/devfile/api/v2 v2.2.1-alpha.0.20230413012049-a6c32fca0dbd # github.com/devfile/api/v2 v2.2.1
## explicit; go 1.18 ## explicit; go 1.18
github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2 github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2
github.com/devfile/api/v2/pkg/attributes github.com/devfile/api/v2/pkg/attributes
@@ -173,7 +173,7 @@ github.com/devfile/api/v2/pkg/utils/overriding
github.com/devfile/api/v2/pkg/utils/unions github.com/devfile/api/v2/pkg/utils/unions
github.com/devfile/api/v2/pkg/validation github.com/devfile/api/v2/pkg/validation
github.com/devfile/api/v2/pkg/validation/variables github.com/devfile/api/v2/pkg/validation/variables
# github.com/devfile/library/v2 v2.2.1-0.20230524160049-04a8b3fc66c0 # github.com/devfile/library/v2 v2.2.2-0.20231102090733-57a7da8b8392
## explicit; go 1.18 ## explicit; go 1.18
github.com/devfile/library/v2/pkg/devfile github.com/devfile/library/v2/pkg/devfile
github.com/devfile/library/v2/pkg/devfile/generator github.com/devfile/library/v2/pkg/devfile/generator
@@ -186,7 +186,6 @@ github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.1.0
github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.2.0 github.com/devfile/library/v2/pkg/devfile/parser/data/v2/2.2.0
github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common
github.com/devfile/library/v2/pkg/devfile/validate github.com/devfile/library/v2/pkg/devfile/validate
github.com/devfile/library/v2/pkg/git
github.com/devfile/library/v2/pkg/testingutil github.com/devfile/library/v2/pkg/testingutil
github.com/devfile/library/v2/pkg/testingutil/filesystem github.com/devfile/library/v2/pkg/testingutil/filesystem
github.com/devfile/library/v2/pkg/util github.com/devfile/library/v2/pkg/util