Skip to content

Commit

Permalink
Merge pull request #5 from b1zzu/recursive-apply-directory
Browse files Browse the repository at this point in the history
chore: add option to recursive apply directory
  • Loading branch information
b1zzu authored Feb 4, 2022
2 parents a297359 + fe99844 commit 29fc627
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 9 deletions.
8 changes: 5 additions & 3 deletions cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import (
)

var (
applyFile string
applyProject string
applyFile string
applyProject string
applyRecursive bool

applyCmd = &cobra.Command{
Use: "apply",
Expand All @@ -20,14 +21,15 @@ var (
}
r := rpdac.NewReportPortal(c)

return r.Apply(applyProject, applyFile)
return r.Apply(applyProject, applyFile, applyRecursive)
},
}
)

func init() {
applyCmd.Flags().StringVarP(&applyFile, "file", "f", "", "YAML file")
applyCmd.Flags().StringVarP(&applyProject, "project", "p", "", "ReportPortal Project")
applyCmd.Flags().BoolVarP(&applyRecursive, "recursive", "r", false, "If file is a directory it will recusive apply all objects in it")

applyCmd.MarkFlagRequired("file")
applyCmd.MarkFlagRequired("project")
Expand Down
2 changes: 0 additions & 2 deletions pkg/rpdac/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,6 @@ func (s *FilterService) Update(project string, current, target Object) error {
if err != nil {
return fmt.Errorf("error updating filter \"%s\": %w", targetFilter.Name, err)
}

log.Printf("update \"%s\" filter", targetFilter.Name)
return nil
}

Expand Down
59 changes: 58 additions & 1 deletion pkg/rpdac/reportportal.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package rpdac

import (
"errors"
"fmt"
"io/fs"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"

"github.com/b1zzu/reportportal-dashboards-as-code/pkg/reportportal"
"gopkg.in/yaml.v2"
Expand Down Expand Up @@ -122,7 +127,59 @@ func (r *ReportPortal) Create(project, file string) error {
return nil
}

func (r *ReportPortal) Apply(project, file string) error {
func (r *ReportPortal) Apply(project, file string, recursive bool) error {

info, err := os.Stat(file)
if os.IsNotExist(err) {
return fmt.Errorf("error '%s' is not a vailid file or directory: %w", file, err)
} else if err != nil {
return err
}

if info.IsDir() {

if !recursive {
return fmt.Errorf("error '%s' is a directory, use the `-r` option if you want to recursive apply all object in the directory", file)
}

failed := false
err = filepath.WalkDir(file, func(path string, d fs.DirEntry, err error) error {
if err != nil {
log.Printf("Unknow error: %s", err)
return nil
}

if d.IsDir() {
// skip directories
return nil
}

if !strings.HasSuffix(d.Name(), ".yml") && !strings.HasSuffix(d.Name(), ".yaml") {
log.Printf("Ignore file '%s' because only .yml|.yaml are supported", path)
return nil
}

if err := r.ApplyFile(project, path); err != nil {
failed = true
log.Printf("Failed to apply file '%s': %s", path, err)
}
return nil
})
if err != nil {
return err
}

if failed {
return errors.New("error applying one or more objects")
}
return nil

} else {
return r.ApplyFile(project, file)
}
}

func (r *ReportPortal) ApplyFile(project, file string) error {

fileBytes, err := ioutil.ReadFile(file)
if err != nil {
Expand Down
147 changes: 144 additions & 3 deletions pkg/rpdac/reportportal_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package rpdac

import (
"fmt"
"io/ioutil"
"os"
"testing"
Expand Down Expand Up @@ -268,7 +269,7 @@ description: Test desc
r := NewReportPortal(nil)
r.Dashboard = mockService

err := r.Apply("test_project", file)
err := r.Apply("test_project", file, false)
if err != nil {
t.Errorf("Apply retunred error: %s", err)
}
Expand Down Expand Up @@ -317,7 +318,7 @@ description: Test new desc
r := NewReportPortal(nil)
r.Dashboard = mockService

err := r.Apply("test_project", file)
err := r.Apply("test_project", file, false)
if err != nil {
t.Errorf("Apply retunred error: %s", err)
}
Expand Down Expand Up @@ -355,10 +356,150 @@ description: Test desc
r := NewReportPortal(nil)
r.Dashboard = mockService

err := r.Apply("test_project", file)
err := r.Apply("test_project", file, false)
if err != nil {
t.Errorf("Apply retunred error: %s", err)
}

testDeepEqual(t, mockService.Counter, MockServiceCounter{GetByName: 1, Create: 1})
}

func tempDir(t *testing.T) (string, func()) {
t.Helper()

dir, err := ioutil.TempDir("", "")
if err != nil {
t.Fatalf("failed to create tmp directory: %s", err)
}
return dir, func() { os.RemoveAll(dir) }
}

func mkdir(t *testing.T, name string) {
t.Helper()

err := os.Mkdir(name, 0755)
if err != nil {
t.Fatalf("failed to create dir '%s': %s", name, err)
}
}

func writeFile(t *testing.T, filename, data string) {
t.Helper()

err := ioutil.WriteFile(filename, []byte(data), 0644)
if err != nil {
t.Fatalf("failed to write file '%s': %s", filename, err)
}
}

func TestApply_Directory(t *testing.T) {

dir, clean := tempDir(t)
defer clean()

writeFile(t, dir+"/dashboard.yml", `kind: Dashboard
name: Test
`)
writeFile(t, dir+"/skipme.xml", `Some randome stuff`)
mkdir(t, dir+"/subfolder")
writeFile(t, dir+"/subfolder/filter.yaml", `kind: Filter
name: Test
`)

mockDashboardService := &MockService{
GetByNameM: func(project, name string) (Object, error) {
testEqual(t, project, "test_project")
testEqual(t, name, "Test")
return nil, nil
},
CreateM: func(project string, o Object) error {
testEqual(t, project, "test_project")
testDeepEqual(t, o, &Dashboard{
Kind: DashboardKind,
Name: "Test",
}, cmpopts.IgnoreUnexported(Dashboard{}))
return nil
},
}
mockFilterService := &MockService{
GetByNameM: func(project, name string) (Object, error) {
testEqual(t, project, "test_project")
testEqual(t, name, "Test")
return &Filter{
Kind: FilterKind,
Name: "Test",
}, nil
},
}
r := NewReportPortal(nil)
r.Dashboard = mockDashboardService
r.Filter = mockFilterService

err := r.Apply("test_project", dir, true)
if err != nil {
t.Errorf("Apply retunred error: %s", err)
}

testDeepEqual(t, mockDashboardService.Counter, MockServiceCounter{GetByName: 1, Create: 1})
testDeepEqual(t, mockFilterService.Counter, MockServiceCounter{GetByName: 1})
}

func TestApply_DirectoryWithoutRecursive(t *testing.T) {

dir, clean := tempDir(t)
defer clean()
r := NewReportPortal(nil)

err := r.Apply("test_project", dir, false)
if err == nil {
t.Errorf("Want err but got nil")
} else {
want := fmt.Sprintf("error '%s' is a directory, use the `-r` option if you want to recursive apply all object in the directory", dir)
if err.Error() != want {
t.Errorf("Want err '%s' but got '%s'", want, err)
}
}
}

func TestApply_DirectoryWithWrongObject(t *testing.T) {

dir, clean := tempDir(t)
defer clean()

writeFile(t, dir+"/dashboard.yml", `kind: Something
name: Test
`)
writeFile(t, dir+"/skipme.xml", `Some randome stuff`)
mkdir(t, dir+"/subfolder")
writeFile(t, dir+"/subfolder/filter.yaml", `kind: Filter
name: Test
`)

mockDashboardService := &MockService{}
mockFilterService := &MockService{
GetByNameM: func(project, name string) (Object, error) {
testEqual(t, project, "test_project")
testEqual(t, name, "Test")
return &Filter{
Kind: FilterKind,
Name: "Test",
}, nil
},
}
r := NewReportPortal(nil)
r.Dashboard = mockDashboardService
r.Filter = mockFilterService

err := r.Apply("test_project", dir, true)
if err == nil {
t.Errorf("Want err but got nil")
} else {
want := "error applying one or more objects"
if err.Error() != want {
t.Errorf("Want err '%s' but got '%s'", want, err)
}
}

testDeepEqual(t, mockDashboardService.Counter, MockServiceCounter{})
testDeepEqual(t, mockFilterService.Counter, MockServiceCounter{GetByName: 1})
}

0 comments on commit 29fc627

Please sign in to comment.