Skip to content

Commit 9a43def

Browse files
rickeylevjanwinkler1
authored andcommitted
add toml2json
1 parent 694fb48 commit 9a43def

4 files changed

Lines changed: 123 additions & 0 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
load("@rules_python//python:defs.bzl", "py_test")
2+
3+
py_test(
4+
name = "toml2json_test",
5+
srcs = ["toml2json_test.py"],
6+
main = "toml2json_test.py",
7+
deps = [
8+
"//tools/private/toml2json",
9+
],
10+
)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import io
2+
import json
3+
import os
4+
import sys
5+
import tempfile
6+
import unittest
7+
from unittest.mock import patch
8+
9+
from tools.private.toml2json import toml2json
10+
11+
class Toml2JsonTest(unittest.TestCase):
12+
13+
def setUp(self):
14+
self.temp_dir = tempfile.TemporaryDirectory()
15+
self.addCleanup(self.temp_dir.cleanup)
16+
17+
def _create_temp_toml_file(self, content):
18+
fd, path = tempfile.mkstemp(suffix=".toml", dir=self.temp_dir.name)
19+
with os.fdopen(fd, "wb") as f:
20+
f.write(content)
21+
return path
22+
23+
def test_basic_conversion(self):
24+
toml_content = b"""
25+
[owner]
26+
name = "Tom Preston-Werner"
27+
dob = 1979-05-27T07:32:00-08:00
28+
"""
29+
expected_json = {
30+
"owner": {
31+
"name": "Tom Preston-Werner",
32+
"dob": "1979-05-27T07:32:00-08:00"
33+
}
34+
}
35+
36+
toml_file_path = self._create_temp_toml_file(toml_content)
37+
38+
with patch('sys.stdout', new=io.StringIO()) as mock_stdout:
39+
with patch('sys.argv', ['toml2json.py', toml_file_path]):
40+
toml2json.main()
41+
actual_json = json.loads(mock_stdout.getvalue())
42+
self.assertEqual(actual_json, expected_json)
43+
44+
def test_invalid_toml(self):
45+
toml_content = b"""
46+
[owner
47+
name = "Tom Preston-Werner"
48+
"""
49+
50+
toml_file_path = self._create_temp_toml_file(toml_content)
51+
52+
with patch('sys.stderr', new=io.StringIO()) as mock_stderr:
53+
with patch('sys.stdout', new=io.StringIO()): # We don't expect stdout for errors
54+
with patch('sys.exit') as mock_exit:
55+
with patch('sys.argv', ['toml2json.py', toml_file_path]):
56+
toml2json.main()
57+
mock_exit.assert_called_with(1)
58+
self.assertIn("Error decoding TOML", mock_stderr.getvalue())
59+
60+
61+
if __name__ == '__main__':
62+
unittest.main()
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
load("@rules_python//python:defs.bzl", "py_binary")
2+
3+
exports_files(["toml2json.py"])
4+
5+
py_binary(
6+
name = "toml2json",
7+
srcs = ["toml2json.py"],
8+
visibility = ["//visibility:public"],
9+
)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import json
2+
import sys
3+
import datetime
4+
5+
try:
6+
import tomllib
7+
except ImportError:
8+
try:
9+
import tomli as tomllib
10+
except ImportError:
11+
print("Error: need tomllib (python >=3.11) or tomli installed on host python", file=sys.stderr)
12+
sys.exit(1)
13+
14+
15+
def json_serializer(obj):
16+
if isinstance(obj, datetime.datetime):
17+
return obj.isoformat()
18+
raise TypeError(f"Object of type {type(obj).__name__} is not JSON serializable")
19+
20+
21+
def main():
22+
if len(sys.argv) < 2:
23+
print("Usage: toml2json <toml_file>", file=sys.stderr)
24+
sys.exit(1)
25+
26+
toml_file_path = sys.argv[1]
27+
28+
try:
29+
with open(toml_file_path, "rb") as f:
30+
data = tomllib.load(f)
31+
json.dump(data, sys.stdout, indent=2, default=json_serializer)
32+
print()
33+
except FileNotFoundError:
34+
print(f"Error: File not found: {toml_file_path}", file=sys.stderr)
35+
sys.exit(1)
36+
except tomllib.TOMLDecodeError as e:
37+
print(f"Error decoding TOML: {e}", file=sys.stderr)
38+
sys.exit(1)
39+
40+
41+
if __name__ == "__main__":
42+
main()

0 commit comments

Comments
 (0)