55from .jsonldutils import load_file , validate_data
66from .utils import lgr , start_server , stop_server
77
8+ DIR_TO_SKIP = [".git" , "__pycache__" , "env" , "venv" ]
9+ FILES_TO_SKIP = [".DS_Store" , ".gitignore" , ".flake8" , ".autorc" , "LICENSE" ]
10+ SUPPORTED_EXTENSIONS = [
11+ ".jsonld" ,
12+ "json" ,
13+ "js" ,
14+ "" ,
15+ ]
816
9- def validate_dir (directory , started = False , http_kwargs = {}):
17+
18+ def validate_dir (
19+ directory : str ,
20+ started : bool = False ,
21+ http_kwargs : None | dict [str , int ] = None ,
22+ stop = None ,
23+ ):
1024 """Validate a directory containing JSONLD documents against the ReproSchema pydantic model.
1125
26+ Recursively goes through the directory tree and validates files with the allowed extensions.
27+
1228 Parameters
1329 ----------
1430 directory: str
1531 Path to directory to walk for validation
32+
1633 started : bool
1734 Whether an http server exists or not
18- http_kwargs : dict
35+
36+ http_kwargs : dict or None
1937 Keyword arguments for the http server. Valid keywords are: port, path
2038 and tmpdir
2139
40+ stop: None or function
41+ Function to use to stop the HTTP server
42+
2243 Returns
2344 -------
2445 conforms: bool
2546 Whether the document is conformant with the shape. Raises an exception
2647 if any document is non-conformant.
2748
2849 """
50+ if http_kwargs is None :
51+ http_kwargs = {}
52+
2953 if not os .path .isdir (directory ):
54+ if stop is not None :
55+ stop_server (stop )
3056 raise Exception (f"{ directory } is not a directory" )
31- print (f"Validating directory { directory } " )
32- stop = None
33- if not started :
34- stop , port = start_server (** http_kwargs )
35- http_kwargs ["port" ] = port
36- else :
37- if "port" not in http_kwargs :
38- raise KeyError ("HTTP server started, but port key is missing" )
39-
40- for root , _ , files in os .walk (directory ):
41- for name in files :
42- full_file_name = os .path .join (root , name )
43-
44- if Path (full_file_name ).suffix not in [
45- ".jsonld" ,
46- "json" ,
47- "js" ,
48- "" ,
49- ]:
50- lgr .info (f"Skipping file { full_file_name } " )
51- continue
52-
53- lgr .debug (f"Validating file { full_file_name } " )
54- try :
55- data = load_file (
56- full_file_name , started = True , http_kwargs = http_kwargs
57- )
58- if len (data ) == 0 :
59- raise ValueError ("Empty data graph" )
60- print (f"Validating { full_file_name } " )
61- conforms , vtext = validate_data (data )
62- except (ValueError , json .JSONDecodeError ):
57+
58+ if Path (directory ).name in DIR_TO_SKIP :
59+ lgr .info (f"Skipping directory { directory } " )
60+ return True
61+
62+ lgr .debug (f"Validating directory { directory } " )
63+
64+ files_to_validate = [
65+ str (x )
66+ for x in Path (directory ).iterdir ()
67+ if x .is_file ()
68+ and x .name not in FILES_TO_SKIP
69+ and x .suffix in SUPPORTED_EXTENSIONS
70+ ]
71+
72+ for name in files_to_validate :
73+ lgr .debug (f"Validating file { name } " )
74+
75+ try :
76+ data = load_file (name , started = started , http_kwargs = http_kwargs )
77+ if len (data ) == 0 :
6378 if stop is not None :
6479 stop_server (stop )
65- raise
66- else :
67- if not conforms :
68- lgr .critical (
69- f"File { full_file_name } has validation errors."
70- )
71- if stop is not None :
72- stop_server (stop )
73- raise ValueError (vtext )
74- if not started :
75- stop_server (stop )
76- return True
80+ raise ValueError (f"Empty data graph in file { name } " )
81+ conforms , vtext = validate_data (data )
82+ except (ValueError , json .JSONDecodeError ):
83+ if stop is not None :
84+ stop_server (stop )
85+ raise
86+ else :
87+ if not conforms :
88+ lgr .critical (f"File { name } has validation errors." )
89+ stop_server (stop )
90+ raise ValueError (vtext )
91+
92+ dirs_to_validate = [
93+ str (x )
94+ for x in Path (directory ).iterdir ()
95+ if x .is_dir () and x .name not in DIR_TO_SKIP
96+ ]
97+
98+ for dir in dirs_to_validate :
99+ conforms , stop = validate_dir (
100+ dir , started = started , http_kwargs = http_kwargs , stop = stop
101+ )
102+
103+ return True , stop
77104
78105
79106def validate (path ):
@@ -92,16 +119,29 @@ def validate(path):
92119
93120 """
94121 if os .path .isdir (path ):
95- conforms = validate_dir (path )
122+
123+ stop , port = start_server ()
124+ http_kwargs = {"port" : port }
125+ started = True
126+
127+ conforms , _ = validate_dir (
128+ path , started = started , http_kwargs = http_kwargs , stop = stop
129+ )
130+
131+ stop_server (stop )
132+
96133 else :
97- # Skip validation for .DS_Store files
98- if Path (path ).name == ".DS_Store" :
99- lgr .info (f"{ path } is a .DS_Store file and is skipped. " )
134+
135+ if Path (path ).name in FILES_TO_SKIP :
136+ lgr .info (f"Skipping file { path } " )
100137 return True
138+
101139 data = load_file (path , started = False )
102140 conforms , vtext = validate_data (data )
103141 if not conforms :
104142 lgr .critical (f"File { path } has validation errors." )
105143 raise ValueError (vtext )
144+
106145 lgr .info (f"{ path } conforms." )
146+
107147 return conforms
0 commit comments