Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Delete Comp, Command, Proj, StarterProj #65

Merged
merged 7 commits into from
Mar 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ require (
github.com/openshift/api v0.0.0-20200930075302-db52bc4ef99f
github.com/pkg/errors v0.9.1
github.com/spf13/afero v1.2.2
github.com/stretchr/testify v1.6.1 // indirect
github.com/stretchr/testify v1.6.1
github.com/xeipuuv/gojsonschema v1.2.0
k8s.io/api v0.19.0
k8s.io/apimachinery v0.19.0
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,7 @@ gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
14 changes: 9 additions & 5 deletions pkg/devfile/parser/data/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,30 @@ type DevfileData interface {
GetComponents(common.DevfileOptions) ([]v1.Component, error)
AddComponents(components []v1.Component) error
UpdateComponent(component v1.Component)
DeleteComponent(name string) error

// project related methods
GetProjects(common.DevfileOptions) ([]v1.Project, error)
AddProjects(projects []v1.Project) error
UpdateProject(project v1.Project)
DeleteProject(name string) error

// starter projects related commands
GetStarterProjects(common.DevfileOptions) ([]v1.StarterProject, error)
AddStarterProjects(projects []v1.StarterProject) error
UpdateStarterProject(project v1.StarterProject)
DeleteStarterProject(name string) error

// command related methods
GetCommands(common.DevfileOptions) ([]v1.Command, error)
AddCommands(commands ...v1.Command) error
AddCommands(commands []v1.Command) error
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is changing the signature of an existing function. It will break every project that already uses this function.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kadel Thanks for the review and concern. Yes, you're right, there should be a release every sprint, specifically when there is a breaking change with the changelog of the PR/commit.

Let me think about it a bit more. Since devfile/library has never had a release, I can do a v1.0.0-alpha release after this PR.

What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be great. At least we would know when and what problems we can expect when upgrading to a newer version.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kadel do you have any other concerns before I merge this PR? I am looking to do a pre-release once this PR is in and hopefully generate a changelog for the release so its easier to track changes.

UpdateCommand(command v1.Command)
DeleteCommand(id string) error

// volume related methods
AddVolume(volume v1.Component, path string) error
DeleteVolume(name string) error
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is removing existing functions that other tools might be already using. This is a breaking change.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're right

GetVolumeMountPath(name string) (string, error)
// volume mount related methods
AddVolumeMounts(componentName string, volumeMounts []v1.VolumeMount) error
DeleteVolumeMount(name string) error
GetVolumeMountPath(mountName, componentName string) (string, error)

// workspace related methods
GetDevfileWorkspace() *v1.DevWorkspaceTemplateSpecContent
Expand Down
24 changes: 18 additions & 6 deletions pkg/devfile/parser/data/v2/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,10 @@ func (d *DevfileV2) GetCommands(options common.DevfileOptions) ([]v1.Command, er

// AddCommands adds the slice of Command objects to the Devfile's commands
// if a command is already defined, error out
func (d *DevfileV2) AddCommands(commands ...v1.Command) error {
devfileCommands, err := d.GetCommands(common.DevfileOptions{})
if err != nil {
return err
}
func (d *DevfileV2) AddCommands(commands []v1.Command) error {

for _, command := range commands {
for _, devfileCommand := range devfileCommands {
for _, devfileCommand := range d.Commands {
if command.Id == devfileCommand.Id {
return &common.FieldAlreadyExistError{Name: command.Id, Field: "command"}
}
Expand All @@ -57,3 +53,19 @@ func (d *DevfileV2) UpdateCommand(command v1.Command) {
}
}
}

// DeleteCommand removes the specified command
func (d *DevfileV2) DeleteCommand(id string) error {

for i := range d.Commands {
if d.Commands[i].Id == id {
d.Commands = append(d.Commands[:i], d.Commands[i+1:]...)
return nil
}
}

return &common.FieldNotFoundError{
Field: "command",
Name: id,
}
}
83 changes: 82 additions & 1 deletion pkg/devfile/parser/data/v2/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/devfile/api/v2/pkg/attributes"
"github.com/devfile/library/pkg/devfile/parser/data/v2/common"
"github.com/stretchr/testify/assert"
)

func TestDevfile200_GetCommands(t *testing.T) {
Expand Down Expand Up @@ -216,7 +217,7 @@ func TestDevfile200_AddCommands(t *testing.T) {
},
}

got := d.AddCommands(tt.newCommands...)
got := d.AddCommands(tt.newCommands)
if !tt.wantErr && got != nil {
t.Errorf("TestDevfile200_AddCommands() unexpected error - %v", got)
} else if tt.wantErr && got == nil {
Expand Down Expand Up @@ -300,3 +301,83 @@ func TestDevfile200_UpdateCommands(t *testing.T) {
})
}
}

func TestDeleteCommands(t *testing.T) {

d := &DevfileV2{
v1.Devfile{
DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{
DevWorkspaceTemplateSpecContent: v1.DevWorkspaceTemplateSpecContent{
Commands: []v1.Command{
{
Id: "command1",
CommandUnion: v1.CommandUnion{
Exec: &v1.ExecCommand{},
},
},
{
Id: "command2",
CommandUnion: v1.CommandUnion{
Exec: &v1.ExecCommand{},
},
},
{
Id: "command3",
CommandUnion: v1.CommandUnion{
Composite: &v1.CompositeCommand{
Commands: []string{"command1", "command2", "command1"},
},
},
},
},
},
},
},
}

tests := []struct {
name string
commandToDelete string
wantCommands []v1.Command
wantErr bool
}{
{
name: "Successfully delete command",
commandToDelete: "command1",
wantCommands: []v1.Command{
{
Id: "command2",
CommandUnion: v1.CommandUnion{
Exec: &v1.ExecCommand{},
},
},
{
Id: "command3",
CommandUnion: v1.CommandUnion{
Composite: &v1.CompositeCommand{
Commands: []string{"command1", "command2", "command1"},
},
},
},
},
wantErr: false,
},
{
name: "Missing Command",
commandToDelete: "command34",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := d.DeleteCommand(tt.commandToDelete)
if (err != nil) != tt.wantErr {
t.Errorf("DeleteCommand() error = %v, wantErr %v", err, tt.wantErr)
return
} else if err == nil {
assert.Equal(t, tt.wantCommands, d.Commands, "The two values should be the same.")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this if statement, already checked by the previous one (previous if block should return)
can directly check tt.wantCommands & d.Commands
same for the other tests

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no we cant, because there are tests where we want an err and that should be skipped. The prev if block is to check if there is an err mis match. I've updated it to a better if else block

Copy link
Collaborator

@yangcao77 yangcao77 Mar 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it won't be skipped, because it's returning from that single test func(t *testing.T){}, it will continue the for loop for the rest of tests

}
})
}

}
30 changes: 21 additions & 9 deletions pkg/devfile/parser/data/v2/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,13 @@ func (d *DevfileV2) GetDevfileVolumeComponents(options common.DevfileOptions) ([
// if a component is already defined, error out
func (d *DevfileV2) AddComponents(components []v1.Component) error {

componentMap := make(map[string]bool)

for _, component := range d.Components {
componentMap[component.Name] = true
}
for _, component := range components {
if _, ok := componentMap[component.Name]; !ok {
d.Components = append(d.Components, component)
} else {
return &common.FieldAlreadyExistError{Name: component.Name, Field: "component"}
for _, devfileComponent := range d.Components {
if component.Name == devfileComponent.Name {
return &common.FieldAlreadyExistError{Name: component.Name, Field: "component"}
}
}
d.Components = append(d.Components, component)
}
return nil
}
Expand All @@ -88,3 +84,19 @@ func (d *DevfileV2) UpdateComponent(component v1.Component) {
d.Components[index] = component
}
}

// DeleteComponent removes the specified component
func (d *DevfileV2) DeleteComponent(name string) error {

for i := range d.Components {
if d.Components[i].Name == name {
d.Components = append(d.Components[:i], d.Components[i+1:]...)
return nil
}
}

return &common.FieldNotFoundError{
Field: "component",
Name: name,
}
}
92 changes: 92 additions & 0 deletions pkg/devfile/parser/data/v2/components_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/devfile/api/v2/pkg/attributes"
"github.com/devfile/library/pkg/devfile/parser/data/v2/common"
"github.com/devfile/library/pkg/testingutil"
"github.com/stretchr/testify/assert"
)

func TestDevfile200_AddComponent(t *testing.T) {
Expand Down Expand Up @@ -403,3 +404,94 @@ func TestGetDevfileVolumeComponents(t *testing.T) {
}

}

func TestDeleteComponents(t *testing.T) {

d := &DevfileV2{
v1.Devfile{
DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{
DevWorkspaceTemplateSpecContent: v1.DevWorkspaceTemplateSpecContent{
Components: []v1.Component{
{
Name: "comp2",
ComponentUnion: v1.ComponentUnion{
Container: &v1.ContainerComponent{
Container: v1.Container{
VolumeMounts: []v1.VolumeMount{
testingutil.GetFakeVolumeMount("comp2", "/path"),
testingutil.GetFakeVolumeMount("comp2", "/path2"),
testingutil.GetFakeVolumeMount("comp3", "/path"),
},
},
},
},
},
{
Name: "comp2",
ComponentUnion: v1.ComponentUnion{
Volume: &v1.VolumeComponent{},
},
},
{
Name: "comp3",
ComponentUnion: v1.ComponentUnion{
Volume: &v1.VolumeComponent{},
},
},
},
},
},
},
}

tests := []struct {
name string
componentToDelete string
wantComponents []v1.Component
wantErr bool
}{
{
name: "Successfully delete a Component",
componentToDelete: "comp3",
wantComponents: []v1.Component{
{
Name: "comp2",
ComponentUnion: v1.ComponentUnion{
Container: &v1.ContainerComponent{
Container: v1.Container{
VolumeMounts: []v1.VolumeMount{
testingutil.GetFakeVolumeMount("comp2", "/path"),
testingutil.GetFakeVolumeMount("comp2", "/path2"),
testingutil.GetFakeVolumeMount("comp3", "/path"),
},
},
},
},
},
{
Name: "comp2",
ComponentUnion: v1.ComponentUnion{
Volume: &v1.VolumeComponent{},
},
},
},
wantErr: false,
},
{
name: "Missing Component",
componentToDelete: "comp12",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := d.DeleteComponent(tt.componentToDelete)
if (err != nil) != tt.wantErr {
t.Errorf("DeleteComponent() error = %v, wantErr %v", err, tt.wantErr)
} else if err == nil {
assert.Equal(t, tt.wantComponents, d.Components, "The two values should be the same.")
}
})
}

}
18 changes: 14 additions & 4 deletions pkg/devfile/parser/data/v2/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ func (d *DevfileV2) GetEvents() v1.Events {
// AddEvents adds the Events Object to the devfile's events
// if the event is already defined in the devfile, error out
func (d *DevfileV2) AddEvents(events v1.Events) error {

if d.Events == nil {
d.Events = &v1.Events{}
}

if len(events.PreStop) > 0 {
if len(d.Events.PreStop) > 0 {
return &common.FieldAlreadyExistError{Field: "pre stop"}
Expand Down Expand Up @@ -50,16 +55,21 @@ func (d *DevfileV2) AddEvents(events v1.Events) error {
// UpdateEvents updates the devfile's events
// it only updates the events passed to it
func (d *DevfileV2) UpdateEvents(postStart, postStop, preStart, preStop []string) {
if len(postStart) != 0 {

if d.Events == nil {
d.Events = &v1.Events{}
}

if postStart != nil {
d.Events.PostStart = postStart
}
if len(postStop) != 0 {
if postStop != nil {
d.Events.PostStop = postStop
}
if len(preStart) != 0 {
if preStart != nil {
d.Events.PreStart = preStart
}
if len(preStop) != 0 {
if preStop != nil {
d.Events.PreStop = preStop
}
}
Loading