Browse Source

feat: add `black` formatter

dev
Dnomd343 4 weeks ago
parent
commit
e2c3be25a2
  1. 16
      pyproject.toml
  2. 56
      src/syncplay_boot/boot.py
  3. 30
      tests/test_convert.py
  4. 65
      uv.lock

16
pyproject.toml

@ -21,6 +21,7 @@ dependencies = [
[dependency-groups]
dev = [
"black>=25.1.0",
"pyright>=1.1.400",
"pytest>=8.3.5",
"ruff>=0.11.10",
@ -28,19 +29,28 @@ dev = [
]
[tool.uv.sources]
syncplay = { path = "./src/syncplay/" }
syncplay = { path = "src/syncplay" }
[tool.ruff]
line-length = 120
target-version = "py312"
lint.select = ["E", "F", "B", "N", "W"]
lint.ignore = ["E701"]
exclude = ["src/syncplay"]
[tool.black]
line-length = 120
target-version = ["py312"]
skip-string-normalization = true
include = "(src/syncplay_boot|tests)"
[tool.pyright]
pythonVersion = "3.12"
typeCheckingMode = "basic"
pythonPlatform = "All"
include = ["src"]
include = [
"src/syncplay_boot",
"tests",
]
[tool.hatch.version]
path = "src/syncplay/syncplay/__init__.py"

56
src/syncplay_boot/boot.py

@ -101,13 +101,17 @@ CFG_OPTS: dict[str, tuple[type, bool]] = {} # for loading configure file
def debug_msg(prefix: str, message: Any) -> None:
""" Output debug message. """
"""
Output debug message.
"""
if os.environ.get('DEBUG', '').upper() in ['ON', 'TRUE']:
print(f'\033[33m{prefix}\033[0m -> \033[90m{message}\033[0m', file=sys.stderr)
def init_opts() -> None:
""" Build syncplay formatting options. """
"""
Build syncplay formatting options.
"""
for name, field in SyncplayOptions.__annotations__.items():
field_t, is_list = field.__args__[0], False
if type(field_t) is GenericAlias:
@ -131,7 +135,9 @@ def init_opts() -> None:
def load_from_env() -> SyncplayOptions:
""" Load syncplay options from environment variables. """
"""
Load syncplay options from environment variables.
"""
options: SyncplayOptions = {}
for name, field_t in ENV_OPTS.items():
if name.upper() in os.environ:
@ -148,21 +154,30 @@ def load_from_env() -> SyncplayOptions:
def load_from_args() -> SyncplayOptions:
""" Load syncplay options from command line arguments. """
"""
Load syncplay options from command line arguments.
"""
def __version_msg() -> str:
python_ver = f'{platform.python_implementation()} {platform.python_version()}'
return (f'{parser.description} v{syncplay.version} '
f'({syncplay.milestone} {syncplay.release_number}) '
f'[{python_ver} {platform.machine()}]')
return (
f'{parser.description} v{syncplay.version} '
f'({syncplay.milestone} {syncplay.release_number}) '
f'[{python_ver} {platform.machine()}]'
)
def __build_args(opt: str) -> list[str]:
match opt := opt.replace('_', '-'):
case 'config': return ['-c', f'--{opt}']
case 'port': return ['-p', f'--{opt}']
case 'motd': return ['-m', f'--{opt}']
case 'password': return ['-k', f'--{opt}']
case _: return [f'--{opt}']
case 'config':
return ['-c', f'--{opt}']
case 'port':
return ['-p', f'--{opt}']
case 'motd':
return ['-m', f'--{opt}']
case 'password':
return ['-k', f'--{opt}']
case _:
return [f'--{opt}']
parser = argparse.ArgumentParser(description='Syncplay Docker Bootstrap')
parser.add_argument('-v', '--version', action='version', version=__version_msg())
@ -181,7 +196,9 @@ def load_from_args() -> SyncplayOptions:
def load_from_config(path: str) -> SyncplayOptions:
""" Load syncplay options from configure file. """
"""
Load syncplay options from configure file.
"""
def __load_file() -> dict[str, Any]:
if not os.path.exists(path):
@ -211,7 +228,9 @@ def load_from_config(path: str) -> SyncplayOptions:
def load_opts() -> SyncplayOptions:
""" Combine syncplay options from multiple source. """
"""
Combine syncplay options from multiple source.
"""
env_opts = load_from_env()
cli_opts = load_from_args()
cfg_opts = load_from_config((env_opts | cli_opts).get('config', 'config.yml'))
@ -229,10 +248,14 @@ def load_opts() -> SyncplayOptions:
def sp_convert(opts: SyncplayOptions) -> list[str]:
""" Construct the startup arguments for syncplay server. """
"""
Construct the startup arguments for syncplay server.
"""
def __temp_file(file: str, content: str) -> str:
""" Create and save content to temporary files. """
"""
Create and save content to temporary files.
"""
file = os.path.join(temp_dir, file)
with open(file, 'w', encoding='utf-8') as fp:
fp.write(content)
@ -288,6 +311,7 @@ def bootstrap(opts: SyncplayOptions | None = None) -> None:
debug_msg('Syncplay startup arguments', sys.argv)
from syncplay import ep_server
sys.exit(ep_server.main())

30
tests/test_convert.py

@ -35,12 +35,12 @@ def convert_builder(keep_port: bool = False, keep_salt: bool = False) -> Callabl
if not keep_port:
if '--port' in output and '8999' in output:
if (index := output.index('--port')) + 1 == output.index('8999'):
output = output[:index] + output[index + 2:]
output = output[:index] + output[index + 2 :]
if not keep_salt:
if '--salt' in output and '' in output:
if (index := output.index('--salt')) + 1 == output.index(''):
output = output[:index] + output[index + 2:]
output = output[:index] + output[index + 2 :]
return output
@ -96,9 +96,9 @@ def test_boolean_flags() -> None:
Test boolean flags handling of options conversion.
"""
convert = convert_builder()
assert convert({'isolate_rooms': True}) == [f'--isolate-rooms']
assert convert({'disable_chat': True}) == [f'--disable-chat']
assert convert({'disable_ready': True}) == [f'--disable-ready']
assert convert({'isolate_rooms': True}) == ['--isolate-rooms']
assert convert({'disable_chat': True}) == ['--disable-chat']
assert convert({'disable_ready': True}) == ['--disable-ready']
assert convert({'enable_stats': True}) == ['--stats-db-file', '/data/stats.db']
assert convert({'enable_tls': True}) == ['--tls', '/certs/']
@ -132,8 +132,12 @@ def test_ip_configure() -> None:
convert = convert_builder()
assert convert({}) == []
assert convert({'listen_ipv4': '0.0.0.0'}) == ['--ipv4-only', '--interface-ipv4', '0.0.0.0']
assert convert({'listen_ipv6': '::'}) == ['--ipv6-only', '--interface-ipv6', '::']
assert convert({'listen_ipv4': '0.0.0.0', 'listen_ipv6': '::'}) == ['--interface-ipv4', '0.0.0.0', '--interface-ipv6', '::']
assert convert({'listen_ipv6': 'fc00::1'}) == ['--ipv6-only', '--interface-ipv6', 'fc00::1']
# fmt: off
assert convert({'listen_ipv4': '0.0.0.0', 'listen_ipv6': 'fc00::1'}) == [
'--interface-ipv4', '0.0.0.0',
'--interface-ipv6', 'fc00::1',
] # fmt: on
def test_path_env(temp_dir_setup) -> None:
@ -157,7 +161,7 @@ def test_full_options() -> None:
Test full options conversion.
"""
convert = convert_builder(keep_port=True, keep_salt=True)
options = convert({
opts: boot.SyncplayOptions = {
'port': 12345,
'password': 'secret',
'motd': 'Welcome to Syncplay',
@ -173,9 +177,9 @@ def test_full_options() -> None:
'max_chat_message': 500,
'permanent_rooms': ['room1', 'room2', 'room3'],
'listen_ipv4': '0.0.0.0',
'listen_ipv6': '::'
})
'listen_ipv6': '::',
}
# fmt: off
expected = [
'--port', '12345',
'--password', 'secret',
@ -192,6 +196,6 @@ def test_full_options() -> None:
'--permanent-rooms-file', '/tmp/rooms.list',
'--interface-ipv4', '0.0.0.0',
'--interface-ipv6', '::'
]
] # fmt: on
assert options == expected
assert convert(opts) == expected

65
uv.lock

@ -29,6 +29,30 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/02/ff/1175b0b7371e46244032d43a56862d0af455823b5280a50c63d99cc50f18/automat-25.4.16-py3-none-any.whl", hash = "sha256:04e9bce696a8d5671ee698005af6e5a9fa15354140a87f4870744604dcdd3ba1", size = 42842, upload-time = "2025-04-16T20:12:14.447Z" },
]
[[package]]
name = "black"
version = "25.1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "click" },
{ name = "mypy-extensions" },
{ name = "packaging" },
{ name = "pathspec" },
{ name = "platformdirs" },
]
sdist = { url = "https://files.pythonhosted.org/packages/94/49/26a7b0f3f35da4b5a65f081943b7bcd22d7002f5f0fb8098ec1ff21cb6ef/black-25.1.0.tar.gz", hash = "sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666", size = 649449, upload-time = "2025-01-29T04:15:40.373Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/83/71/3fe4741df7adf015ad8dfa082dd36c94ca86bb21f25608eb247b4afb15b2/black-25.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4b60580e829091e6f9238c848ea6750efed72140b91b048770b64e74fe04908b", size = 1650988, upload-time = "2025-01-29T05:37:16.707Z" },
{ url = "https://files.pythonhosted.org/packages/13/f3/89aac8a83d73937ccd39bbe8fc6ac8860c11cfa0af5b1c96d081facac844/black-25.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e2978f6df243b155ef5fa7e558a43037c3079093ed5d10fd84c43900f2d8ecc", size = 1453985, upload-time = "2025-01-29T05:37:18.273Z" },
{ url = "https://files.pythonhosted.org/packages/6f/22/b99efca33f1f3a1d2552c714b1e1b5ae92efac6c43e790ad539a163d1754/black-25.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b48735872ec535027d979e8dcb20bf4f70b5ac75a8ea99f127c106a7d7aba9f", size = 1783816, upload-time = "2025-01-29T04:18:33.823Z" },
{ url = "https://files.pythonhosted.org/packages/18/7e/a27c3ad3822b6f2e0e00d63d58ff6299a99a5b3aee69fa77cd4b0076b261/black-25.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:ea0213189960bda9cf99be5b8c8ce66bb054af5e9e861249cd23471bd7b0b3ba", size = 1440860, upload-time = "2025-01-29T04:19:12.944Z" },
{ url = "https://files.pythonhosted.org/packages/98/87/0edf98916640efa5d0696e1abb0a8357b52e69e82322628f25bf14d263d1/black-25.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f", size = 1650673, upload-time = "2025-01-29T05:37:20.574Z" },
{ url = "https://files.pythonhosted.org/packages/52/e5/f7bf17207cf87fa6e9b676576749c6b6ed0d70f179a3d812c997870291c3/black-25.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3", size = 1453190, upload-time = "2025-01-29T05:37:22.106Z" },
{ url = "https://files.pythonhosted.org/packages/e3/ee/adda3d46d4a9120772fae6de454c8495603c37c4c3b9c60f25b1ab6401fe/black-25.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171", size = 1782926, upload-time = "2025-01-29T04:18:58.564Z" },
{ url = "https://files.pythonhosted.org/packages/cc/64/94eb5f45dcb997d2082f097a3944cfc7fe87e071907f677e80788a2d7b7a/black-25.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:a22f402b410566e2d1c950708c77ebf5ebd5d0d88a6a2e87c86d9fb48afa0d18", size = 1442613, upload-time = "2025-01-29T04:19:27.63Z" },
{ url = "https://files.pythonhosted.org/packages/09/71/54e999902aed72baf26bca0d50781b01838251a462612966e9fc4891eadd/black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717", size = 207646, upload-time = "2025-01-29T04:15:38.082Z" },
]
[[package]]
name = "certifi"
version = "2025.4.26"
@ -71,6 +95,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" },
]
[[package]]
name = "click"
version = "8.2.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" },
]
[[package]]
name = "colorama"
version = "0.4.6"
@ -166,6 +202,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" },
]
[[package]]
name = "mypy-extensions"
version = "1.1.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" },
]
[[package]]
name = "nodeenv"
version = "1.9.1"
@ -184,6 +229,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" },
]
[[package]]
name = "pathspec"
version = "0.12.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" },
]
[[package]]
name = "pem"
version = "23.1.0"
@ -193,6 +247,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/c9/97/8299a481ae6c08494b5d53511e6a4746775d8a354c685c69d8796b2ed482/pem-23.1.0-py3-none-any.whl", hash = "sha256:78bbb1e75b737891350cb9499cbba31da5d59545f360f44163c0bc751cad55d3", size = 9195, upload-time = "2023-06-21T10:24:39.164Z" },
]
[[package]]
name = "platformdirs"
version = "4.3.8"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362, upload-time = "2025-05-07T22:47:42.121Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567, upload-time = "2025-05-07T22:47:40.376Z" },
]
[[package]]
name = "pluggy"
version = "1.6.0"
@ -406,6 +469,7 @@ dependencies = [
[package.dev-dependencies]
dev = [
{ name = "black" },
{ name = "pyright" },
{ name = "pytest" },
{ name = "ruff" },
@ -420,6 +484,7 @@ requires-dist = [
[package.metadata.requires-dev]
dev = [
{ name = "black", specifier = ">=25.1.0" },
{ name = "pyright", specifier = ">=1.1.400" },
{ name = "pytest", specifier = ">=8.3.5" },
{ name = "ruff", specifier = ">=0.11.10" },

Loading…
Cancel
Save