This repository has been archived by the owner on Jun 14, 2019. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Extract Node type and Tree func to tree package. * Document public interface for package tree. * Add tests for (Node) Print() output and for Tree() generation of Node. * Add Godeps, Circle config, and bin/vet from https://github.com/thoughtbot/laces
- Loading branch information
1 parent
a7f7c80
commit 62418fe
Showing
11 changed files
with
243 additions
and
92 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#!/usr/bin/env bash | ||
# | ||
# validates that the project is clean of formatting and vet errors. | ||
# symlink as .git/hooks/pre-commit to use as a pre-commit check. | ||
# | ||
|
||
if [[ -n "${GIT_INDEX_FILE}" ]]; then | ||
gofiles=$(git diff --cached --name-only --diff-filter=ACM | grep '.go$') | ||
else | ||
gofiles=$(find . ! -path "*/_*" -name "*.go") | ||
fi | ||
|
||
[ -z "$gofiles" ] && exit 0 | ||
|
||
function checkfmt() { | ||
unformatted=$(gofmt -l $*) | ||
[ -z "$unformatted" ] && return 0 | ||
|
||
echo >&2 "Go files must be formatted with gofmt. Please run:" | ||
for fn in $unformatted; do | ||
echo >&2 " gofmt -w $PWD/$fn" | ||
done | ||
|
||
return 1 | ||
} | ||
|
||
function checkvet() { | ||
unvetted=$(go vet ./... 2>&1 | grep -v "exit status") | ||
[ -z "$unvetted" ] && return 0 | ||
|
||
echo >&2 "Go files must be vetted. Check these problems:" | ||
IFS=$'\n' | ||
for line in $unvetted; do | ||
echo >&2 " $line" | ||
done | ||
unset IFS | ||
|
||
return 1 | ||
} | ||
|
||
checkfmt $gofiles || fail=yes | ||
checkvet $gofiles || fail=yes | ||
|
||
[ -z "$fail" ] || exit 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# See https://robots.thoughtbot.com/configure-circleci-for-go | ||
machine: | ||
environment: | ||
IMPORT_PATH: "github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME" | ||
MYGOPATH: "$(echo $GOPATH | cut -d : -f 1)" | ||
|
||
dependencies: | ||
pre: | ||
- go get github.com/tools/godep | ||
|
||
override: | ||
- mkdir -p "$MYGOPATH/src/$IMPORT_PATH" | ||
- rsync -azC --delete ./ "$MYGOPATH/src/$IMPORT_PATH/" | ||
|
||
test: | ||
pre: | ||
- bin/vet | ||
|
||
override: | ||
- godep go test ./... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"os" | ||
|
||
"github.com/calebthompson/ftree/tree" | ||
) | ||
|
||
func main() { | ||
r := bufio.NewScanner(os.Stdin) | ||
lines := []string{} | ||
for r.Scan() { | ||
lines = append(lines, r.Text()) | ||
} | ||
|
||
t := tree.Tree(lines, "/") | ||
t.Print(0, nil) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package tree | ||
|
||
import ( | ||
"fmt" | ||
"sort" | ||
) | ||
|
||
// Node is a tree of string. Leaves are empty Nodes or nil. | ||
type Node map[string]Node | ||
|
||
// Print recurses through n and its member Nodes to pretty-print a Node as a | ||
// tree such as: | ||
// | ||
// ├── ftree | ||
// │ ├── node.go | ||
// │ ├── tree.go | ||
// │ └── tree_test.go | ||
// └── main.go | ||
// | ||
// Print should initially be called as n.Print(0, nil). The arguments are | ||
// primarily interesting during recursion. | ||
func (n Node) Print(indent int, leaders []string) { | ||
var keys []string | ||
for k := range n { | ||
keys = append(keys, k) | ||
} | ||
sort.Strings(keys) | ||
|
||
for i, part := range keys { | ||
if part == "" { | ||
n[part].Print(indent, leaders) | ||
continue | ||
} | ||
|
||
for _, l := range leaders { | ||
fmt.Print(l) | ||
} | ||
|
||
// For chains of single element maps, such as | ||
// { "Users": { "caleb": { "code": {}, "books": {} } }, | ||
// combine to { "Users/caleb": { "code": {}, "books": {} } }. | ||
for { | ||
if len(n[part]) != 1 { | ||
break | ||
} | ||
for k, v := range n[part] { | ||
part += "/" + k | ||
n[part] = v | ||
} | ||
} | ||
|
||
if i == len(keys)-1 { | ||
fmt.Printf("%s %s\n", "└──", part) | ||
n[part].Print(indent+1, append(leaders, " ")) | ||
} else { | ||
fmt.Printf("%s %s\n", "├──", part) | ||
n[part].Print(indent+1, append(leaders, "│ ")) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package tree | ||
|
||
func ExamplePrint() { | ||
tree := Node{ | ||
"caleb": Node{ | ||
"code": Node{"ftree": Node{}}, | ||
"books": Node{ | ||
"Learning Go": Node{}, | ||
"The Little Go Book": Node{}, | ||
}, | ||
}, | ||
} | ||
|
||
tree.Print(0, nil) | ||
|
||
// Output: | ||
// └── caleb | ||
// ├── books | ||
// │ ├── Learning Go | ||
// │ └── The Little Go Book | ||
// └── code/ftree | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package tree | ||
|
||
import "strings" | ||
|
||
// Tree splits each line in lines on delim and builds a Node: a tree data | ||
// structure of maps with string keys. | ||
func Tree(lines []string, delim string) Node { | ||
var parts []Node | ||
for _, line := range lines { | ||
parts = append(parts, buildTree(line, delim)) | ||
} | ||
|
||
var tree Node | ||
for _, part := range parts { | ||
tree = merge(part, tree) | ||
} | ||
|
||
return tree | ||
} | ||
|
||
func buildTree(line, delim string) Node { | ||
var subtree = Node{} | ||
split := strings.SplitN(line, delim, 2) | ||
if len(split) > 1 { | ||
subtree[split[0]] = buildTree(split[1], delim) | ||
} else { | ||
subtree[split[0]] = Node{} | ||
} | ||
return subtree | ||
} | ||
|
||
func merge(src Node, dest Node) Node { | ||
if dest == nil { | ||
dest = Node{} | ||
} | ||
for k, v := range src { | ||
dest[k] = merge(v, dest[k]) | ||
} | ||
return dest | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package tree | ||
|
||
import ( | ||
"reflect" | ||
"testing" | ||
) | ||
|
||
func TestTree(t *testing.T) { | ||
lines := []string{ | ||
"caleb/code/ftree", | ||
"caleb/books", | ||
} | ||
|
||
want := Node{ | ||
"caleb": Node{ | ||
"code": Node{"ftree": Node{}}, | ||
"books": Node{}, | ||
}, | ||
} | ||
|
||
got := Tree(lines, "/") | ||
|
||
if !reflect.DeepEqual(want, got) { | ||
t.Fatalf("Expected \n%#v, got \n%#v", want, got) | ||
} | ||
} |