22import argparse
33from pathlib import Path
44import yaml
5+ from urllib .parse import urlsplit
6+ from schema_salad .fetcher import DefaultFetcher
7+ from cwltool .context import LoadingContext
8+
9+ APPROVED_SCHEMAS = (
10+ "https://raw.githubusercontent.com/eoap/schemas/main/ogc.yaml" ,
11+ "https://raw.githubusercontent.com/eoap/schemas/main/geojson.yaml" ,
12+ "https://raw.githubusercontent.com/eoap/schemas/main/string_format.yaml" ,
13+ )
14+
15+
16+ class PublishedSchemaFetcher (DefaultFetcher ):
17+ """Fetch the approved published contracts through the schema SDK."""
18+
19+ def fetch_text (self , url : str , content_types : list [str ] | None = None ) -> str :
20+ if urlsplit (url ).scheme in {"http" , "https" } and url .split ("#" )[0 ] not in APPROVED_SCHEMAS :
21+ raise RuntimeError ("Only approved published schemas may be fetched" )
22+ return super ().fetch_text (url , content_types )
23+
524
625
726def render (path ):
@@ -14,7 +33,7 @@ def check(value):
1433 if isinstance (value , dict ):
1534 assert '$include' not in value , f'{ path } : external include'
1635 if '$import' in value :
17- assert value ['$import' ] in ('https://raw.githubusercontent.com/eoap/schemas/main/ogc.yaml' , 'https://raw.githubusercontent.com/eoap/schemas/main/geojson.yaml' ), f'{ path } : unapproved schema import'
36+ assert value ['$import' ] in ('https://raw.githubusercontent.com/eoap/schemas/main/ogc.yaml' , 'https://raw.githubusercontent.com/eoap/schemas/main/geojson.yaml' , 'https://raw.githubusercontent.com/eoap/schemas/main/string_format.yaml' ), f'{ path } : unapproved schema import'
1837 for child in value .values (): check (child )
1938 elif isinstance (value , list ):
2039 for child in value : check (child )
@@ -53,29 +72,28 @@ def check(value):
5372 parser = argparse .ArgumentParser (description = __doc__ )
5473 parser .add_argument ('--validate' , action = 'store_true' , help = 'Also validate isolated CWL, allowing the approved OGC schema import' )
5574 parser .add_argument ('--output' , type = Path , default = Path ('/tmp/stac-cwl-docs' ))
75+ parser .add_argument ("--source" , type = Path , default = Path (__file__ ).resolve ().parents [1 ])
5676 args = parser .parse_args ()
57- root = Path ( __file__ ). resolve (). parents [ 1 ]
77+ root = args . source
5878 for path in sorted (root .rglob ('*.cwl' )):
5979 if path .name .startswith ('.' ) or not path .stat ().st_size or any (part .startswith ('.' ) for part in path .relative_to (root ).parts ): continue
6080 markdown = render (path )
6181 if args .validate :
62- import requests
6382 import shutil
6483 import tempfile
84+ from cwltool .context import LoadingContext
6585 from cwltool .main import main
66- original_request = requests .sessions .Session .request
67- def blocked_request (session , method , url , ** kwargs ):
68- if url .split ('#' )[0 ] in ('https://raw.githubusercontent.com/eoap/schemas/main/ogc.yaml' , 'https://raw.githubusercontent.com/eoap/schemas/main/geojson.yaml' ):
69- return original_request (session , method , url , ** kwargs )
70- raise RuntimeError ('Only the approved OGC schema may be fetched' )
71- requests .sessions .Session .request = blocked_request
72- try :
73- with tempfile .TemporaryDirectory () as isolated :
74- target_cwl = Path (isolated ) / path .name
75- shutil .copy (path , target_cwl )
76- assert main (['--validate' , str (target_cwl )]) == 0 , path
77- finally :
78- requests .sessions .Session .request = original_request
86+ document = yaml .safe_load (path .read_text ())
87+ graph = document .get ("$graph" )
88+ entrypoints = [process ["id" ].rsplit ("#" , 1 )[- 1 ] for process in graph ] if graph else [None ]
89+ with tempfile .TemporaryDirectory () as isolated :
90+ target_cwl = Path (isolated ) / path .name
91+ shutil .copy (path , target_cwl )
92+ for entrypoint in entrypoints :
93+ context = LoadingContext ()
94+ context .fetcher_constructor = PublishedSchemaFetcher
95+ target = str (target_cwl ) + ("#" + entrypoint if entrypoint else "" )
96+ assert main (["--validate" , target ], loadingContext = context ) == 0 , (path , entrypoint )
7997 target = args .output / path .relative_to (root ).with_suffix ('.md' )
8098 target .parent .mkdir (parents = True , exist_ok = True )
8199 target .write_text (markdown )
0 commit comments