77import  yaml 
88from  pydantic  import  BaseModel , Field 
99from  typing_extensions  import  Self 
10+ from  yaml .parser  import  ParserError 
1011
1112from  .exceptions  import  FileNotValidError 
1213from  .utils  import  find_files , read_file 
@@ -31,6 +32,8 @@ class InfrahubFileData(BaseModel):
3132class  LocalFile (BaseModel ):
3233    identifier : str  |  None  =  None 
3334    location : Path 
35+     multiple_documents : bool  =  False 
36+     document_position : int  |  None  =  None 
3437    content : dict  |  None  =  None 
3538    valid : bool  =  True 
3639    error_message : str  |  None  =  None 
@@ -57,20 +60,52 @@ def load_content(self) -> None:
5760    def  validate_content (self ) ->  None :
5861        pass 
5962
63+     @classmethod  
64+     def  load_file_from_disk (cls , path : Path ) ->  list [Self ]:
65+         yaml_files : list [Self ] =  []
66+ 
67+         try :
68+             file_content  =  read_file (path )
69+ 
70+             has_multiple_document  =  bool (file_content .count ("---" ) >  1 )
71+ 
72+             if  has_multiple_document :
73+                 for  content  in  yaml .safe_load_all (file_content ):
74+                     yaml_files .append (cls (location = path , multiple_documents = has_multiple_document , content = content ))
75+             else :
76+                 yaml_files .append (
77+                     cls (location = path , multiple_documents = has_multiple_document , content = yaml .safe_load (file_content ))
78+                 )
79+         except  FileNotValidError  as  exc :
80+             yaml_files .append (
81+                 cls (location = path , multiple_documents = has_multiple_document , error_message = exc .message , valid = False )
82+             )
83+         except  (yaml .YAMLError , ParserError ):
84+             yaml_files .append (
85+                 cls (
86+                     location = path ,
87+                     multiple_documents = has_multiple_document ,
88+                     error_message = "Invalid YAML/JSON file" ,
89+                     valid = False ,
90+                 )
91+             )
92+ 
93+         if  has_multiple_document :
94+             for  idx , file  in  enumerate (yaml_files ):
95+                 file .document_position  =  idx  +  1 
96+ 
97+         return  yaml_files 
98+ 
6099    @classmethod  
61100    def  load_from_disk (cls , paths : list [Path ]) ->  list [Self ]:
62101        yaml_files : list [Self ] =  []
63102        for  file_path  in  paths :
64103            if  file_path .is_file ():
65-                 yaml_file  =  cls (location = file_path )
66-                 yaml_file .load_content ()
67-                 yaml_files .append (yaml_file )
104+                 yaml_files .extend (cls .load_file_from_disk (path = file_path ))
68105            elif  file_path .is_dir ():
69106                files  =  find_files (extension = ["yaml" , "yml" , "json" ], directory = file_path )
70107                for  item  in  files :
71-                     yaml_file  =  cls (location = item )
72-                     yaml_file .load_content ()
73-                     yaml_files .append (yaml_file )
108+                     yaml_files .extend (cls .load_file_from_disk (path = item ))
74109            else :
75110                raise  FileNotValidError (name = str (file_path ), message = f"{ file_path }  )
76111
0 commit comments