Skip to content

Commit f67bdfa

Browse files
jacobstrclaude
andcommitted
Document alias collision limitation and add context
- Added test documenting potential alias collision scenario when site_name matches generated alias pattern (site_name-SectionName) - Updated limitations.md with clear example and workaround - Created claude.md to preserve original prompts and design context 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 4206d62 commit f67bdfa

3 files changed

Lines changed: 157 additions & 0 deletions

File tree

claude.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Development Context
2+
3+
This file captures the original prompts and context that motivated the changes to this fork of mkdocs-monorepo-plugin.
4+
5+
## Original Problem Statement
6+
7+
The user wanted to reorganize documentation navigation in a monorepo setup. Specifically:
8+
9+
1. **Initial Request**: Reorganize guides to highlight "Running Applications in Kubernetes" at the top level
10+
- Original prompt: "I believe the guides Certificate Management with cert-manager, Using Public IPs for Egress Traffic, Configuring GitLab Datasource Access need to be organized, these are like individual topics. I would like to highlight at the top level Running Applications in Kubernetes"
11+
12+
2. **Navigation Structure Goals**:
13+
- Surface TigerCLI guides prominently (currently under "Others → TigerCLI → Guides")
14+
- Categorize other guides under thematic sections (Security, Cost Management, Observability)
15+
- Avoid duplicating the entire TigerCLI navigation tree
16+
17+
3. **Technical Challenge**:
18+
- Original prompt: "Can we have multiple locations?" (regarding including TigerCLI in multiple places)
19+
- The existing mkdocs-monorepo-plugin didn't support including only a subset of a navigation tree
20+
- Using `!include` would either:
21+
- Include the entire navigation tree, or
22+
- Require manual duplication of content
23+
24+
4. **Solution Direction**:
25+
- Original prompt: "Can we make 'Kubernetes and TigerCLI' use the build-deploy/tigercli guide section of the tree? Like can I reference a heading inside of mkdocs?"
26+
- Fork mkdocs-monorepo-plugin to add anchor-based partial navigation inclusion
27+
- Implement syntax: `!include path/to/mkdocs.yml#SectionName`
28+
29+
## Design Decisions
30+
31+
### Alias Generation Strategy
32+
When an anchor is used, the alias is generated as `{site_name}-{SectionName}` to:
33+
- Ensure uniqueness from the full include
34+
- Allow the same mkdocs.yml to be included both fully and partially
35+
- Provide clear, predictable naming
36+
37+
### Known Limitations
38+
Original prompt: "The fragment syntax uses the alias name correct? It then generates a new alias. I suppose this could result in collisions and might make this potentially incompatible."
39+
40+
We documented this in `limitations.md`:
41+
- If `site_name` of one file matches the generated alias of another (`{SiteName}-{Section}`), a collision occurs
42+
- Build-time detection with clear error messages
43+
- Workaround: Avoid naming patterns that match generated aliases
44+
45+
### Testing Philosophy
46+
Original prompt: "Can we test / assert for an expected failure? How specific can we get? Let's use existing practices in the project if it already has some form of test harness, mocking etc."
47+
48+
- Used existing `unittest` framework
49+
- Added `test_alias_collision_detection()` to document and test the collision scenario
50+
- Followed existing pattern of `self.assertRaises(SystemExit)` for expected failures
51+
52+
## Final Navigation Structure
53+
54+
```yaml
55+
nav:
56+
- Components: "*include docs/vendor/build-deploy/planet-idp/components/*/mkdocs.yml"
57+
- Guides:
58+
- Deploying Applications: "!include docs/vendor/build-deploy/tigercli/mkdocs.yml#Guides"
59+
- Security:
60+
- Certificate Management with cert-manager: guide/certificate-management-with-cert-manager.md
61+
- Cost Management:
62+
- Using Public IPs for Egress Traffic: guide/using-public-ips-for-egress-traffic.md
63+
- Observability:
64+
- Configuring GitLab Datasource Access: guide/configuring-gitlab-datasource-access.md
65+
- Others:
66+
- TigerCLI: "!include docs/vendor/build-deploy/tigercli/mkdocs.yml"
67+
```
68+
69+
This structure:
70+
- Highlights deployment guides prominently under "Guides → Deploying Applications"
71+
- Organizes other guides thematically
72+
- Keeps full TigerCLI documentation available under "Others"
73+
- Uses the new anchor syntax to extract only the "Guides" section
74+
75+
## Attribution
76+
77+
Changes developed with assistance from Claude Code (Anthropic), as noted in commit messages with co-authorship attribution.

