88 tool_name = os.file_name (os.executable ())
99 tool_version = '0.0.3'
1010 tool_description = 'Prints all V functions in .v files under PATH/, that do not yet have documentation comments.'
11+ work_dir_prefix = normalise_path (os.real_path (os.wd_at_startup) + '/' )
1112)
1213
1314struct UndocumentedFN {
@@ -23,44 +24,34 @@ struct Options {
2324 private bool
2425 js bool
2526 no_line_numbers bool
27+ exclude []string
28+ relative_paths bool
2629}
2730
28- fn collect (path string , mut l []string , f fn (string , mut []string )) {
29- if ! os.is_dir (path) {
30- return
31- }
32- mut files := os.ls (path) or { return }
33- for file in files {
34- p := path + os.path_separator + file
35- if os.is_dir (p) && ! os.is_link (p) {
36- collect (p, mut l, f)
37- } else if os.exists (p) {
38- f (p, mut l)
39- }
40- }
41- return
42- }
43-
44- fn report_undocumented_functions_in_path (opt Options, path string ) {
31+ fn (opt Options) report_undocumented_functions_in_path (path string ) {
4532 mut files := []string {}
46- collect_fn := fn (path string , mut l []string ) {
47- if os. file_ext (path) == '.v' {
48- l << os. real_path (path)
33+ collect (path, mut files, fn (npath string , mut accumulated_paths []string ) {
34+ if ! npath. ends_with ( '.v' ) {
35+ return
4936 }
50- }
51- collect (path, mut files, collect_fn)
37+ if npath.ends_with ('_test.v' ) {
38+ return
39+ }
40+ accumulated_paths << npath
41+ })
5242 for file in files {
53- if file.ends_with ('_test .v' ) {
43+ if ! opt.js && file.ends_with ('.js .v' ) {
5444 continue
5545 }
56- if ! opt.js && file. ends_with ( '.js.v' ) {
46+ if opt.exclude.len > 0 && opt.exclude. any (file. contains ( it ) ) {
5747 continue
5848 }
59- report_undocumented_functions_in_file (opt, file)
49+ opt. report_undocumented_functions_in_file (file)
6050 }
6151}
6252
63- fn report_undocumented_functions_in_file (opt Options, file string ) {
53+ fn (opt &Options) report_undocumented_functions_in_file (nfile string ) {
54+ file := os.real_path (nfile)
6455 contents := os.read_file (file) or { panic (err) }
6556 lines := contents.split ('\n ' )
6657 mut info := []UndocumentedFN{}
@@ -104,17 +95,42 @@ fn report_undocumented_functions_in_file(opt Options, file string) {
10495 } else {
10596 ''
10697 }
98+ ofile := if opt.relative_paths {
99+ nfile.replace (work_dir_prefix, '' )
100+ } else {
101+ os.real_path (nfile)
102+ }
107103 if opt.deprecated {
108- println ('$file :$line_numbers$undocumented_fn.signature $tags_str ' )
104+ println ('$ofile :$line_numbers$undocumented_fn.signature $tags_str ' )
109105 } else {
110106 if 'deprecated' ! in undocumented_fn.tags {
111- println ('$file :$line_numbers$undocumented_fn.signature $tags_str ' )
107+ println ('$ofile :$line_numbers$undocumented_fn.signature $tags_str ' )
112108 }
113109 }
114110 }
115111 }
116112}
117113
114+ fn normalise_path (path string ) string {
115+ return path.replace ('\\ ' , '/' )
116+ }
117+
118+ fn collect (path string , mut l []string , f fn (string , mut []string )) {
119+ if ! os.is_dir (path) {
120+ return
121+ }
122+ mut files := os.ls (path) or { return }
123+ for file in files {
124+ p := normalise_path (os.join_path_single (path, file))
125+ if os.is_dir (p) && ! os.is_link (p) {
126+ collect (p, mut l, f)
127+ } else if os.exists (p) {
128+ f (p, mut l)
129+ }
130+ }
131+ return
132+ }
133+
118134fn collect_tags (line string ) []string {
119135 mut cleaned := line.all_before ('/' )
120136 cleaned = cleaned.replace_each (['[' , '' , ']' , '' , ' ' , '' ])
@@ -137,18 +153,21 @@ fn main() {
137153 deprecated: fp.bool ('deprecated' , `d` , false , 'Include deprecated functions in output.' )
138154 private: fp.bool ('private' , `p` , false , 'Include private functions in output.' )
139155 js: fp.bool ('js' , 0 , false , 'Include JavaScript functions in output.' )
140- no_line_numbers: fp.bool ('no-line-numbers' , 0 , false , 'Exclude line numbers in output.' )
156+ no_line_numbers: fp.bool ('no-line-numbers' , `n` , false , 'Exclude line numbers in output.' )
141157 collect_tags: fp.bool ('tags' , `t` , false , 'Also print function tags if any is found.' )
158+ exclude: fp.string_multi ('exclude' , `e` , '' )
159+ relative_paths: fp.bool ('relative-paths' , `r` , false , 'Use relative paths in output.' )
142160 }
161+ dump (opt)
143162 if opt.show_help {
144163 println (fp.usage ())
145164 exit (0 )
146165 }
147166 for path in os.args[1 ..] {
148167 if os.is_file (path) {
149- report_undocumented_functions_in_file (opt, path)
168+ opt. report_undocumented_functions_in_file (path)
150169 } else {
151- report_undocumented_functions_in_path (opt, path)
170+ opt. report_undocumented_functions_in_path (path)
152171 }
153172 }
154173}
0 commit comments