Skip to content
Open
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
28 changes: 17 additions & 11 deletions script/schema_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
JSON_CV_TYPE_SCHEMA = "schema"
JSON_ACTION = "action"

DOCS_ROOT = Path(".") / "src" / "content" / "docs"

Comment on lines +29 to +30
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

URL generation in SeeAlso.md() and convert_links_and_shortcodes is broken by the new path depth.

DOCS_ROOT now resolves to PosixPath("src/content/docs") (3 parts), so doc files have paths like src/content/docs/components/sensor.mdx with parts ('src', 'content', 'docs', 'components', 'sensor.mdx').

Both SeeAlso.md() (line 75) and convert_links_and_shortcodes (line 452) use the hardcoded parts[1:-1] slice, which was designed for a 1-level prefix (content/):

Structure parts[1:-1] Generated URL
Old: content/components/sensor.md ('components',) /components/sensor
New: src/content/docs/components/sensor.mdx ('content', 'docs', 'components') /content/docs/components/sensor

This will cause all "See also" links and relative docref shortcode URLs written into the schema JSON to be incorrect. Fix by making the URL slice relative to DOCS_ROOT:

🐛 Proposed fix — derive URL relative to `DOCS_ROOT`

Apply to SeeAlso.md() (line 75):

 def md(self):
-    url_path = "/" + "/".join(list(self.file.parts[1:-1]))
-    if self.file.stem != "_index":
-        url_path += f"/{self.file.stem}"
+    relative = self.file.relative_to(DOCS_ROOT)
+    url_path = "/" + "/".join(relative.parts[:-1])
+    if self.file.stem not in ("_index", "index"):
+        url_path += f"/{self.file.stem}"

Apply to convert_links_and_shortcodes (line 452):