docs/limitations.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
11
# Caveats / Known Design Decisions
22

33
- In an included `mkdocs.yml`, you cannot have `!include`. It is only supported in the root `mkdocs.yml`
4+
5+
- **Anchor-based inclusion alias collision risk**: When using anchor syntax (`!include path/to/mkdocs.yml#SectionName`), the generated alias follows the pattern `{site_name}-{SectionName}`. This can create a collision if you also include a separate `mkdocs.yml` file whose `site_name` exactly matches this generated alias.
6+
7+
**Example collision scenario:**
8+
```yaml
9+
# File A: docs/team-a/mkdocs.yml
10+
site_name: MyDocs
11+
nav:
12+
- Guides:
13+
- Getting Started: getting-started.md
14+
15+
# File B: docs/team-b/mkdocs.yml
16+
site_name: MyDocs-Guides
17+
nav:
18+
- Overview: overview.md
19+
20+
# Root mkdocs.yml - This will cause a collision!
21+
nav:
22+
- Team A Guides: "!include docs/team-a/mkdocs.yml#Guides" # alias: "MyDocs-Guides"
23+
- Team B: "!include docs/team-b/mkdocs.yml" # alias: "MyDocs-Guides"
24+
```
25+
26+
**Workaround:** Ensure your `site_name` values don't match the pattern `{OtherSiteName}-{SectionName}` when using anchor-based includes. The collision will be detected at build time with a clear error message listing all registered aliases.

mkdocs_monorepo_plugin/tests/test_plugin.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,60 @@ def test_section_not_found(self):
130130
with self.assertRaises(SystemExit):
131131
loader.read()
132132
loader.getNav()
133+
134+
def test_alias_collision_detection(self):
135+
"""Test that alias collisions are properly detected.
136+
137+
Known limitation: If a site_name matches another site's generated
138+
alias (site_name-SectionName), a collision occurs.
139+
140+
Example collision scenario:
141+
- Site A: site_name="TestSite" with #Guides -> alias="TestSite-Guides"
142+
- Site B: site_name="TestSite-Guides" (no anchor) -> alias="TestSite-Guides"
143+
144+
This test verifies that such collisions are detected and raise an error.
145+
"""
146+
# Create a second mkdocs file with a site_name that collides with
147+
# the generated alias from the first file
148+
collision_file = os.path.join(self.test_dir, "collision.yml")
149+
with open(collision_file, 'w') as f:
150+
f.write("""site_name: TestSite-Guides
151+
docs_dir: docs
152+
nav:
153+
- Home: index.md
154+
""")
155+
156+
# Set up config with both includes - one with anchor, one without
157+
root_config = {
158+
"config_file_path": os.path.join(self.test_dir, "root.yml"),
159+
"docs_dir": os.path.join(self.test_dir, "docs"),
160+
"nav": [
161+
{"Section1": "!include mkdocs.yml#Guides"},
162+
{"Section2": "!include collision.yml"}
163+
]
164+
}
165+
166+
# Create root mkdocs.yml
167+
with open(root_config["config_file_path"], 'w') as f:
168+
f.write("""site_name: Root
169+
docs_dir: docs
170+
nav:
171+
- Section1: "!include mkdocs.yml#Guides"
172+
- Section2: "!include collision.yml"
173+
""")
174+
175+
# Verify the aliases would collide
176+
config1 = {"config_file_path": self.mkdocs_file}
177+
loader1 = IncludeNavLoader(config1, "mkdocs.yml#Guides")
178+
loader1.read()
179+
alias1 = loader1.getAlias()
180+
181+
config2 = {"config_file_path": collision_file}
182+
loader2 = IncludeNavLoader(config2, "collision.yml")
183+
loader2.read()
184+
alias2 = loader2.getAlias()
185+
186+
# Both should produce "TestSite-Guides"
187+
self.assertEqual(alias1, "TestSite-Guides")
188+
self.assertEqual(alias2, "TestSite-Guides")
189+
self.assertEqual(alias1, alias2) # Collision confirmed

0 commit comments

Comments
 (0)