feat[config]: Use toml for configs

This commit is contained in:
2026-06-27 22:44:25 +03:00
parent fd88aabe46
commit 28f1fda048
5 changed files with 42 additions and 42 deletions
+3 -11
View File
@@ -31,15 +31,7 @@ It is slightly ancient solution for modern Docker/Kubernetes backends,
but provides configuration in one place and _secure enough_ place to save token.
Example config:
```ini
[main]
endpoint=https://example.com
token=XXXXX
format={owner}/{name}
out_dir=/home/user/repositories
ssh_key=/home/user/id_rsa
```
Example config is available in [config.example.toml](config.example.toml).
### Native
@@ -50,9 +42,9 @@ removing the ability to specify a user
2. Install dependencies (`pip3 install -r requirements.txt`).
Venv-level is recommended.
3. Install git (`sudo apt install git`)
4. And run it with path to ini config.
4. And run it with path to TOML config.
```bash
python gitea-mirror.py config.ini
python gitea-mirror.py config.toml
```
+6
View File
@@ -0,0 +1,6 @@
[main]
endpoint = "https://example.com"
token = "XXXXX"
format = "{owner}/{name}"
out_dir = "/home/user/repositories"
ssh_key = "/home/user/id_rsa"
+2 -2
View File
@@ -2,7 +2,7 @@ import os.path
import sys
from os import makedirs
from src.config import Config, read_ini_config
from src.config import Config, read_toml_config
from src.git import git_clone, git_pull
from src.gitea_api import GiteaApi
from src.models import GiteaRepository
@@ -28,7 +28,7 @@ def main():
print("Usage: python gitea-mirror.py CONFIG_PATH")
sys.exit(1)
try:
config = read_ini_config(sys.argv[1])
config = read_toml_config(sys.argv[1])
except RuntimeError as err:
print(f"Invalid config: {err}")
sys.exit(1)
+19 -18
View File
@@ -2,38 +2,39 @@
Token should be treated as password,
files are more secure in general than command-line arguments
.ini config example
TOML config example
[main]
endpoint=https://example.com/gitea
token=something
format={owner}/{name}
out_dir=/home/user/repositories
ssh_key=/home/user/.ssh/id_rsa.pub
endpoint = "https://example.com/gitea"
token = "something"
format = "{owner}/{name}"
out_dir = "/home/user/repositories"
ssh_key = "/home/user/.ssh/id_rsa.pub"
"""
import configparser
import os
import tomllib
from .models import Config
MAIN_SECTION = "main"
def read_ini_config(path: str) -> Config:
def read_toml_config(path: str) -> Config:
if not os.path.exists(path):
raise RuntimeError("INI config path is not exists")
raise RuntimeError("TOML config path does not exist")
parser = configparser.ConfigParser()
parser.read(path)
try:
endpoint = parser[MAIN_SECTION]["endpoint"]
token = parser[MAIN_SECTION]["token"]
repository_format = parser[MAIN_SECTION]["format"]
out_dir = parser[MAIN_SECTION]["out_dir"]
ssh_key_path = parser[MAIN_SECTION]["ssh_key"]
except KeyError as err:
raise RuntimeError(f"No value for section: {err}")
with open(path, "rb") as config_file:
data = tomllib.load(config_file)
main = data[MAIN_SECTION]
endpoint = main["endpoint"]
token = main["token"]
repository_format = main["format"]
out_dir = main["out_dir"]
ssh_key_path = main["ssh_key"]
except (KeyError, tomllib.TOMLDecodeError) as err:
raise RuntimeError(f"Invalid TOML config: {err}") from err
return Config(
repository_format=repository_format,
+12 -11
View File
@@ -2,18 +2,18 @@ from tempfile import NamedTemporaryFile
import pytest
from src.config import Config, read_ini_config
from src.config import Config, read_toml_config
@pytest.mark.parametrize(
"config_data, expected",
[
(
"[main]\ntoken=something\n"
"format={owner}/{name}\n"
"ssh_key=/tmp/no_key\n"
"endpoint=https://example.com\n"
"out_dir=/home/user/repositories",
'[main]\ntoken = "something"\n'
'format = "{owner}/{name}"\n'
'ssh_key = "/tmp/no_key"\n'
'endpoint = "https://example.com"\n'
'out_dir = "/home/user/repositories"',
Config(
token="something",
repository_format="{owner}/{name}",
@@ -23,20 +23,21 @@ from src.config import Config, read_ini_config
),
),
("[main]", None),
("not valid toml", None),
],
)
def test_ini_config(config_data, expected):
def test_toml_config(config_data, expected):
with NamedTemporaryFile() as tf:
if config_data:
tf.write(config_data.encode("utf-8"))
tf.flush()
if expected:
assert read_ini_config(tf.name) == expected
assert read_toml_config(tf.name) == expected
else:
with pytest.raises(RuntimeError):
read_ini_config(tf.name)
read_toml_config(tf.name)
def test_ini_config_not_exists():
def test_toml_config_not_exists():
with pytest.raises(RuntimeError):
read_ini_config("not_existing_file")
read_toml_config("not_existing_file")