Skip to content

Commit

Permalink
Merge pull request #47 from ivanilves/issue-45
Browse files Browse the repository at this point in the history
refactor(issue-45): improve "tree" and "node" packages
  • Loading branch information
ivanilves committed Apr 14, 2023
2 parents c1d16e5 + f552996 commit f4743ad
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 60 deletions.
18 changes: 11 additions & 7 deletions cmd/travelgrunt/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@ func buildMenuFromTree(t tree.Tree) string {
var selected string
var parentID string

for c := -1; c < t.LevelCount(); c++ {
if !t.HasChildren(c, parentID) {
selected = parentID

break
for idx := -1; idx < t.LevelCount(); idx++ {
if len(parentID) > 0 {
if !t.GetNode(parentID).HasChildren() {
return parentID
}
}

selected, err := menu.Build(t.ChildNames(c, parentID), terminal.Height(), parentID)
selected, err := menu.Build(t.LevelChildNames(idx, parentID), terminal.Height(), parentID)

if err != nil {
if err.Error() == "^C" {
Expand All @@ -63,7 +63,11 @@ func buildMenuFromTree(t tree.Tree) string {
log.Fatalf("failed to build menu: %s", err.Error())
}

parentID = t.ChildItems(c, parentID)[selected]
if selected == "." {
return parentID
}

parentID = t.LevelChildItems(idx, parentID)[selected]
}

return selected
Expand Down
4 changes: 2 additions & 2 deletions pkg/directory/tree/node/node.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package node

// Node is an element Tree gets composed from (a path with hierarchical and connection metadata)
// Node is an element Tree gets composed from (a path enriched with hierarchical and connection metadata)
type Node struct {
name string
path string
Expand Down Expand Up @@ -32,7 +32,7 @@ func (n Node) HasChildren() bool {
return len(n.children) > 0
}

// IsTerminal tells us if that node has can be a Tree exit point
// IsTerminal tells us if that node has can be used as a tree exit point
func (n Node) IsTerminal() bool {
return n.terminal
}
30 changes: 12 additions & 18 deletions pkg/directory/tree/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,13 @@ func (t Tree) levelItems(idx int) (items map[string]string) {
return items
}

// ChildItems gives us a list of child items for the [parent] node located on the given level ID and the given path
func (t Tree) ChildItems(idx int, parentPath string) (items map[string]string) {
// GetNode returns a node record for the given path
func (t Tree) GetNode(path string) node.Node {
return t.nodes[path]
}

// LevelChildItems gives us a list of child items for the [parent] node located on the given level ID and on the given path
func (t Tree) LevelChildItems(idx int, parentPath string) (items map[string]string) {
if len(t.levels) < idx+1 {
return nil
}
Expand All @@ -152,8 +157,8 @@ func (t Tree) ChildItems(idx int, parentPath string) (items map[string]string) {
items = make(map[string]string, len(t.levels[idx+1]))

for path, name := range t.levels[idx+1] {
currentNode := t.nodes[path]
parentNode := t.nodes[parentPath]
currentNode := t.GetNode(path)
parentNode := t.GetNode(parentPath)

if currentNode.IsAChildOf(parentNode) {
items[name] = path
Expand All @@ -167,18 +172,7 @@ func (t Tree) ChildItems(idx int, parentPath string) (items map[string]string) {
return items
}

// ChildNames gives us a list of child names for the [parent] node located on the given level ID and the given path
func (t Tree) ChildNames(idx int, parentPath string) []string {
return sortedKeys(t.ChildItems(idx, parentPath))
}

// HasChildren tells us if a node on the given level ID and the given path has child nodes (if node is a parent itself)
func (t Tree) HasChildren(idx int, parentPath string) bool {
return len(t.ChildItems(idx, parentPath)) > 0
}

func (t Tree) nodeExists(path string) bool {
_, defined := t.nodes[path]

return defined
// LevelChildNames gives us a list of child names for the [parent] node located on the given level ID and on the given path
func (t Tree) LevelChildNames(idx int, parentPath string) []string {
return sortedKeys(t.LevelChildItems(idx, parentPath))
}
37 changes: 9 additions & 28 deletions pkg/directory/tree/tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,25 +64,25 @@ func TestLevelItems(t *testing.T) {
assert.Equal("terragrunt", items["terragrunt"])
}

func TestChildItems(t *testing.T) {
func TestLevelChildItems(t *testing.T) {
assert := assert.New(t)

assert.Nil(mock.ChildItems(10, "whatever"))
assert.Equal(map[string]string{}, mock.ChildItems(4, "terragrunt/prod/region-1/k8s/foo"))
assert.Equal(mock.levelItems(0), mock.ChildItems(-1, "ignored-if-minus-one-passed"))
assert.Nil(mock.LevelChildItems(10, "whatever"))
assert.Equal(map[string]string{}, mock.LevelChildItems(4, "terragrunt/prod/region-1/k8s/foo"))
assert.Equal(mock.levelItems(0), mock.LevelChildItems(-1, "ignored-if-minus-one-passed"))

items := mock.ChildItems(0, "terragrunt")
items := mock.LevelChildItems(0, "terragrunt")
expected := map[string]string{"dev": "terragrunt/dev", "prod": "terragrunt/prod"}

assert.NotNil(items)
assert.Equal(2, len(items))
assert.Equal(expected, items)
}

func TestChildItemsTerminalAndWithChildren(t *testing.T) {
func TestLevelChildItemsTerminalAndWithChildren(t *testing.T) {
assert := assert.New(t)

items := mock.ChildItems(3, "terragrunt/dev/region-1/rds")
items := mock.LevelChildItems(3, "terragrunt/dev/region-1/rds")
expected := map[string]string{
".": "terragrunt/dev/region-1/rds",
"bar": "terragrunt/dev/region-1/rds/bar",
Expand All @@ -95,32 +95,13 @@ func TestChildItemsTerminalAndWithChildren(t *testing.T) {
assert.Equal(expected, items)
}

func TestChildNames(t *testing.T) {
func TestLevelChildNames(t *testing.T) {
assert := assert.New(t)

items := mock.ChildNames(0, "terragrunt")
items := mock.LevelChildNames(0, "terragrunt")
expected := []string{"dev", "prod"}

assert.NotNil(items)
assert.Equal(2, len(items))
assert.Equal(expected, items)
}

func TestHasChildren(t *testing.T) {
assert := assert.New(t)

assert.True(mock.HasChildren(-1, ""))
assert.True(mock.HasChildren(-1, "whatever"))

assert.True(mock.nodeExists("terragrunt"))
assert.True(mock.HasChildren(0, "terragrunt"))

assert.True(mock.nodeExists("terragrunt/prod/region-1/k8s"))
assert.True(mock.HasChildren(3, "terragrunt/prod/region-1/k8s"))

assert.False(mock.nodeExists("i-do-not-exist"))
assert.False(mock.HasChildren(0, "i-do-not-exist"))

assert.True(mock.nodeExists("terragrunt/prod/region-1/k8s/foo"))
assert.False(mock.HasChildren(4, "terragrunt/prod/region-1/k8s/foo"))
}
12 changes: 7 additions & 5 deletions pkg/menu/menu.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@ func getSize(itemCount int, size int) int {
}

// Build creates an interactive menu to chose destination directory from
func Build(items []string, maxSize int, previous string) (selected string, err error) {
func Build(items []string, size int, parentID string) (selected string, err error) {
var extension string

if len(items) == 0 {
return "", fmt.Errorf("no items")
}

if len(previous) > 0 {
fmt.Printf("=> %s\n", previous)
if len(parentID) > 0 {
extension = fmt.Sprintf(" [from \"%s\"]", parentID)
}

if len(items) == 1 {
Expand All @@ -50,9 +52,9 @@ func Build(items []string, maxSize int, previous string) (selected string, err e
}

prompt := promptui.Select{
Label: label,
Label: label + extension,
Items: items,
Size: getSize(len(items), maxSize-Overhead),
Size: getSize(len(items), size-Overhead),
Searcher: searcher,
}

Expand Down

0 comments on commit f4743ad

Please sign in to comment.