def main(argv: Optional[List[str]] = None) -> int: parser = get_parser() clargs = vars(parser.parse_args(argv)) # special cases: destructively consume CLI-only arguments with dict.pop if clargs.pop("logo"): with open(pkg_resources.resource_filename("nonos", "logo.txt")) as fh: logo = fh.read() print(f"{logo}{__doc__}Version {__version__}") return 0 if clargs.pop("version"): print(__version__) return 0 level = parse_verbose_level(clargs.pop("verbose")) logger.setLevel(level) if clargs.pop("isolated"): config_file_args: Dict[str, Any] = {} elif (ifile := clargs.pop("input")) is not None: if not os.path.isfile(ifile): print_err(f"Couldn't find requested input file '{ifile}'.") return 1 print_warn(f"[bold white]Using parameters from '{ifile}'.") config_file_args = inifix.load(ifile)
def command(inifile: str, indent: int | None = None) -> int: inifile = Path(inifile) if not inifile.is_file(): print_err(f"no such file {inifile}") return 1 print(json.dumps(load(inifile), indent=indent)) return 0
def loadIniFile(self): self.inifile = inifix.load(os.path.join(self.directory, self.paramfile)) if self.code == "idefix": self.vtk = self.inifile["Output"]["vtk"] elif self.code == "pluto": self.vtk = self.inifile["Static Grid Output"]["vtk"][0] elif self.code == "fargo3d": self.vtk = self.inifile["NINTERM"] * self.inifile["DT"] elif self.code == "fargo-adsg": self.vtk = self.inifile["Ninterm"] * self.inifile["DT"]
def test_format_keep_data(inifile, capsys, tmp_path): target = tmp_path / inifile.name ref_data = load(inifile) shutil.copyfile(inifile, target) ret = main([str(target)]) assert isinstance(ret, int) out, err = capsys.readouterr() # nothing to output to stdout with --inplace assert out == "" if err == f"{target} is already formatted\n": assert ret == 0 else: assert err == f"Fixing {target}\n" assert ret != 0 data_new = load(target) assert data_new == ref_data
def test_bool_cast_integration(s, expected, tmp_path): with open(tmp_path / "dummy.ini", "w") as fh: fh.write(f"dummy {s}") d = inifix.load(tmp_path / "dummy.ini") assert d == {"dummy": expected}
return 0 level = parse_verbose_level(clargs.pop("verbose")) logger.setLevel(level) if clargs.pop("isolated"): config_file_args: Dict[str, Any] = {} elif (ifile := clargs.pop("input")) is not None: if not os.path.isfile(ifile): print_err(f"Couldn't find requested input file '{ifile}'.") return 1 print_warn(f"[bold white]Using parameters from '{ifile}'.") config_file_args = inifix.load(ifile) elif os.path.isfile("nonos.ini"): print_warn("[bold white]Using parameters from 'nonos.ini'.") config_file_args = inifix.load("nonos.ini") else: config_file_args = {} # check that every parameter in the configuration is also exposed to the CLI assert not set(DEFAULTS).difference(set(clargs)) # squeeze out any unset value form cli config to leave room for file parameters clargs = {k: v for k, v in clargs.items() if v is not None} # NOTE: init.config is also a ChainMap instance with a default layer # this may be seen either as hyperstatism (good thing) or error prone redundancy (bad thing) args = ChainMap(clargs, config_file_args, DEFAULTS) if clargs.pop("config"): conf_repr = {} for key in DEFAULTS:
def command( directory: str, inifile: str = "idefix.ini", duration: float | None = None, time_step: float | None = None, one_step: bool | None = False, ) -> int: input_inifile = inifile for loc in [Path.cwd(), Path(directory)]: pinifile = (loc / input_inifile).resolve() if pinifile.is_file(): break else: print_err(f"could not find inifile {input_inifile}") return 1 if one_step: if time_step is None: time_step = inifix.load(pinifile)["TimeIntegrator"]["first_dt"] duration = time_step compilation_required = False d = Path(directory) if not (d / "idefix").is_file(): if not (d / "Makefile").is_file(): print_err( "No idefix instance or Makefile found in the target directory. " "Run `idfx conf` first." ) return 1 compilation_required = True else: last_compilation_time = os.stat(d / "idefix").st_mtime source_patterns = ( "**/*.hpp", "**/*.cpp", "**/*.h", "**/*.c", "**/CMakeLists.txt", ) files_to_check = files_from_patterns(d, *source_patterns, recursive=True) idefix_dir = Path(os.environ["IDEFIX_DIR"]) try: with pushd(idefix_dir): git_indexed_idefix_files = [ os.path.abspath(_) for _ in subprocess.run(["git", "ls-files"], capture_output=True) .stdout.decode() .split("\n") ] except subprocess.CalledProcessError: # emmit no warning here as Idefix might not be installed as a git copy pass else: files_to_check.extend( list( set(git_indexed_idefix_files).intersection( set(files_from_patterns(idefix_dir / "src", *source_patterns)) ) ) ) source_edit_times = tuple( (file, os.stat(file).st_mtime) for file in files_to_check ) time_deltas = tuple( (file, edit_time - last_compilation_time) for file, edit_time in source_edit_times ) if updated_since_compilation := tuple( file for file, td in time_deltas if td > 0 ): print_warning( "The following files were updated since last compilation:", ) print("\n".join(updated_since_compilation), file=sys.stderr) compilation_required = Confirm.ask( "Would you like to recompile before running the program ?" )
time_deltas = tuple( (file, edit_time - last_compilation_time) for file, edit_time in source_edit_times ) if updated_since_compilation := tuple( file for file, td in time_deltas if td > 0 ): print_warning( "The following files were updated since last compilation:", ) print("\n".join(updated_since_compilation), file=sys.stderr) compilation_required = Confirm.ask( "Would you like to recompile before running the program ?" ) if compilation_required and (ret := _make(directory)) != 0: return ret conf = inifix.load(pinifile) if time_step is not None: conf["TimeIntegrator"]["first_dt"] = time_step if duration is not None: conf["TimeIntegrator"]["tstop"] = duration with pushd(d), NamedTemporaryFile() as tmp_inifile: inifix.dump(conf, tmp_inifile.name) ret = subprocess.call(["./idefix", "-i", tmp_inifile.name]) if ret != 0: print_err("idefix terminated with an error.") return ret