unfiltered walker tree
This commit is contained in:
+54
-108
@@ -52,11 +52,15 @@ func Write(result *walker.Result, outputPath string, appendMode bool, singleFile
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !singleFile {
|
if !singleFile {
|
||||||
root := tree.Build(result.Entries)
|
treeRoot, err := tree.BuildFullTree(result.AbsRoot, result.Cfg)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot build tree: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
rootName := filepath.Base(result.AbsRoot)
|
rootName := filepath.Base(result.AbsRoot)
|
||||||
sb.WriteString("## Directory Tree\n\n")
|
sb.WriteString("## Directory Tree\n\n")
|
||||||
sb.WriteString(fenceChars + "\n")
|
sb.WriteString(fenceChars + "\n")
|
||||||
sb.WriteString(renderTreeForLLM(root, rootName))
|
sb.WriteString(renderTreeWithLegend(treeRoot, rootName))
|
||||||
sb.WriteString(fenceChars + "\n\n")
|
sb.WriteString(fenceChars + "\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,13 +121,9 @@ func WriteSlices(result *walker.Result, outputDir, repoName string) ([]string, e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var generated []string
|
treeRoot, err := tree.BuildFullTree(absRoot, result.Cfg)
|
||||||
indexBasename := "index_" + repoName + ".md"
|
if err != nil {
|
||||||
rootPath := filepath.Join(outputDir, indexBasename)
|
return nil, fmt.Errorf("cannot build full tree: %w", err)
|
||||||
generated = append(generated, rootPath)
|
|
||||||
|
|
||||||
if err := writeRootSlice(rootPath, absRoot, rootName, repoName, rootFiles, topLevelDirs, result.OmitTest, result.Commit, result.Instructions); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to write root slice: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var dirNames []string
|
var dirNames []string
|
||||||
@@ -132,6 +132,21 @@ func WriteSlices(result *walker.Result, outputDir, repoName string) ([]string, e
|
|||||||
}
|
}
|
||||||
sort.Strings(dirNames)
|
sort.Strings(dirNames)
|
||||||
|
|
||||||
|
for _, dirName := range dirNames {
|
||||||
|
if node, ok := treeRoot.Children[dirName]; ok {
|
||||||
|
node.Ref = filepath.Join(dirName, dirName+"_"+repoName+".md")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var generated []string
|
||||||
|
indexBasename := "index_" + repoName + ".md"
|
||||||
|
rootPath := filepath.Join(outputDir, indexBasename)
|
||||||
|
generated = append(generated, rootPath)
|
||||||
|
|
||||||
|
if err := writeRootSlice(rootPath, absRoot, rootName, repoName, rootFiles, topLevelDirs, result.OmitTest, result.Commit, result.Instructions, treeRoot); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to write root slice: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
for _, dirName := range dirNames {
|
for _, dirName := range dirNames {
|
||||||
sliceName := strings.TrimSuffix(dirName, "/") + "_" + repoName + ".md"
|
sliceName := strings.TrimSuffix(dirName, "/") + "_" + repoName + ".md"
|
||||||
sliceDir := filepath.Join(outputDir, dirName)
|
sliceDir := filepath.Join(outputDir, dirName)
|
||||||
@@ -144,17 +159,7 @@ func WriteSlices(result *walker.Result, outputDir, repoName string) ([]string, e
|
|||||||
absDir := filepath.Join(absRoot, dirName)
|
absDir := filepath.Join(absRoot, dirName)
|
||||||
dirEntries := topLevelDirs[dirName]
|
dirEntries := topLevelDirs[dirName]
|
||||||
|
|
||||||
treeEntries := make([]walker.Entry, len(dirEntries))
|
if err := writeDirSlice(slicePath, absDir, absRoot, dirName, dirEntries, indexBasename, result.OmitTest, result.Commit, treeRoot); err != nil {
|
||||||
for i, e := range dirEntries {
|
|
||||||
sepIdx := strings.Index(e.RelPath, string(filepath.Separator))
|
|
||||||
if sepIdx >= 0 {
|
|
||||||
treeEntries[i] = walker.Entry{RelPath: e.RelPath[sepIdx+1:], Size: e.Size}
|
|
||||||
} else {
|
|
||||||
treeEntries[i] = e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := writeDirSlice(slicePath, absDir, absRoot, dirName, treeEntries, dirEntries, indexBasename, result.OmitTest, result.Commit); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to write slice %s: %w", sliceName, err)
|
return nil, fmt.Errorf("failed to write slice %s: %w", sliceName, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,7 +167,7 @@ func WriteSlices(result *walker.Result, outputDir, repoName string) ([]string, e
|
|||||||
return generated, nil
|
return generated, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeRootSlice(path, absRoot, rootName, repoName string, rootFiles []walker.Entry, topLevelDirs map[string][]walker.Entry, omitTest bool, commit *git.CommitInfo, instContent string) error {
|
func writeRootSlice(path, absRoot, rootName, repoName string, rootFiles []walker.Entry, topLevelDirs map[string][]walker.Entry, omitTest bool, commit *git.CommitInfo, instContent string, treeRoot *tree.Node) error {
|
||||||
f, err := os.Create(path)
|
f, err := os.Create(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot create root file: %w", err)
|
return fmt.Errorf("cannot create root file: %w", err)
|
||||||
@@ -179,10 +184,9 @@ func writeRootSlice(path, absRoot, rootName, repoName string, rootFiles []walker
|
|||||||
sb.WriteString("\n")
|
sb.WriteString("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
treeLines := buildTreeWithRefs(rootName, repoName, topLevelDirs, rootFiles)
|
|
||||||
sb.WriteString("## Directory Tree\n\n")
|
sb.WriteString("## Directory Tree\n\n")
|
||||||
sb.WriteString(fenceChars + "\n")
|
sb.WriteString(fenceChars + "\n")
|
||||||
sb.WriteString(treeLines)
|
sb.WriteString(renderTreeWithLegend(treeRoot, rootName))
|
||||||
sb.WriteString(fenceChars + "\n\n")
|
sb.WriteString(fenceChars + "\n\n")
|
||||||
|
|
||||||
sb.WriteString("## Vertical Slices Index\n\n")
|
sb.WriteString("## Vertical Slices Index\n\n")
|
||||||
@@ -238,7 +242,7 @@ func writeRootSlice(path, absRoot, rootName, repoName string, rootFiles []walker
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeDirSlice(path, absDir, absRoot, dirName string, treeEntries, fileEntries []walker.Entry, rootFileName string, omitTest bool, commit *git.CommitInfo) error {
|
func writeDirSlice(path, absDir, absRoot, dirName string, fileEntries []walker.Entry, rootFileName string, omitTest bool, commit *git.CommitInfo, treeRoot *tree.Node) error {
|
||||||
f, err := os.Create(path)
|
f, err := os.Create(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot create slice file: %w", err)
|
return fmt.Errorf("cannot create slice file: %w", err)
|
||||||
@@ -254,8 +258,7 @@ func writeDirSlice(path, absDir, absRoot, dirName string, treeEntries, fileEntri
|
|||||||
|
|
||||||
sb.WriteString("## Directory Tree\n\n")
|
sb.WriteString("## Directory Tree\n\n")
|
||||||
sb.WriteString(fenceChars + "\n")
|
sb.WriteString(fenceChars + "\n")
|
||||||
sliceTree := buildTreeFromEntries(dirName, treeEntries)
|
sb.WriteString(renderTreeWithLegend(treeRoot, filepath.Base(absRoot)))
|
||||||
sb.WriteString(sliceTree)
|
|
||||||
sb.WriteString(fenceChars + "\n\n")
|
sb.WriteString(fenceChars + "\n\n")
|
||||||
|
|
||||||
if len(fileEntries) > 0 {
|
if len(fileEntries) > 0 {
|
||||||
@@ -287,93 +290,16 @@ func writeDirSlice(path, absDir, absRoot, dirName string, treeEntries, fileEntri
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildTreeWithRefs(rootName, repoName string, topLevelDirs map[string][]walker.Entry, rootFiles []walker.Entry) string {
|
func renderTreeWithLegend(root *tree.Node, rootName string) string {
|
||||||
var sb strings.Builder
|
|
||||||
sb.WriteString(rootName)
|
|
||||||
sb.WriteString("/\n")
|
|
||||||
|
|
||||||
var dirNames []string
|
|
||||||
for k := range topLevelDirs {
|
|
||||||
dirNames = append(dirNames, k)
|
|
||||||
}
|
|
||||||
sort.Strings(dirNames)
|
|
||||||
|
|
||||||
sort.Slice(rootFiles, func(i, j int) bool {
|
|
||||||
return rootFiles[i].RelPath < rootFiles[j].RelPath
|
|
||||||
})
|
|
||||||
|
|
||||||
type treeItem struct {
|
|
||||||
name string
|
|
||||||
isDir bool
|
|
||||||
sliceRef string
|
|
||||||
}
|
|
||||||
|
|
||||||
items := make([]treeItem, 0, len(dirNames)+len(rootFiles))
|
|
||||||
for _, d := range dirNames {
|
|
||||||
sliceRef := filepath.Join(d, strings.TrimSuffix(d, "/")+"_"+repoName+".md")
|
|
||||||
items = append(items, treeItem{
|
|
||||||
name: d,
|
|
||||||
isDir: true,
|
|
||||||
sliceRef: sliceRef,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
for _, rf := range rootFiles {
|
|
||||||
items = append(items, treeItem{
|
|
||||||
name: rf.RelPath,
|
|
||||||
isDir: false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Slice(items, func(i, j int) bool {
|
|
||||||
return items[i].name < items[j].name
|
|
||||||
})
|
|
||||||
|
|
||||||
for _, item := range items {
|
|
||||||
sb.WriteString("+- ")
|
|
||||||
sb.WriteString(item.name)
|
|
||||||
if item.isDir {
|
|
||||||
sb.WriteString("/")
|
|
||||||
sb.WriteString(" -> see ")
|
|
||||||
sb.WriteString(item.sliceRef)
|
|
||||||
}
|
|
||||||
sb.WriteString("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildTreeFromEntries(rootName string, entries []walker.Entry) string {
|
|
||||||
root := &tree.Node{IsDir: true, Children: make(map[string]*tree.Node)}
|
|
||||||
|
|
||||||
for _, e := range entries {
|
|
||||||
parts := strings.Split(e.RelPath, string(filepath.Separator))
|
|
||||||
cur := root
|
|
||||||
|
|
||||||
for i, part := range parts {
|
|
||||||
isLeaf := i == len(parts)-1
|
|
||||||
if _, ok := cur.Children[part]; !ok {
|
|
||||||
node := &tree.Node{Name: part, IsDir: !isLeaf}
|
|
||||||
if !isLeaf {
|
|
||||||
node.Children = make(map[string]*tree.Node)
|
|
||||||
}
|
|
||||||
cur.Children[part] = node
|
|
||||||
}
|
|
||||||
cur = cur.Children[part]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
sb.WriteString(rootName)
|
sb.WriteString(rootName)
|
||||||
sb.WriteString("/\n")
|
sb.WriteString("/\n")
|
||||||
renderNodeLLM(&sb, root, "")
|
renderNodeLLM(&sb, root, "")
|
||||||
return sb.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func renderTreeForLLM(root *tree.Node, rootName string) string {
|
if hasAnyAnnotation(root) {
|
||||||
var sb strings.Builder
|
sb.WriteString("Legend: ~ ignored | ~ tests omitted | ~ omitted | ~ exceeded --max-depth\n")
|
||||||
sb.WriteString(rootName)
|
}
|
||||||
sb.WriteString("/\n")
|
|
||||||
renderNodeLLM(&sb, root, "")
|
|
||||||
return sb.String()
|
return sb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,6 +321,14 @@ func renderNodeLLM(sb *strings.Builder, node *tree.Node, prefix string) {
|
|||||||
if child.IsDir {
|
if child.IsDir {
|
||||||
sb.WriteString("/")
|
sb.WriteString("/")
|
||||||
}
|
}
|
||||||
|
if child.Annotation != "" {
|
||||||
|
sb.WriteString(" ~ ")
|
||||||
|
sb.WriteString(child.Annotation)
|
||||||
|
}
|
||||||
|
if child.Ref != "" {
|
||||||
|
sb.WriteString(" -> see ")
|
||||||
|
sb.WriteString(child.Ref)
|
||||||
|
}
|
||||||
sb.WriteString("\n")
|
sb.WriteString("\n")
|
||||||
|
|
||||||
if child.IsDir && child.Children != nil {
|
if child.IsDir && child.Children != nil {
|
||||||
@@ -409,6 +343,18 @@ func renderNodeLLM(sb *strings.Builder, node *tree.Node, prefix string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hasAnyAnnotation(node *tree.Node) bool {
|
||||||
|
if node.Annotation != "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, child := range node.Children {
|
||||||
|
if hasAnyAnnotation(child) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func readFile(path string) (string, error) {
|
func readFile(path string) (string, error) {
|
||||||
data, err := os.ReadFile(path)
|
data, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+20
-60
@@ -1,76 +1,36 @@
|
|||||||
package tree
|
package tree
|
||||||
|
|
||||||
import (
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.flo.fo/FLO/dirmd/internal/walker"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Node struct {
|
type Node struct {
|
||||||
Name string
|
Name string
|
||||||
IsDir bool
|
IsDir bool
|
||||||
Children map[string]*Node
|
Children map[string]*Node
|
||||||
|
Annotation string
|
||||||
|
Ref string
|
||||||
}
|
}
|
||||||
|
|
||||||
func Build(entries []walker.Entry) *Node {
|
func splitPath(relPath string) []string {
|
||||||
root := &Node{IsDir: true, Children: make(map[string]*Node)}
|
var parts []string
|
||||||
|
start := 0
|
||||||
|
for i := 0; i <= len(relPath); i++ {
|
||||||
|
if i == len(relPath) || relPath[i] == '/' || relPath[i] == '\\' {
|
||||||
|
if i > start {
|
||||||
|
parts = append(parts, relPath[start:i])
|
||||||
|
}
|
||||||
|
start = i + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parts
|
||||||
|
}
|
||||||
|
|
||||||
for _, e := range entries {
|
func addPath(root *Node, rel string, isDir bool) *Node {
|
||||||
parts := strings.Split(e.RelPath, "/")
|
parts := splitPath(rel)
|
||||||
cur := root
|
cur := root
|
||||||
|
|
||||||
for i, part := range parts {
|
for i, part := range parts {
|
||||||
isLeaf := i == len(parts)-1
|
|
||||||
if _, ok := cur.Children[part]; !ok {
|
if _, ok := cur.Children[part]; !ok {
|
||||||
cur.Children[part] = &Node{Name: part, IsDir: !isLeaf, Children: make(map[string]*Node)}
|
cur.Children[part] = &Node{Name: part, IsDir: i < len(parts)-1, Children: make(map[string]*Node)}
|
||||||
}
|
}
|
||||||
cur = cur.Children[part]
|
cur = cur.Children[part]
|
||||||
}
|
}
|
||||||
}
|
cur.IsDir = isDir
|
||||||
|
return cur
|
||||||
return root
|
|
||||||
}
|
|
||||||
|
|
||||||
func Render(root *Node, rootName string) string {
|
|
||||||
var sb strings.Builder
|
|
||||||
sb.WriteString(rootName)
|
|
||||||
sb.WriteString("/\n")
|
|
||||||
renderNode(&sb, root, "")
|
|
||||||
return sb.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func renderNode(sb *strings.Builder, node *Node, prefix string) {
|
|
||||||
keys := make([]string, 0, len(node.Children))
|
|
||||||
for k := range node.Children {
|
|
||||||
keys = append(keys, k)
|
|
||||||
}
|
|
||||||
sort.Strings(keys)
|
|
||||||
|
|
||||||
for i, key := range keys {
|
|
||||||
child := node.Children[key]
|
|
||||||
isLast := i == len(keys)-1
|
|
||||||
|
|
||||||
if isLast {
|
|
||||||
sb.WriteString(prefix + "└── ")
|
|
||||||
} else {
|
|
||||||
sb.WriteString(prefix + "├── ")
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.WriteString(child.Name)
|
|
||||||
if child.IsDir {
|
|
||||||
sb.WriteString("/")
|
|
||||||
}
|
|
||||||
sb.WriteString("\n")
|
|
||||||
|
|
||||||
if child.IsDir {
|
|
||||||
newPrefix := prefix
|
|
||||||
if isLast {
|
|
||||||
newPrefix += " "
|
|
||||||
} else {
|
|
||||||
newPrefix += "│ "
|
|
||||||
}
|
|
||||||
renderNode(sb, child, newPrefix)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,170 @@
|
|||||||
|
package tree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.flo.fo/FLO/dirmd/internal/config"
|
||||||
|
"git.flo.fo/FLO/dirmd/internal/filter"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BuildFullTree(absRoot string, cfg *config.Config) (*Node, error) {
|
||||||
|
root := &Node{IsDir: true, Children: make(map[string]*Node)}
|
||||||
|
|
||||||
|
err := filepath.WalkDir(absRoot, func(path string, d fs.DirEntry, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
rel, rerr := filepath.Rel(absRoot, path)
|
||||||
|
if rerr != nil || rel == "." {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if filter.IsSymlink(path) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
depth := strings.Count(rel, string(filepath.Separator)) + 1
|
||||||
|
if depth > cfg.MaxDepth {
|
||||||
|
node := addPath(root, rel, d.IsDir())
|
||||||
|
node.Annotation = "exceeded --max-depth"
|
||||||
|
if d.IsDir() {
|
||||||
|
return filepath.SkipDir
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
name := filepath.Base(path)
|
||||||
|
|
||||||
|
if d.IsDir() {
|
||||||
|
if isIgnoredName(name, cfg.Ignores) {
|
||||||
|
node := addPath(root, rel, true)
|
||||||
|
node.Annotation = "ignored (--ignore)"
|
||||||
|
return filepath.SkipDir
|
||||||
|
}
|
||||||
|
if cfg.OmitTest && isTestDir(rel) {
|
||||||
|
node := addPath(root, rel, true)
|
||||||
|
node.Annotation = "tests omitted (--omit-test)"
|
||||||
|
return filepath.SkipDir
|
||||||
|
}
|
||||||
|
addPath(root, rel, true)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if annotation, ok := fileAnnotation(rel, name, cfg); ok {
|
||||||
|
node := addPath(root, rel, false)
|
||||||
|
node.Annotation = annotation
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
addPath(root, rel, false)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot walk %s: %w", absRoot, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return root, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isIgnoredName(name string, ignores []string) bool {
|
||||||
|
if strings.HasPrefix(name, ".") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, pattern := range ignores {
|
||||||
|
if matched, _ := filepath.Match(pattern, name); matched {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func isTestDir(rel string) bool {
|
||||||
|
slashPath := filepath.ToSlash(rel)
|
||||||
|
return strings.Contains(slashPath, "/tests/") || strings.HasPrefix(slashPath, "tests/")
|
||||||
|
}
|
||||||
|
|
||||||
|
func fileAnnotation(rel, name string, cfg *config.Config) (string, bool) {
|
||||||
|
if strings.HasPrefix(name, ".") {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
for _, pattern := range cfg.Ignores {
|
||||||
|
if matched, _ := filepath.Match(pattern, name); matched {
|
||||||
|
return "ignored (--ignore)", true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if cfg.OmitTest && isTestFileName(rel, name) {
|
||||||
|
return "tests omitted (--omit-test)", true
|
||||||
|
}
|
||||||
|
if cfg.OmitMd && isNonReadmeMarkdown(name) {
|
||||||
|
return "omitted (--omit-md)", true
|
||||||
|
}
|
||||||
|
if cfg.FrontendOnly && !isFrontendOrReadme(rel, name) {
|
||||||
|
return "omitted (--frontend-only)", true
|
||||||
|
}
|
||||||
|
if cfg.SkipFrontend && isFrontendExt(rel) {
|
||||||
|
return "omitted (--skip-frontend)", true
|
||||||
|
}
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
func isTestFileName(rel, name string) bool {
|
||||||
|
ext := strings.ToLower(filepath.Ext(name))
|
||||||
|
switch ext {
|
||||||
|
case ".go":
|
||||||
|
return strings.HasSuffix(strings.ToLower(name), "_test.go")
|
||||||
|
case ".java":
|
||||||
|
base := strings.TrimSuffix(name, filepath.Ext(name))
|
||||||
|
if strings.HasSuffix(base, "Test") || strings.HasSuffix(base, "Tests") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
slashPath := filepath.ToSlash(rel)
|
||||||
|
return strings.Contains(slashPath, "/src/test/")
|
||||||
|
case ".py":
|
||||||
|
lower := strings.ToLower(name)
|
||||||
|
if strings.HasPrefix(lower, "test_") || strings.HasSuffix(lower, "_test.py") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if strings.EqualFold(name, "conftest.py") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return isTestDir(rel)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func isNonReadmeMarkdown(name string) bool {
|
||||||
|
ext := strings.ToLower(filepath.Ext(name))
|
||||||
|
if ext != ".md" && ext != ".markdown" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return !strings.EqualFold(name, "README.md")
|
||||||
|
}
|
||||||
|
|
||||||
|
func isFrontendOrReadme(rel, name string) bool {
|
||||||
|
if isFrontendExt(rel) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return strings.EqualFold(name, "README.md")
|
||||||
|
}
|
||||||
|
|
||||||
|
func isFrontendExt(rel string) bool {
|
||||||
|
ext := strings.ToLower(filepath.Ext(rel))
|
||||||
|
for _, fe := range frontendExts {
|
||||||
|
if strings.EqualFold(ext, fe) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var frontendExts = []string{
|
||||||
|
".html", ".htm", ".gohtml", ".tmpl",
|
||||||
|
".css", ".scss", ".sass", ".less",
|
||||||
|
".js", ".jsx", ".mjs", ".cjs",
|
||||||
|
".ts", ".tsx",
|
||||||
|
".vue", ".svelte",
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@ type Result struct {
|
|||||||
AbsRoot string
|
AbsRoot string
|
||||||
SingleFile bool
|
SingleFile bool
|
||||||
OmitTest bool
|
OmitTest bool
|
||||||
|
Cfg *config.Config
|
||||||
Commit *git.CommitInfo
|
Commit *git.CommitInfo
|
||||||
Instructions string
|
Instructions string
|
||||||
}
|
}
|
||||||
@@ -67,7 +68,7 @@ func processSingleFile(cfg *config.Config) (*Result, error) {
|
|||||||
Entries: []Entry{{RelPath: filepath.Base(cfg.AbsRoot), Size: info.Size()}},
|
Entries: []Entry{{RelPath: filepath.Base(cfg.AbsRoot), Size: info.Size()}},
|
||||||
AbsRoot: filepath.Dir(cfg.AbsRoot),
|
AbsRoot: filepath.Dir(cfg.AbsRoot),
|
||||||
SingleFile: true,
|
SingleFile: true,
|
||||||
OmitTest: cfg.OmitTest,
|
Cfg: cfg,
|
||||||
Commit: commitInfo,
|
Commit: commitInfo,
|
||||||
Instructions: instContent,
|
Instructions: instContent,
|
||||||
}, nil
|
}, nil
|
||||||
@@ -83,7 +84,7 @@ func walkDirectory(cfg *config.Config) (*Result, error) {
|
|||||||
OmitMd: cfg.OmitMd,
|
OmitMd: cfg.OmitMd,
|
||||||
}
|
}
|
||||||
|
|
||||||
result := &Result{AbsRoot: cfg.AbsRoot, OmitTest: cfg.OmitTest}
|
result := &Result{AbsRoot: cfg.AbsRoot, Cfg: cfg, OmitTest: cfg.OmitTest}
|
||||||
|
|
||||||
result.Commit = git.GetCommitInfo(cfg.AbsRoot)
|
result.Commit = git.GetCommitInfo(cfg.AbsRoot)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user