Skip to content

Commit 71b4c73

Browse files
committed
Add directory tree generation
1 parent d8556a1 commit 71b4c73

File tree

4 files changed

+83
-3
lines changed

4 files changed

+83
-3
lines changed

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/flowdev/spaghetti-cutter
22

3-
go 1.14
3+
go 1.16
44

55
require (
66
github.com/hjson/hjson-go v3.0.1+incompatible

go.sum

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
github.com/hjson/hjson-go v0.2.3 h1:KhG7/PSxTibbYOzFso5FoiX2gWePcANaCsvM1WE/bTo=
21
github.com/hjson/hjson-go v3.0.1+incompatible h1:JwOXblcMiBbiWue7iPkoFK9oXSnW8n+qXh/0Fio6TCo=
32
github.com/hjson/hjson-go v3.0.1+incompatible/go.mod h1:qsetwF8NlsTsOTwZTApNlTCerV+b2GjYRRcIk4JMFio=
43
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=

main.go

+28-1
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,14 @@ func cut(args []string) int {
3737
usageNoLinks = "don't use links in '" + doc.FileName + "' files"
3838
defaultStats = "*"
3939
usageStats = "write '" + stat.FileName + "' for packages (separated by ','; '' for none)"
40+
defaultDirTree = false
41+
usageDirTree = "write a directory tree to the 'dirtree.txt' file"
4042
)
4143
var startDir string
4244
var docPkgs string
4345
var noLinks bool
4446
var statPkgs string
47+
var dirTree bool
4548
fs := flag.NewFlagSet("spaghetti-cutter", flag.ExitOnError)
4649
fs.StringVar(&startDir, "root", defaultRoot, usageRoot)
4750
fs.StringVar(&startDir, "r", defaultRoot, usageRoot+usageShort)
@@ -51,6 +54,8 @@ func cut(args []string) int {
5154
fs.BoolVar(&noLinks, "l", defaultNoLinks, usageNoLinks+usageShort)
5255
fs.StringVar(&statPkgs, "stats", defaultStats, usageStats)
5356
fs.StringVar(&statPkgs, "s", defaultStats, usageStats+usageShort)
57+
fs.BoolVar(&dirTree, "dirtree", defaultDirTree, usageDirTree)
58+
fs.BoolVar(&dirTree, "t", defaultDirTree, usageDirTree+usageShort)
5459
err := fs.Parse(args)
5560
if err != nil {
5661
log.Printf("FATAL - %v", err)
@@ -123,6 +128,10 @@ func cut(args []string) int {
123128
log.Print("INFO - No documentation wanted.")
124129
}
125130

131+
if dirTree {
132+
writeDirTree(root, ".")
133+
}
134+
126135
return retCode
127136
}
128137

@@ -136,7 +145,7 @@ func writeStatistics(stPkgs, root, rootPkg string, depMap data.DependencyMap) {
136145
continue
137146
}
138147
statFile := filepath.Join(statPkg, stat.FileName)
139-
log.Printf("INFO - Write package statistics to file: %s", statFile)
148+
log.Printf("INFO - Writeing package statistics to file: %s", statFile)
140149
statFile = filepath.Join(root, statFile)
141150
err := ioutil.WriteFile(statFile, []byte(statMD), 0644)
142151
if err != nil {
@@ -156,6 +165,24 @@ func writeDocumentation(docPkgs, root, rootPkg string, noLinks bool, depMap data
156165
doc.WriteDocs(dtPkgs, depMap, linkDocPkgs, rootPkg, root)
157166
}
158167

168+
var mapEntry = struct{}{}
169+
170+
func writeDirTree(root, name string) error {
171+
treeFile := filepath.Join(root, dirs.TreeFile)
172+
log.Printf("INFO - Writing directory tree to file: %s", treeFile)
173+
tree, err := dirs.Tree(root, name, []string{"vendor", "testdata", ".*"})
174+
if err != nil {
175+
log.Print("ERROR - Unable to generate directory tree")
176+
return err
177+
}
178+
err = ioutil.WriteFile(treeFile, []byte(tree), 0644)
179+
if err != nil {
180+
log.Printf("ERROR - Unable to write directory tree to file %s: %v", treeFile, err)
181+
return err
182+
}
183+
return nil
184+
}
185+
159186
func findPackagesWithFileAsSlice(signalFile, pkgNames, root, pkgType string) []string {
160187
var pkgs []string
161188
if pkgNames == "*" { // find all existing files

x/dirs/dirs.go

+54
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,20 @@ import (
44
"fmt"
55
"log"
66
"os"
7+
"path"
78
"path/filepath"
89
"strings"
910
)
1011

12+
const (
13+
TreeFile = "dirtree.txt"
14+
newLine = "\n"
15+
emptyItem = " "
16+
middleItem = "├── "
17+
continueItem = "│ "
18+
lastItem = "└── "
19+
)
20+
1121
// FindRoot finds the root of a project.
1222
// It looks for the configuration file: .spaghetti-cutter.json
1323
func FindRoot(startDir, cfgFile string) (string, error) {
@@ -94,3 +104,47 @@ func FindPkgsWithFile(file string, startPkgs []string, root string, excludeRoot
94104
}
95105
return retPkgs
96106
}
107+
108+
func Tree(root, name string, exclude []string) (string, error) {
109+
sb := &strings.Builder{}
110+
111+
err := generateTree(root, name, sb, "", exclude)
112+
if err != nil {
113+
return "", err
114+
}
115+
return sb.String(), nil
116+
}
117+
118+
func generateTree(root, name string, sb *strings.Builder, indent string, exclude []string) error {
119+
sb.WriteString(name)
120+
sb.WriteString(newLine)
121+
122+
files, err := os.ReadDir(root)
123+
if err != nil {
124+
log.Printf("ERROR - Unable to read the directory %q: %v", root, err)
125+
return err
126+
}
127+
128+
lastI := len(files) - 1
129+
for i, file := range files {
130+
if file.IsDir() && includeFile(file.Name(), exclude) {
131+
if i == lastI {
132+
sb.WriteString(indent + lastItem)
133+
generateTree(filepath.Join(root, file.Name()), file.Name(), sb, indent+emptyItem, exclude)
134+
} else {
135+
sb.WriteString(indent + middleItem)
136+
generateTree(filepath.Join(root, file.Name()), file.Name(), sb, indent+continueItem, exclude)
137+
}
138+
}
139+
}
140+
return nil
141+
}
142+
143+
func includeFile(name string, exclude []string) bool {
144+
for _, ex := range exclude {
145+
if m, _ := path.Match(ex, name); m {
146+
return false
147+
}
148+
}
149+
return true
150+
}

0 commit comments

Comments
 (0)