-    url = args.deploy_url + "/" + "/".join(md_file.parts[1:-1]) + "/" + ref
+    url = args.deploy_url + "/" + "/".join(md_file.relative_to(DOCS_ROOT).parts[:-1]) + "/" + ref
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@script/schema_doc.py` around lines 29 - 30, SeeAlso.md() and
convert_links_and_shortcodes are building URLs by slicing path.parts[1:-1],
which breaks when DOCS_ROOT has extra path segments; change both to compute the
path relative to DOCS_ROOT (use Path.relative_to(DOCS_ROOT) or
Path.resolve().relative_to(DOCS_ROOT.resolve())) and build the URL from that
relative path's parts (remove the file suffix and join remaining parts with
'/'), replacing the hardcoded parts[1:-1] logic so generated URLs are relative
to DOCS_ROOT regardless of its depth.

args = None


Expand Down Expand Up @@ -395,20 +397,20 @@ def encode_doxygen(value):
def get_md_file_ref(md_file, ref):
# This should mimic the docref short code, see /themes/esphome-theme/layouts/shortcodes/docref.html
if ref.startswith("/"):
md_parent = Path(".") / "content"
md_parent = DOCS_ROOT
ref = ref[1:]
else:
md_parent = md_file.parent
if ref.endswith("/"):
ref = ref[:-1]

ref_md_path = md_parent / (ref + ".md")
ref_md_path = md_parent / (ref + ".mdx")
if ref_md_path.exists():
return ref_md_path
ref_md_default = md_parent / ref / "_index.md"
ref_md_default = md_parent / ref / "_index.mdx"
if ref_md_default.exists():
return ref_md_default
ref_md_default = Path(".") / "content" / "components" / (ref + ".md")
ref_md_default = DOCS_ROOT / "components" / (ref + ".mdx")
if ref_md_default.exists():
return ref_md_default
return md_file # go nowhere
Comment on lines +407 to 416
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check the actual MDX files in the docs structure
find src/content/docs -type f -name "*index.mdx" 2>/dev/null | head -30

Repository: esphome/esphome-docs

Length of output: 1439


🏁 Script executed:

# Check for _index.mdx files specifically
find src/content/docs -type f -name "_index.mdx" 2>/dev/null | head -30

Repository: esphome/esphome-docs

Length of output: 46


🏁 Script executed:

# Get context around lines 407-416, 765, and 787 in script/schema_doc.py
sed -n '400,420p' script/schema_doc.py

Repository: esphome/esphome-docs

Length of output: 662


🏁 Script executed:

# Check line 765 context
sed -n '760,770p' script/schema_doc.py

Repository: esphome/esphome-docs

Length of output: 449


🏁 Script executed:

# Check line 787 context
sed -n '780,795p' script/schema_doc.py

Repository: esphome/esphome-docs

Length of output: 827


🏁 Script executed:

# Search for where file_name is assigned before line 787
sed -n '700,790p' script/schema_doc.py | grep -n "file_name"

Repository: esphome/esphome-docs

Length of output: 218


🏁 Script executed:

# Get broader context around the file processing loop
sed -n '680,810p' script/schema_doc.py

Repository: esphome/esphome-docs

Length of output: 4850


Update _index.mdx references to index.mdx — Hugo migration incomplete.

The codebase uses index.mdx for directory index files (confirmed across src/content/docs/), but the fallback lookup at line 410 still searches for _index.mdx, which no longer exists. Similarly, the guards at lines 787 and 797 check file_name == "_index", but file_name = md_file.stem will be index for actual files, so these conditions never match.

Update all three locations to use the index convention:

Proposed fixes

Line 410:

-    ref_md_default = md_parent / ref / "_index.mdx"
+    ref_md_default = md_parent / ref / "index.mdx"

Line 787:

-        if file_name == "_index" and content_folder == "components":
+        if file_name == "index" and content_folder == "components":

Line 797:

-            if file_name == "_index":
+            if file_name == "index":
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ref_md_path = md_parent / (ref + ".mdx")
if ref_md_path.exists():
return ref_md_path
ref_md_default = md_parent / ref / "_index.md"
ref_md_default = md_parent / ref / "_index.mdx"
if ref_md_default.exists():
return ref_md_default
ref_md_default = Path(".") / "content" / "components" / (ref + ".md")
ref_md_default = DOCS_ROOT / "components" / (ref + ".mdx")
if ref_md_default.exists():
return ref_md_default
return md_file # go nowhere
ref_md_path = md_parent / (ref + ".mdx")
if ref_md_path.exists():
return ref_md_path
ref_md_default = md_parent / ref / "index.mdx"
if ref_md_default.exists():
return ref_md_default
ref_md_default = DOCS_ROOT / "components" / (ref + ".mdx")
if ref_md_default.exists():
return ref_md_default
return md_file # go nowhere
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@script/schema_doc.py` around lines 407 - 416, The fallback lookup currently
checks for "_index.mdx" and the guards compare file_name == "_index", but the
repo uses "index.mdx" so these branches never match; update the fallback in the
ref resolution (variable ref_md_default) to look for ref / "index.mdx" (and the
DOCS_ROOT components fallback to (ref + ".mdx") remains), and change the guards
that compare file_name == "_index" to compare file_name == "index" (search for
uses of md_file.stem and the variables file_name around the checks at the two
locations) so directory index pages are detected correctly.

Expand Down Expand Up @@ -745,22 +747,22 @@ def oddities_titles(folder, file, title):
core = esphome_json["core"]

md_files = []
for root, _, files in os.walk(Path(".") / "content" / "components"):
for root, _, files in os.walk(DOCS_ROOT / "components"):
for file in files:
if file.endswith(".md"):
if file.endswith(".mdx"):
fullpath = Path(root, file)
md_files.append(fullpath)
md_files.append(Path(".") / "content" / "automations" / "actions.md")
md_files.append(DOCS_ROOT / "automations" / "actions.mdx")

fill_anchors(
md_files
+ [
# config-lambda, config-templatable
Path(".") / "content" / "automations" / "templates.md",
DOCS_ROOT / "automations" / "templates.mdx",
# config-id, config-pin_schema
Path(".") / "content" / "guides" / "configuration-types.md",
DOCS_ROOT / "guides" / "configuration-types.mdx",
# api-rest
Path(".") / "content" / "web-api" / "_index.md",
DOCS_ROOT / "web-api" / "index.mdx",
]
)

Expand Down Expand Up @@ -953,10 +955,14 @@ def oddities_titles(folder, file, title):
schema = json_config[config_component]["schemas"].get(
f"{platform_name.upper()}_SCHEMA"
)
else:
elif platform_name:
schema = json_config[f"{config_component}.{platform_name}"][
"schemas"
].get("CONFIG_SCHEMA")
else:
print(
f"{md_file}:{index} {config_component} unknown component type"
)
else:
schema = None
if schema:
Expand Down