Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vdoc: improve vdocignore file handling by walking all .vdocignore sub-paths in IgnoreRules.get, add test #21521

Merged
merged 2 commits into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 38 additions & 26 deletions cmd/tools/vdoc/files.v
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,18 @@ mut:
}

fn get_modules(path string) []string {
mut ignore_rules := IgnoreRules{}
mut modules := map[string]bool{}
for p in get_paths(path, mut ignore_rules) {
for p in get_paths(path, IgnoreRules.get(path)) {
modules[os.dir(p)] = true
}
mut res := modules.keys()
res.sort()
return res
}

fn get_paths(path string, mut ignore_rules IgnoreRules) []string {
fn get_paths(path string, ignore_rules IgnoreRules) []string {
mut res := []string{}
outer: for p in os.ls(path) or { return [] } {
ignore_rules.get(path)
fp := os.join_path(path, p)
if fp in ignore_rules.paths {
continue
Expand All @@ -45,7 +43,7 @@ fn get_paths(path string, mut ignore_rules IgnoreRules) []string {
}
}
if is_dir {
res << get_paths(fp, mut ignore_rules)
res << get_paths(fp, ignore_rules)
continue
}
if p.ends_with('.v') {
Expand All @@ -55,30 +53,44 @@ fn get_paths(path string, mut ignore_rules IgnoreRules) []string {
return res
}

fn (mut ignore_rules IgnoreRules) get(path string) {
ignore_content := os.read_file(os.join_path(path, '.vdocignore')) or { return }
if ignore_content.trim_space() == '' {
return
}
rules := ignore_content.split_into_lines().map(it.trim_space())
for rule in rules {
if rule.starts_with('#') {
continue
fn IgnoreRules.get(path string) IgnoreRules {
mut res := IgnoreRules{}
mut vdocignore_paths := []string{}
mut vdocignore_paths_ref := &vdocignore_paths
os.walk(path, fn [vdocignore_paths_ref] (p string) {
if os.file_name(p) == '.vdocignore' {
unsafe {
vdocignore_paths_ref << p
}
}
if rule.contains('*.') || rule.contains('**') {
// Skip wildcards that are defined in an ignore file.
// For now, only add a basic implementation in `get_paths`
// that can handle the default `*_test.v` pattern.
eprintln('vdoc: Wildcards in ignore rules are not yet supported.')
})
for ignore_path in vdocignore_paths {
ignore_content := os.read_file(ignore_path) or { continue }
if ignore_content.trim_space() == '' {
continue
}
if rule.starts_with('/') {
// Similar to `.gitignore`, a pattern starting with `/` should only ignore
// the pattern relative to the directory of the `.vdocignore` file.
// `/a` should ignore `/a` but not `/b/a`. While `a` should ignore `/a` and `/b/a`.
ignore_rules.paths[os.join_path(path, rule.trim_left('/'))] = true
} else {
ignore_rules.patterns[path] << rule
rules := ignore_content.split_into_lines().map(it.trim_space())
for rule in rules {
if rule.starts_with('#') {
continue
}
if rule.contains('*.') || rule.contains('**') {
// Skip wildcards that are defined in an ignore file.
// For now, only add a basic implementation in `get_paths`
// that can handle the default `*_test.v` pattern.
eprintln('vdoc: Wildcards in ignore rules are not yet supported.')
continue
}
p := os.dir(ignore_path)
if rule.starts_with('/') {
// Similar to `.gitignore`, a pattern starting with `/` should only ignore
// the pattern relative to the directory of the `.vdocignore` file.
// `/a` should ignore `/a` but not `/b/a`. While `a` should ignore `/a` and `/b/a`.
res.paths[os.join_path(p, rule.trim_left('/'))] = true
} else {
res.patterns[p] << rule
}
}
}
return res
}
32 changes: 23 additions & 9 deletions cmd/tools/vdoc/vdoc_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@ module main
import os
import arrays

const tpath = os.join_path(os.vtmp_dir(), 'vod_test_module')

fn testsuite_begin() {
os.rmdir_all(tpath) or {}
os.mkdir_all(tpath)!
os.chdir(tpath)!
}


fn testsuite_end() {
os.rmdir_all(tpath) or {}
}

fn test_trim_doc_node_description() {
mod := 'foo'
mut readme := '## Description
Expand All @@ -20,16 +33,17 @@ It also assists with composing and testing baz.'
assert res2 == res
}

fn test_get_module_list() {
tpath := os.join_path(os.vtmp_dir(), 'vod_test_module')
os.rmdir_all(tpath) or {}
os.mkdir_all(tpath)!
defer {
os.rmdir_all(tpath) or {}
}

os.chdir(tpath)!
fn test_ignore_rules() {
os.write_file('.vdocignore', ['pattern1', 'pattern2', '/path1'].join_lines())!
os.mkdir('subdir')!
os.write_file(os.join_path('subdir', '.vdocignore'), ['pattern3', '/path2'].join_lines())!
rules := IgnoreRules.get('.')
assert rules.patterns['.'] == ['pattern1', 'pattern2']
assert rules.patterns['./subdir'] == ['pattern3']
assert rules.paths == {'./path1': true, './subdir/path2': true}
}

fn test_get_module_list() {
// For information on leading slash rules, refer to the comments in `IgnoreRules.get`.
ignore_rules := ['bravo', '/echo', '/foxtrot/golf', 'hotel.v/', 'india/juliett']
os.write_file('.vdocignore', ignore_rules.join_lines())!
Expand Down