|
"""Sync `.env` with `pyproject.toml`. |
|
|
|
Parameters |
|
---------- |
|
tool_name: str |
|
Tool table name in `pyproject.toml` |
|
env_name: str = "env" |
|
Table name for environment variables in `pyproject.toml`. |
|
setenv: bool = False |
|
Also set environment variables in the interpreter session. |
|
env: Path = Path(".env") |
|
Path to environment file. |
|
pyproject: Path = Path("pyproject.toml") |
|
Path to `pyproject.toml`. |
|
write: bool = True |
|
Write to the environment file. |
|
|
|
Examples |
|
-------- |
|
|
|
Download this script to your project directory containing a `pyproject.toml` with a |
|
table named `tool.my_tool.env` and use `uv` run this tool in an isolated environment: |
|
|
|
uv run env.py |
|
|
|
You can install `uv` on Windows, |
|
|
|
Invoke-RestMethod 'https://astral.sh/uv/install.ps1' | Invoke-Expression |
|
|
|
or on macOS and Linux, |
|
|
|
curl -LsSf https://astral.sh/uv/install.sh | sh |
|
|
|
Notes |
|
----- |
|
|
|
Copyright (c) 2024 Blake Naccarato |
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
of this software and associated documentation files (the "Software"), to deal |
|
in the Software without restriction, including without limitation the rights |
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
copies of the Software, and to permit persons to whom the Software is |
|
furnished to do so, subject to the following conditions: |
|
|
|
The above copyright notice and this permission notice shall be included in all |
|
copies or substantial portions of the Software. |
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
SOFTWARE. |
|
""" |
|
# /// script |
|
# requires-python = ">3.10, <3.12" |
|
# dependencies = [ "cappa==0.22.5", "python-dotenv==1.0.1" ] |
|
# /// |
|
|
|
from __future__ import annotations |
|
|
|
from io import StringIO |
|
from pathlib import Path |
|
|
|
from cappa.base import command, invoke |
|
from cappa.output import Output |
|
from dotenv import dotenv_values, load_dotenv |
|
from tomllib import loads |
|
|
|
|
|
def main(args: SyncEnvVars, out: Output): |
|
"""Sync `.env` with `pyproject.toml`.""" |
|
if not args.pyproject.exists(): |
|
args.pyproject.write_text(f"[tool.{args.tool_name}.env]\n", encoding="utf-8") |
|
config_env = loads(args.pyproject.read_text(encoding="utf-8")) |
|
for key in ("tool", args.tool_name, args.env_name): |
|
if key not in config_env: |
|
raise KeyError(f"Key {key!r} not found in {args.pyproject}") |
|
config_env = config_env[key] |
|
dotenv = dotenv_values(args.env) |
|
keys_set: list[str] = [] |
|
for key in dotenv: |
|
if override := config_env.get(key): |
|
keys_set.append(key) |
|
dotenv[key] = override |
|
for k, v in config_env.items(): |
|
if k not in keys_set: |
|
dotenv[k] = v |
|
env = "\n".join(f"{k}={v}" for k, v in dotenv.items()) |
|
if args.setenv: |
|
load_dotenv(stream=StringIO(env)) |
|
if args.write: |
|
Path(args.env).write_text(env, encoding="utf-8") |
|
elif env: |
|
out.output(env) |
|
|
|
|
|
@command(invoke=main) |
|
class SyncEnvVars: |
|
"""Sync `.env` with `pyproject.toml`.""" |
|
|
|
tool_name: str = "dev" |
|
"""Tool table name in `pyproject.toml`.""" |
|
env_name: str = "env" |
|
"""Table name for environment variables in `pyproject.toml`.""" |
|
setenv: bool = False |
|
"""Also set environment variables in the interpreter session.""" |
|
env: Path = Path(".env") |
|
"""Path to environment file.""" |
|
pyproject: Path = Path("pyproject.toml") |
|
"""Path to `pyproject.toml`.""" |
|
write: bool = True |
|
"""Write to the environment file.""" |
|
|
|
|
|
if __name__ == "__main__": |
|
invoke(SyncEnvVars) |