Skip to content

Instantly share code, notes, and snippets.

@ShivamPR21
Created October 16, 2023 22:40
Show Gist options
  • Save ShivamPR21/26bba01a14f2c87c998cd4dfd09fc1ac to your computer and use it in GitHub Desktop.
Save ShivamPR21/26bba01a14f2c87c998cd4dfd09fc1ac to your computer and use it in GitHub Desktop.
Merge Two TOML configuration files
import tomli
import tomli_w
import argparse
import os
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("file1")
parser.add_argument("file2")
parser.add_argument("out_file")
args = parser.parse_args()
# print(args)
# Check for input file existence
file1, file2 = args.file1, args.file2
out_path = args.out_file
if not (os.path.exists(file1) and file1.endswith('toml')):
raise ValueError(f'Invalid path {file1}')
if not (os.path.exists(file2) and file2.endswith('toml')):
raise ValueError(f'Invalid path {file2}')
if os.path.isdir(out_path):
output_parent_dir = out_path
output_file = os.path.basename(file1)
else:
output_parent_dir = os.path.abspath(os.path.join(out_path, os.path.pardir))
output_file = os.path.basename(out_path)
os.makedirs(output_parent_dir, exist_ok=True)
with open(file1, mode='rb') as stream:
f1 = tomli.load(stream)
with open(file2, mode='rb') as stream:
f2 = tomli.load(stream)
# print(f'{f1 = } \n {f2 = }')
for key, val in f2.items():
if not isinstance(val, dict):
if key not in f1:
f1.update({key: val})
continue
if key in f1:
try:
for key_, val_ in val.items():
if key_ not in f1[key]:
f1[key].update({key_: val_})
except ValueError as e:
raise ValueError(e)
else:
f1.update({key: val})
with open(os.path.join(output_parent_dir, out_path), 'wb') as outfile:
tomli_w.dump(f1, outfile)
@ShivamPR21
Copy link
Author

Usage :

python toml-merge.py <base_file_path> <source_file_path> <out_path/dir>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment