Skip to content

Commit 79d034b

Browse files
committed
add verbose parameter to script to improve logging
1 parent 1c3efc9 commit 79d034b

File tree

4 files changed

+122
-298
lines changed

4 files changed

+122
-298
lines changed

plugins/checkFloatingPages.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
const { promisify } = require('util');
4+
const glob = promisify(require('glob'));
5+
const matter = require('gray-matter');
6+
7+
async function checkFloatingPages(context, options) {
8+
return {
9+
name: 'check-floating-pages',
10+
11+
async postBuild({ siteConfig, routesPaths, outDir, head }) {
12+
const { baseUrl } = siteConfig;
13+
const docsDir = path.resolve(context.siteDir, 'docs');
14+
15+
let sidebarItems = [];
16+
const sidebarsPath = path.join(context.siteDir, 'sidebars.js');
17+
if (fs.existsSync(sidebarsPath)) {
18+
try {
19+
const sidebars = require(sidebarsPath);
20+
sidebarItems = getSidebarItems(sidebars);
21+
} catch (err) {
22+
console.error("Error loading sidebars.js", err);
23+
throw err; // Stop the build
24+
}
25+
}
26+
27+
const markdownFiles = await glob(path.join(docsDir, '**/*.md'));
28+
const floatingPages = [];
29+
30+
for (const filePath of markdownFiles) {
31+
const fileContent = fs.readFileSync(filePath, 'utf-8');
32+
const { data } = matter(fileContent);
33+
34+
const relativePath = path.relative(docsDir, filePath).replace(/\\/g, '/').replace(/\.md$/, '');
35+
36+
// Check 1: Explicit sidebar_position or id in frontmatter
37+
if (data.sidebar_position || data.id) {
38+
const idToCheck = data.id || relativePath;
39+
if (!sidebarItems.includes(idToCheck)) {
40+
floatingPages.push(filePath);
41+
}
42+
} else {
43+
//Check 2: Implicit.
44+
if (!sidebarItems.includes(relativePath)) {
45+
floatingPages.push(filePath);
46+
}
47+
}
48+
}
49+
50+
if (floatingPages.length > 0) {
51+
console.error('\x1b[31m%s\x1b[0m', 'Floating pages found:');
52+
floatingPages.forEach(page => console.error(` - ${page}`));
53+
if (options && options.failBuild) {
54+
throw new Error('Floating pages found. See above for details.');
55+
}
56+
} else {
57+
console.log('\x1b[32m%s\x1b[0m', 'No floating pages found.');
58+
}
59+
}
60+
}
61+
}
62+
63+
function getSidebarItems(sidebarConfig) {
64+
let items = []
65+
function traverse(item) {
66+
if (item.type === 'doc') {
67+
items.push(item.id);
68+
} else if (item.type === 'category' || item.type === 'autogenerated') {
69+
(item.items || []).forEach(traverse);
70+
} else if (item.type === 'link') {
71+
// no need to worry about links
72+
}
73+
}
74+
// sidebarConfig can be an array or an object
75+
if (Array.isArray(sidebarConfig)) {
76+
sidebarConfig.forEach(traverse);
77+
} else {
78+
Object.values(sidebarConfig).forEach(sidebar => {
79+
sidebar.forEach(traverse)
80+
})
81+
}
82+
return items;
83+
}
84+
85+
module.exports = checkFloatingPages;

scripts/table-of-contents-generator/toc_gen.py

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,19 @@ def parse_args() -> argparse.Namespace:
3939
)
4040
parser.add_argument('--ignore', metavar='S', type=str, nargs='+',
4141
help='Directory names to ignore. E.g --ignore _snippets images')
42+
parser.add_argument(
43+
"--verbose",
44+
action="store_true",
45+
help="Enable verbose logging"
46+
)
4247
return parser.parse_args()
4348

44-
def extract_title_description_slug(filename):
49+
def log(message, verbose=False):
50+
"""Print message only if verbose mode is enabled"""
51+
if verbose:
52+
print(message)
53+
54+
def extract_title_description_slug(filename, verbose=False):
4555
data = defaultdict(str)
4656
missing_fields = []
4757
frontmatter_data = {}
@@ -63,29 +73,30 @@ def extract_title_description_slug(filename):
6373

6474
data.update(frontmatter_data)
6575

66-
if missing_fields:
67-
print(f"Warning: {filename} is missing some fields:")
76+
if missing_fields and verbose:
77+
log(f"Warning: {filename} is missing some fields:", verbose)
6878
for field in missing_fields:
69-
print(f"- {field}")
79+
log(f"- {field}", verbose)
7080

7181
return frontmatter_data
7282
except OSError as e:
73-
print(f"Ran into a problem reading frontmatter: {e}")
83+
log(f"Ran into a problem reading frontmatter: {e}", verbose)
7484
sys.exit(1)
75-
def walk_dirs(root_dir, ignore_dirs=[]):
85+
86+
def walk_dirs(root_dir, ignore_dirs=[], verbose=False):
7687
for root, dirs, files in os.walk(root_dir):
7788
# Modify the 'dirs' list in-place to remove ignored directories
7889
if (ignore_dirs is not None):
7990
dirs[:] = [d for d in dirs if d not in ignore_dirs
80-
and not any(d.startswith(ig) for ig in ignore_dirs)]
91+
and not any(d.startswith(ig) for ig in ignore_dirs)]
8192
yield root
8293

83-
def write_md_to_file(json_items, path_to_md_file):
94+
def write_md_to_file(json_items, path_to_md_file, verbose=False):
8495
try:
8596
with open(path_to_md_file, encoding='utf-8') as pre_check:
8697
existing_content = pre_check.read()
8798
if "| Page | Description |" in existing_content:
88-
print(f"Markdown table already exists in {path_to_md_file}. Skipping.")
99+
log(f"Markdown table already exists in {path_to_md_file}. Skipping.", verbose)
89100
return
90101

91102
with open(path_to_md_file, 'a', encoding='utf-8') as f:
@@ -100,12 +111,12 @@ def write_md_to_file(json_items, path_to_md_file):
100111
link = f"[{title}]({slug})" if slug else title
101112
f.write(f"| {link} | {description} |\n")
102113

103-
print(f"Markdown table appended to {path_to_md_file}")
114+
log(f"Markdown table appended to {path_to_md_file}", verbose)
104115

105116
except Exception as e:
106-
print(f"An error occurred: {e}")
107-
def write_to_file(json_items, directory, output=None):
117+
log(f"An error occurred: {e}", verbose)
108118

119+
def write_to_file(json_items, directory, output=None, verbose=False):
109120
if output is not None:
110121
# output to the given path the toc.json file
111122
# If dir='docs/en/interfaces/formats' the file is called docs_en_interfaces_formats_toc.json
@@ -117,20 +128,21 @@ def write_to_file(json_items, directory, output=None):
117128
with open(output_path, "w") as f:
118129
json.dump(json_items, f, indent=4, default=str)
119130
f.write('\n')
120-
print(f"Wrote {output_path}")
131+
log(f"Wrote {output_path}", verbose)
121132
except OSError as e:
122133
if e.errno == 21:
123-
print(f"Directory already exists: {e}")
134+
log(f"Directory already exists: {e}", verbose)
124135
elif e.errno != 17:
125-
print(f"An error occurred creating directory: {e}")
136+
log(f"An error occurred creating directory: {e}", verbose)
137+
126138
def write_file(json_items, args, directory):
127-
print(args)
128139
if (args.out is not None) and (args.md is None):
129-
write_to_file(json_items, directory+"/toc.json", args.out)
140+
write_to_file(json_items, directory+"/toc.json", args.out, args.verbose)
130141
elif (args.out is None) and (args.md is None):
131-
write_to_file(json_items, directory+"/toc.json")
142+
write_to_file(json_items, directory+"/toc.json", verbose=args.verbose)
132143
elif (args.out is None) and (args.md is not None):
133-
write_md_to_file(json_items, args.md)
144+
write_md_to_file(json_items, args.md, args.verbose)
145+
134146
def sort_by_title_before_underscore(json_items):
135147
def sort_key(item):
136148
title = item.get("title", "")
@@ -142,21 +154,19 @@ def sort_key(item):
142154
return sorted(json_items, key=sort_key)
143155

144156
def main():
145-
146157
# Extract script arguments
147158
args = parse_args()
148159
root_dir = args.dir
149160
if root_dir is None:
150-
print("Please provide a directory with argument --dir")
161+
log("Please provide a directory with argument --dir", True) # Always show critical errors
151162
sys.exit(1)
152163
if os.path.lexists(root_dir) is False:
153-
print("Path provided does not exist")
164+
log("Path provided does not exist", True) # Always show critical errors
154165
sys.exit(1)
155166
if args.single_toc is True:
156167
json_items = [] # single list for all directories
157168

158-
for directory in walk_dirs(root_dir, args.ignore): # Walk directories
159-
169+
for directory in walk_dirs(root_dir, args.ignore, args.verbose): # Walk directories
160170
if args.single_toc is False:
161171
json_items = [] # new list for each directory
162172

@@ -167,7 +177,7 @@ def main():
167177
else:
168178
# index.md is ignored as we expect this to be the page for the table of contents
169179
if (filename.endswith(".md") or filename.endswith(".mdx")) and filename != "index.md":
170-
result = extract_title_description_slug(full_path)
180+
result = extract_title_description_slug(full_path, args.verbose)
171181
if result is not None:
172182
json_items.append(result)
173183
if args.single_toc is False:
@@ -177,7 +187,7 @@ def main():
177187
# output to the specified directory if arg --out is provided
178188
write_file(json_items, args, directory)
179189
else:
180-
print("Ran into an issue trying to extract YAML: empty result")
190+
log("Ran into an issue trying to extract YAML: empty result", args.verbose)
181191

182192
if args.single_toc is True:
183193
# don't write toc.json for empty folders
@@ -190,5 +200,4 @@ def main():
190200
sys.exit(1)
191201

192202
if __name__ == "__main__":
193-
main()
194-
203+
main()

0 commit comments

Comments
 (0)