11package dirs
22
33import (
4+ "bufio"
45 "fmt"
56 "log"
67 "os"
@@ -37,11 +38,11 @@ func crawlUpAndFindDirOf(startDir string, files ...string) (string, error) {
3738 return "" , nil
3839}
3940
40- // FindPkgsWithFile is finding packages containing file on disk starting at
41- // 'root' and adding them to those given in 'startPkgs'.
42- func FindPkgsWithFile (file string , startPkgs []string , root string , excludeRoot bool ) map [string ]struct {} {
41+ // FindDepTables is finding packages containing a dependency table on disk
42+ // starting at 'root' and adding them to those given in 'startPkgs'.
43+ func FindDepTables (file , title string , startPkgs []string , root , rootPkg string ) map [string ]struct {} {
4344 val := struct {}{}
44- // prefill doc packages from dtPkgs
45+ // prefill doc packages from startPkgs
4546 retPkgs := make (map [string ]struct {}, 128 )
4647 for _ , p := range startPkgs {
4748 retPkgs [p ] = val
@@ -56,26 +57,31 @@ func FindPkgsWithFile(file string, startPkgs []string, root string, excludeRoot
5657 log .Printf ("WARN - Unable to list directory %q: %v" , path , err )
5758 return filepath .SkipDir
5859 }
59- if excludeRoot && path == root {
60- return nil // don't add the root 'file'
61- }
6260
63- // no valid package starts with '.' and we don't want to search in '.git' and similar
61+ // no valid package starts with '.' and we don't want to search in testdata
6462 if strings .HasPrefix (info .Name (), "." ) || info .Name () == "testdata" {
6563 return filepath .SkipDir
6664 }
6765
68- if _ , err := os .Lstat (filepath .Join (path , file )); err == nil {
66+ depFile := filepath .Join (path , file )
67+ if _ , err := os .Lstat (depFile ); err == nil {
6968 pkg , err := filepath .Rel (root , path )
7069 if err != nil {
7170 log .Printf ("WARN - Unable to compute package for %q: %v" , path , err )
7271 return nil // sub-directories might work
7372 }
74- pkg = strings .ReplaceAll (pkg , "\\ " , "/" ) // packages like URLs have always '/'s
75- if pkg == "." {
73+ pattern , err := readPatternFromFile (depFile , title , rootPkg )
74+ if err != nil {
75+ log .Printf ("WARN - Problem reading pattern from file %q: %v" , depFile , err )
76+ err = nil
77+ }
78+ if pattern == "" {
79+ pattern = strings .ReplaceAll (pkg , "\\ " , "/" ) // packages like URLs have always '/'s
80+ }
81+ if pattern == "." {
7682 retPkgs ["/" ] = val
7783 } else {
78- retPkgs [pkg ] = val
84+ retPkgs [pattern ] = val
7985 }
8086 }
8187 return nil
@@ -85,3 +91,43 @@ func FindPkgsWithFile(file string, startPkgs []string, root string, excludeRoot
8591 }
8692 return retPkgs
8793}
94+
95+ func readPatternFromFile (depFile , prefix , rootPkg string ) (string , error ) {
96+ lines , err := readFirstLines (depFile , 5 )
97+ prefix = strings .ToLower (prefix )
98+ for _ , l := range lines {
99+ if strings .HasPrefix (strings .ToLower (l ), prefix ) {
100+ pattern := l [len (prefix ):]
101+ pattern = strings .TrimSpace (pattern )
102+ if strings .HasPrefix (rootPkg , pattern ) {
103+ pattern = pattern [len (rootPkg ):]
104+ if pattern != "" && pattern [0 ] == '/' {
105+ pattern = pattern [1 :]
106+ }
107+ if pattern == "" {
108+ pattern = "/"
109+ }
110+ }
111+ return pattern , err
112+ }
113+ }
114+ return "" , err
115+ }
116+
117+ func readFirstLines (fileName string , n int ) ([]string , error ) {
118+ file , err := os .Open (fileName )
119+ if err != nil {
120+ return nil , err
121+ }
122+ defer file .Close ()
123+
124+ lines := make ([]string , 0 , n )
125+ scanner := bufio .NewScanner (file )
126+ for i := 0 ; i < n && scanner .Scan (); i ++ {
127+ lines = append (lines , scanner .Text ())
128+ }
129+ if err := scanner .Err (); err != nil {
130+ return lines , err
131+ }
132+ return lines , nil
133+ }
0 commit comments