23
23
4C."""
24
24
25
25
import copy as _copy
26
- import datetime as _datetime
27
26
import os as _os
28
27
import shutil as _shutil
29
28
import subprocess as _subprocess # nosec B404
30
29
import sys as _sys
30
+ from datetime import datetime as _datetime
31
31
from pathlib import Path as _Path
32
32
from typing import Any as _Any
33
33
from typing import Dict as _Dict
34
34
from typing import List as _List
35
35
from typing import Optional as _Optional
36
+ from typing import Tuple as _Tuple
36
37
37
38
import yaml as _yaml
38
39
@@ -346,16 +347,25 @@ def delete_section(self, section_name):
346
347
raise Warning (f"Section { section_name } does not exist!" )
347
348
348
349
def write_input_file (
349
- self , file_path : _Path , * , nox_xml_file : _Optional [str ] = None , ** kwargs
350
+ self ,
351
+ file_path : _Path ,
352
+ * ,
353
+ nox_xml_file : _Optional [str ] = None ,
354
+ add_application_script : _Optional [bool ] = False ,
355
+ ** kwargs ,
350
356
):
351
357
"""Write the input file to disk.
352
358
353
359
Args:
354
- file_path: str
360
+ file_path:
355
361
Path to the input file that should be created.
356
- nox_xml_file: str
362
+ nox_xml_file:
357
363
(optional) If this argument is given, the xml file will be created
358
364
with this name, in the same directory as the input file.
365
+ add_application_script:
366
+ (optional) If this argument is set to True, the script that
367
+ created this input file will be added to the input file as a
368
+ comment.
359
369
"""
360
370
361
371
# Check if a xml file needs to be written.
@@ -382,22 +392,28 @@ def write_input_file(
382
392
width = float ("inf" ),
383
393
)
384
394
395
+ # Add the application script to the input file.
396
+ if add_application_script :
397
+ application_path = _Path (_sys .argv [0 ]).resolve ()
398
+ application_script_lines = self ._get_application_script (
399
+ application_path
400
+ )
401
+ input_file .writelines (application_script_lines )
402
+
385
403
def get_dict_to_dump (
386
404
self ,
387
405
* ,
388
- header : bool = True ,
389
- add_script_to_header : bool = True ,
406
+ information_header : bool = False ,
390
407
check_nox : bool = True ,
391
408
):
392
409
"""Return the dictionary representation of this input file for dumping
393
410
to a yaml file.
394
411
395
412
Args:
396
- header:
397
- If the header should be exported to the input file files.
398
- add_script_to_header:
399
- If true, a copy of the executing script will be added to the input
400
- file. This is only in affect when header is True.
413
+ information_header:
414
+ If the information header should be exported to the input file
415
+ Contains creation date, git details of MeshPy, CubitPy and
416
+ original application which created the input file if available.
401
417
check_nox:
402
418
If this is true, an error will be thrown if no nox file is set.
403
419
"""
@@ -412,14 +428,9 @@ def get_dict_to_dump(
412
428
# TODO: Check if the deepcopy makes sense to be optional
413
429
yaml_dict = _copy .deepcopy (self .sections )
414
430
415
- # TODO: Add header to yaml
416
- # # Add header to the input file.
417
- # end_text = None
418
-
419
- # lines.extend(["// " + line for line in _mpy.input_file_meshpy_header])
420
- # if header:
421
- # header_text, end_text = self._get_header(add_script_to_header)
422
- # lines.append(header_text)
431
+ # Add information header to the input file
432
+ if information_header :
433
+ yaml_dict ["TITLE" ] = self ._get_header ()
423
434
424
435
# Check if a file has to be created for the NOX xml information.
425
436
if self .nox_xml is not None :
@@ -622,104 +633,104 @@ def get_number_of_coupling_conditions(key):
622
633
_dump_mesh_items (yaml_dict , "NODE COORDS" , self .nodes )
623
634
_dump_mesh_items (yaml_dict , "STRUCTURE ELEMENTS" , self .elements )
624
635
625
- # TODO: what to do here - how to add the script
626
- # # Add end text.
627
- # if end_text is not None:
628
- # lines.append(end_text)
629
-
630
636
return yaml_dict
631
637
632
- def _get_header (self , add_script ):
633
- """Return the header for the input file."""
638
+ def _get_header (self ) -> dict :
639
+ """Return the information header for the current MeshPy run.
640
+
641
+ Returns:
642
+ A dictionary with the header information.
643
+ """
644
+
645
+ def _get_git_data (repo_path : _Path ) -> _Tuple [_Optional [str ], _Optional [str ]]:
646
+ """Return the hash and date of the current git commit.
634
647
635
- def get_git_data (repo ):
636
- """Return the hash and date of the current git commit."""
648
+ Args:
649
+ repo_path: Path to the git repository.
650
+ Returns:
651
+ A tuple with the hash and date of the current git commit
652
+ if available, otherwise None.
653
+ """
637
654
git = _shutil .which ("git" )
638
655
if git is None :
639
656
raise RuntimeError ("Git executable not found" )
640
657
out_sha = _subprocess .run ( # nosec B603
641
658
[git , "rev-parse" , "HEAD" ],
642
- cwd = repo ,
659
+ cwd = repo_path ,
643
660
stdout = _subprocess .PIPE ,
644
661
stderr = _subprocess .DEVNULL ,
645
662
)
646
663
out_date = _subprocess .run ( # nosec B603
647
664
[git , "show" , "-s" , "--format=%ci" ],
648
- cwd = repo ,
665
+ cwd = repo_path ,
649
666
stdout = _subprocess .PIPE ,
650
667
stderr = _subprocess .DEVNULL ,
651
668
)
669
+
652
670
if not out_sha .returncode + out_date .returncode == 0 :
653
671
return None , None
654
- else :
655
- sha = out_sha .stdout .decode ("ascii" ).strip ()
656
- date = out_date .stdout .decode ("ascii" ).strip ()
657
- return sha , date
658
-
659
- headers = []
660
- end_text = None
661
-
662
- # Header containing model information.
663
- current_time_string = _datetime .datetime .now ().strftime ("%Y-%m-%d %H:%M:%S" )
664
- model_header = f"// Date: { current_time_string } \n "
665
- if self .description :
666
- model_header += f"// Description: { self .description } \n "
667
- headers .append (model_header )
668
-
669
- # Get information about the script.
670
- script_path = _os .path .realpath (_sys .argv [0 ])
671
- script_git_sha , script_git_date = get_git_data (_os .path .dirname (script_path ))
672
- script_header = "// Script used to create input file:\n "
673
- script_header += f"// path: { script_path } \n "
674
- if script_git_sha is not None :
675
- script_header += (
676
- f"// git sha: { script_git_sha } \n // git date: { script_git_date } \n "
677
- )
678
- headers .append (script_header )
679
672
680
- # Header containing meshpy information.
681
- meshpy_git_sha , meshpy_git_date = get_git_data (
682
- _os .path .dirname (_os .path .realpath (__file__ ))
673
+ git_sha = out_sha .stdout .decode ("ascii" ).strip ()
674
+ git_date = out_date .stdout .decode ("ascii" ).strip ()
675
+ return git_sha , git_date
676
+
677
+ header : dict = {"MeshPy" : {}}
678
+
679
+ header ["MeshPy" ]["creation_date" ] = _datetime .now ().isoformat (
680
+ sep = " " , timespec = "seconds"
683
681
)
684
- headers .append (
685
- "// Input file created with meshpy\n "
686
- f"// git sha: { meshpy_git_sha } \n "
687
- f"// git date: { meshpy_git_date } \n "
682
+
683
+ # application which created the input file
684
+ application_path = _Path (_sys .argv [0 ]).resolve ()
685
+ header ["MeshPy" ]["Application" ] = {"path" : str (application_path )}
686
+
687
+ application_git_sha , application_git_date = _get_git_data (
688
+ application_path .parent
688
689
)
690
+ if application_git_sha is not None and application_git_date is not None :
691
+ header ["MeshPy" ]["Application" ] = {
692
+ "git_sha" : application_git_sha ,
693
+ "git_date" : application_git_date ,
694
+ }
695
+
696
+ # MeshPy information
697
+ meshpy_git_sha , meshpy_git_date = _get_git_data (
698
+ _Path (__file__ ).resolve ().parent
699
+ )
700
+ if meshpy_git_sha is not None and meshpy_git_date is not None :
701
+ header ["MeshPy" ]["MeshPy" ] = {
702
+ "git_SHA" : meshpy_git_sha ,
703
+ "git_date" : meshpy_git_date ,
704
+ }
689
705
706
+ # CubitPy information
690
707
if _cubitpy_is_available ():
691
- # Get git information about cubitpy.
692
- cubitpy_git_sha , cubitpy_git_date = get_git_data (
708
+ cubitpy_git_sha , cubitpy_git_date = _get_git_data (
693
709
_os .path .dirname (_cubitpy .__file__ )
694
710
)
695
711
696
- if cubitpy_git_sha is not None :
697
- # Cubitpy_header.
698
- headers . append (
699
- "// The module cubitpy was loaded \n "
700
- f"// git sha: { cubitpy_git_sha } \n "
701
- f"// git date: { cubitpy_git_date } \n "
702
- )
712
+ if cubitpy_git_sha is not None and cubitpy_git_date is not None :
713
+ header [ "MeshPy" ][ "CubitPy" ] = {
714
+ "git_SHA" : cubitpy_git_sha ,
715
+ "git_date" : cubitpy_git_date ,
716
+ }
717
+
718
+ return header
703
719
704
- string_line = "// " + "" .join (["-" ] * 80 )
720
+ def _get_application_script (self , application_path : _Path ) -> list [str ]:
721
+ """Get the script that created this input file.
705
722
706
- # If needed, append the contents of the script.
707
- if add_script :
708
- # Header for the script 'section'.
709
- script_lines = [
710
- string_line
711
- + "\n // Full script used to create this input file.\n "
712
- + string_line
713
- + "\n "
714
- ]
723
+ Args:
724
+ application_path: Path to the script that created this input file.
725
+ Returns:
726
+ A list of strings with the script that created this input file.
727
+ """
715
728
716
- # Get the contents of script.
717
- with open ( script_path ) as script_file :
718
- script_lines . extend ( script_file . readlines ())
729
+ application_script_lines = [
730
+ "# Application script which created this input file: \n "
731
+ ]
719
732
720
- # Comment the python code lines.
721
- end_text = "//" . join ( script_lines )
733
+ with open ( application_path ) as script_file :
734
+ application_script_lines . extend ( "# " + line for line in script_file )
722
735
723
- return (
724
- string_line + "\n " + (string_line + "\n " ).join (headers ) + string_line
725
- ), end_text
736
+ return application_script_lines
0 commit comments