1616import shutil
1717import sys
1818import tempfile
19- from collections .abc import MutableMapping , MutableSequence
2019from dataclasses import dataclass
2120from pathlib import Path
21+ from typing import cast
2222
2323import yaml
2424
2525SLUG_RE = re .compile (r"^[A-Za-z0-9._-]+$" )
26+ YamlMapping = dict [str , object ]
2627
2728
2829@dataclass
@@ -39,7 +40,9 @@ def parse_args() -> argparse.Namespace:
3940 parser .add_argument ("--operation" , choices = ["sync" , "remove" ], default = "sync" )
4041 parser .add_argument ("--source-root" , type = Path )
4142 parser .add_argument ("--docs-website-root" , required = True , type = Path )
42- parser .add_argument ("--channel" , required = True , choices = ["dev" , "latest" , "version" ])
43+ parser .add_argument (
44+ "--channel" , required = True , choices = ["dev" , "latest" , "version" ]
45+ )
4346 parser .add_argument ("--source-ref" , default = "" )
4447 parser .add_argument ("--version-slug" , default = "" )
4548 parser .add_argument ("--display-name" , default = "" )
@@ -58,11 +61,15 @@ def resolve_slug(channel: str, version_slug: str) -> str:
5861 if not version_slug :
5962 raise ValueError ("--version-slug is required when --channel=version" )
6063 if not SLUG_RE .fullmatch (version_slug ):
61- raise ValueError (f"version slug contains unsupported characters: { version_slug } " )
64+ raise ValueError (
65+ f"version slug contains unsupported characters: { version_slug } "
66+ )
6267 return version_slug
6368
6469
65- def resolve_display_name (channel : str , slug : str , source_ref : str , override : str ) -> str :
70+ def resolve_display_name (
71+ channel : str , slug : str , source_ref : str , override : str
72+ ) -> str :
6673 if override :
6774 return override
6875 if channel == "dev" :
@@ -116,15 +123,15 @@ def copy_if_exists(src: Path, dst: Path) -> None:
116123 shutil .copy2 (src , dst )
117124
118125
119- def read_yaml (path : Path ) -> dict :
126+ def read_yaml (path : Path ) -> YamlMapping :
120127 ensure_existing (path , "YAML file" )
121128 data = yaml .safe_load (path .read_text (encoding = "utf-8" ))
122129 if not isinstance (data , dict ):
123130 raise ValueError (f"expected YAML mapping in { path } " )
124- return data
131+ return cast ( "YamlMapping" , data )
125132
126133
127- def write_yaml (path : Path , data : dict ) -> None :
134+ def write_yaml (path : Path , data : YamlMapping ) -> None :
128135 path .write_text (
129136 yaml .safe_dump (data , sort_keys = False , allow_unicode = True ),
130137 encoding = "utf-8" ,
@@ -140,20 +147,23 @@ def prefix_path(value: object, pages_dir: str) -> object:
140147
141148
142149def prefix_navigation_paths (value : object , pages_dir : str ) -> object :
143- if isinstance (value , MutableMapping ):
150+ if isinstance (value , dict ):
151+ mapping = cast ("YamlMapping" , value )
144152 for key in ("path" , "folder" ):
145- if key in value :
146- value [key ] = prefix_path (value [key ], pages_dir )
147- for child in value .values ():
153+ if key in mapping :
154+ mapping [key ] = prefix_path (mapping [key ], pages_dir )
155+ for child in mapping .values ():
148156 prefix_navigation_paths (child , pages_dir )
149- elif isinstance (value , MutableSequence ):
150- for child in value :
157+ elif isinstance (value , list ):
158+ for child in cast ( "list[object]" , value ) :
151159 prefix_navigation_paths (child , pages_dir )
152160 return value
153161
154162
155- def version_navigation (source_index : Path , pages_dir : str ) -> dict :
156- return prefix_navigation_paths (read_yaml (source_index ), pages_dir )
163+ def version_navigation (source_index : Path , pages_dir : str ) -> YamlMapping :
164+ data = read_yaml (source_index )
165+ prefix_navigation_paths (data , pages_dir )
166+ return data
157167
158168
159169def parse_versions (raw_versions : object ) -> list [VersionEntry ]:
@@ -162,20 +172,27 @@ def parse_versions(raw_versions: object) -> list[VersionEntry]:
162172 if not isinstance (raw_versions , list ):
163173 raise ValueError ("docs.yml versions must be a list" )
164174 entries : list [VersionEntry ] = []
165- for raw in raw_versions :
175+ for raw in cast ( "list[object]" , raw_versions ) :
166176 if not isinstance (raw , dict ):
167177 continue
168- slug = raw .get ("slug" )
169- display_name = raw .get ("display-name" )
170- path = raw .get ("path" )
171- if isinstance (slug , str ) and isinstance (display_name , str ) and isinstance (path , str ):
178+ entry = cast ("YamlMapping" , raw )
179+ slug = entry .get ("slug" )
180+ display_name = entry .get ("display-name" )
181+ path = entry .get ("path" )
182+ if (
183+ isinstance (slug , str )
184+ and isinstance (display_name , str )
185+ and isinstance (path , str )
186+ ):
172187 entries .append (
173188 VersionEntry (slug = slug , display_name = display_name , path = path )
174189 )
175190 return entries
176191
177192
178- def ordered_entries (existing : list [VersionEntry ], updated : VersionEntry ) -> list [VersionEntry ]:
193+ def ordered_entries (
194+ existing : list [VersionEntry ], updated : VersionEntry
195+ ) -> list [VersionEntry ]:
179196 by_slug = {entry .slug : entry for entry in existing }
180197 by_slug [updated .slug ] = updated
181198 existing_order = [entry .slug for entry in existing if entry .slug != updated .slug ]
@@ -206,7 +223,9 @@ def render_versions(entries: list[VersionEntry]) -> list[dict[str, str]]:
206223def component_dirs (fern_dir : Path ) -> list [str ]:
207224 dirs : list [str ] = []
208225 preferred = ["pages-latest" , "pages-dev" ]
209- all_page_dirs = sorted (path .name for path in fern_dir .glob ("pages-*" ) if path .is_dir ())
226+ all_page_dirs = sorted (
227+ path .name for path in fern_dir .glob ("pages-*" ) if path .is_dir ()
228+ )
210229 for name in preferred + all_page_dirs :
211230 path = fern_dir / name / "_components"
212231 component = f"./{ name } /_components"
@@ -229,7 +248,9 @@ def update_docs_yml(docs_yml: Path, updated: VersionEntry, fern_dir: Path) -> No
229248
230249def remove_docs_yml_entry (docs_yml : Path , slug : str , fern_dir : Path ) -> None :
231250 data = read_yaml (docs_yml )
232- entries = [entry for entry in parse_versions (data .get ("versions" )) if entry .slug != slug ]
251+ entries = [
252+ entry for entry in parse_versions (data .get ("versions" )) if entry .slug != slug
253+ ]
233254 data ["experimental" ] = {
234255 "mdx-components" : component_dirs (fern_dir ),
235256 }
@@ -274,7 +295,9 @@ def sync_docs(args: argparse.Namespace) -> None:
274295 )
275296 if refresh_shared :
276297 copy_if_exists (source_fern / "main.css" , target_fern / "main.css" )
277- copy_if_exists (source_fern / "fern.config.json" , target_fern / "fern.config.json" )
298+ copy_if_exists (
299+ source_fern / "fern.config.json" , target_fern / "fern.config.json"
300+ )
278301
279302 versions_dir = target_fern / "versions"
280303 versions_dir .mkdir (parents = True , exist_ok = True )
@@ -294,8 +317,7 @@ def sync_docs(args: argparse.Namespace) -> None:
294317 )
295318
296319 print (
297- f"Synced { channel } docs from { source_ref } to fern/{ pages_dir } "
298- f"({ display_name } )"
320+ f"Synced { channel } docs from { source_ref } to fern/{ pages_dir } ({ display_name } )"
299321 )
300322
301323
0 commit comments