1616# from os import glob
1717
1818from .categories import Category , parse as parse_categories
19+ from .fs import Fs , PathFs
1920from .metadata import (
2021 Example ,
2122 DocFilenames ,
@@ -55,6 +56,7 @@ class DocGenMergeWarning(MetadataError):
5556class DocGen :
5657 root : Path
5758 errors : MetadataErrors
59+ fs : Fs = field (default_factory = PathFs )
5860 entities : Dict [str , str ] = field (default_factory = dict )
5961 prefix : Optional [str ] = None
6062 validation : ValidationConfig = field (default_factory = ValidationConfig )
@@ -171,8 +173,8 @@ def extend_examples(self, examples: Iterable[Example], errors: MetadataErrors):
171173 self .examples [id ] = example
172174
173175 @classmethod
174- def empty (cls , validation : ValidationConfig = ValidationConfig ()) -> "DocGen" :
175- return DocGen (root = Path ("/" ), errors = MetadataErrors (), validation = validation )
176+ def empty (cls , validation : ValidationConfig = ValidationConfig (), fs : Fs = PathFs () ) -> "DocGen" :
177+ return DocGen (root = Path ("/" ), errors = MetadataErrors (), validation = validation , fs = fs )
176178
177179 @classmethod
178180 def default (cls ) -> "DocGen" :
@@ -190,6 +192,7 @@ def clone(self) -> "DocGen":
190192 snippet_files = set (),
191193 cross_blocks = set (),
192194 examples = {},
195+ fs = self .fs ,
193196 )
194197
195198 def for_root (
@@ -199,7 +202,7 @@ def for_root(
199202
200203 config = config or Path (__file__ ).parent / "config"
201204
202- doc_gen = DocGen .empty ()
205+ doc_gen = DocGen .empty (fs = self . fs )
203206 parse_config (doc_gen , root , config , self .validation .strict_titles )
204207 self .merge (doc_gen )
205208
@@ -209,31 +212,31 @@ def for_root(
209212 return self
210213
211214 def find_and_process_metadata (self , metadata_path : Path ):
212- for path in metadata_path . glob ("*_metadata.yaml" ):
215+ for path in self . fs . glob (metadata_path , "*_metadata.yaml" ):
213216 self .process_metadata (path )
214217
215218 def process_metadata (self , path : Path ) -> "DocGen" :
216219 if path in self ._loaded :
217220 return self
218221 try :
219- with open (path ) as file :
220- examples , errs = parse_examples (
221- path ,
222- yaml .safe_load (file ),
223- self .sdks ,
224- self .services ,
225- self .standard_categories ,
226- self .cross_blocks ,
227- self .validation ,
228- )
229- self .extend_examples (examples , self .errors )
230- self .errors .extend (errs )
231- for example in examples :
232- for lang in example .languages :
233- language = example .languages [lang ]
234- for version in language .versions :
235- for excerpt in version .excerpts :
236- self .snippet_files .update (excerpt .snippet_files )
222+ content = self . fs . read (path )
223+ examples , errs = parse_examples (
224+ path ,
225+ yaml .safe_load (content ),
226+ self .sdks ,
227+ self .services ,
228+ self .standard_categories ,
229+ self .cross_blocks ,
230+ self .validation ,
231+ )
232+ self .extend_examples (examples , self .errors )
233+ self .errors .extend (errs )
234+ for example in examples :
235+ for lang in example .languages :
236+ language = example .languages [lang ]
237+ for version in language .versions :
238+ for excerpt in version .excerpts :
239+ self .snippet_files .update (excerpt .snippet_files )
237240 self ._loaded .add (path )
238241 except ParserError as e :
239242 self .errors .append (YamlParseError (file = path , parser_error = str (e )))
@@ -246,8 +249,9 @@ def from_root(
246249 config : Optional [Path ] = None ,
247250 validation : ValidationConfig = ValidationConfig (),
248251 incremental : bool = False ,
252+ fs : Fs = PathFs (),
249253 ) -> "DocGen" :
250- return DocGen .empty (validation = validation ).for_root (
254+ return DocGen .empty (validation = validation , fs = fs ).for_root (
251255 root , config , incremental = incremental
252256 )
253257
@@ -348,6 +352,10 @@ def default(self, obj):
348352 "__entity_errors__" : [{error .entity : error .message ()} for error in obj ]
349353 }
350354
355+ if isinstance (obj , Fs ):
356+ # Don't serialize filesystem objects for security
357+ return {"__fs__" : obj .__class__ .__name__ }
358+
351359 if isinstance (obj , set ):
352360 return {"__set__" : list (obj )}
353361
@@ -356,64 +364,65 @@ def default(self, obj):
356364
357365def parse_config (doc_gen : DocGen , root : Path , config : Path , strict : bool ):
358366 try :
359- with open (root / ".doc_gen" / "validation.yaml" , encoding = "utf-8" ) as file :
360- validation = yaml .safe_load (file )
361- validation = validation or {}
362- doc_gen .validation .allow_list .update (validation .get ("allow_list" , []))
363- doc_gen .validation .sample_files .update (validation .get ("sample_files" , []))
367+ content = doc_gen . fs . read (root / ".doc_gen" / "validation.yaml" )
368+ validation = yaml .safe_load (content )
369+ validation = validation or {}
370+ doc_gen .validation .allow_list .update (validation .get ("allow_list" , []))
371+ doc_gen .validation .sample_files .update (validation .get ("sample_files" , []))
364372 except Exception :
365373 pass
366374
367375 try :
368376 sdk_path = config / "sdks.yaml"
369- with sdk_path . open ( encoding = "utf-8" ) as file :
370- meta = yaml .safe_load (file )
371- sdks , errs = parse_sdks (sdk_path , meta , strict )
372- doc_gen .sdks = sdks
373- doc_gen .errors .extend (errs )
377+ content = doc_gen . fs . read ( sdk_path )
378+ meta = yaml .safe_load (content )
379+ sdks , errs = parse_sdks (sdk_path , meta , strict )
380+ doc_gen .sdks = sdks
381+ doc_gen .errors .extend (errs )
374382 except Exception :
375383 pass
376384
377385 try :
378386 services_path = config / "services.yaml"
379- with services_path . open ( encoding = "utf-8" ) as file :
380- meta = yaml .safe_load (file )
381- services , service_errors = parse_services (services_path , meta )
382- doc_gen .services = services
383- for service in doc_gen .services .values ():
384- if service .expanded :
385- doc_gen .entities [service .long ] = service .expanded .long
386- doc_gen .entities [service .short ] = service .expanded .short
387- doc_gen .errors .extend (service_errors )
387+ content = doc_gen . fs . read ( services_path )
388+ meta = yaml .safe_load (content )
389+ services , service_errors = parse_services (services_path , meta )
390+ doc_gen .services = services
391+ for service in doc_gen .services .values ():
392+ if service .expanded :
393+ doc_gen .entities [service .long ] = service .expanded .long
394+ doc_gen .entities [service .short ] = service .expanded .short
395+ doc_gen .errors .extend (service_errors )
388396 except Exception :
389397 pass
390398
391399 try :
392400 categories_path = config / "categories.yaml"
393- with categories_path . open ( encoding = "utf-8" ) as file :
394- meta = yaml .safe_load (file )
395- standard_categories , categories , errs = parse_categories (
396- categories_path , meta
397- )
398- doc_gen .standard_categories = standard_categories
399- doc_gen .categories = categories
400- doc_gen .errors .extend (errs )
401+ content = doc_gen . fs . read ( categories_path )
402+ meta = yaml .safe_load (content )
403+ standard_categories , categories , errs = parse_categories (
404+ categories_path , meta
405+ )
406+ doc_gen .standard_categories = standard_categories
407+ doc_gen .categories = categories
408+ doc_gen .errors .extend (errs )
401409 except Exception :
402410 pass
403411
404412 try :
405413 entities_config_path = config / "entities.yaml"
406- with entities_config_path . open ( encoding = "utf-8" ) as file :
407- entities_config = yaml .safe_load (file )
414+ content = doc_gen . fs . read ( entities_config_path )
415+ entities_config = yaml .safe_load (content )
408416 for entity , expanded in entities_config ["expanded_override" ].items ():
409417 doc_gen .entities [entity ] = expanded
410418 except Exception :
411419 pass
412420
413421 metadata = root / ".doc_gen/metadata"
414422 try :
423+ cross_content_path = metadata .parent / "cross-content"
415424 doc_gen .cross_blocks = set (
416- [path .name for path in ( metadata . parent / "cross-content" ) .glob ("*.xml" )]
425+ [path .name for path in doc_gen . fs .glob (cross_content_path , "*.xml" )]
417426 )
418427 except Exception :
419428 pass
0 commit comments