Initialisiere VoTiAn NG mit Docker-Build, .env-Konfiguration und Cookie-Sitzungen
This commit is contained in:
commit
1a30233269
63 files changed
+12138
No files matched your search
@@ -0,0 +1,91 @@
|
||||
"""Read local environment configuration without evaluating its contents."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
_ASSIGNMENT = re.compile(r"(?:export[ \t]+)?([A-Za-z_][A-Za-z0-9_]*)=(.*)")
|
||||
|
||||
|
||||
def load_environment(path: Path, current: dict[str, str]) -> dict[str, str]:
|
||||
"""Merge a local .env file with the current environment, which takes priority.
|
||||
|
||||
Values are literal: shell commands, variable references, backslashes and
|
||||
inline ``#`` characters are never interpreted. Optional surrounding quotes
|
||||
are removed, without interpreting escapes. Keep the project's .env values
|
||||
unquoted (and omit ``export``) for compatibility with Docker ``--env-file``.
|
||||
"""
|
||||
try:
|
||||
contents = path.read_bytes()
|
||||
except FileNotFoundError:
|
||||
return dict(current)
|
||||
|
||||
values: dict[str, str] = {}
|
||||
for line_number, raw_line in enumerate(contents.split(b"\n"), start=1):
|
||||
# Accept both LF and CRLF, but not embedded line breaks in a value.
|
||||
raw_line = raw_line.removesuffix(b"\r")
|
||||
try:
|
||||
line = raw_line.decode("utf-8")
|
||||
except UnicodeDecodeError:
|
||||
raise ValueError(f"Invalid .env syntax at line {line_number}") from None
|
||||
|
||||
if "\x00" in line or "\r" in line:
|
||||
raise ValueError(f"Invalid .env syntax at line {line_number}")
|
||||
line = line.lstrip(" \t")
|
||||
if not line or line.startswith("#"):
|
||||
continue
|
||||
match = _ASSIGNMENT.fullmatch(line)
|
||||
if match is None:
|
||||
raise ValueError(f"Invalid .env syntax at line {line_number}")
|
||||
|
||||
key, value = match.groups()
|
||||
if value.startswith(("'", '"')):
|
||||
quoted_value = value.rstrip(" \t")
|
||||
if len(quoted_value) < 2 or quoted_value[-1] != quoted_value[0]:
|
||||
raise ValueError(f"Invalid .env syntax at line {line_number}")
|
||||
value = quoted_value[1:-1]
|
||||
values[key] = value
|
||||
|
||||
values.update(current)
|
||||
return values
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
"""Run a command with the project's .env, retaining the caller's directory."""
|
||||
command = sys.argv[1:] if argv is None else argv
|
||||
if not command or command[0] in ("-h", "--help"):
|
||||
print(
|
||||
"Usage: python3 scripts/env_config.py COMMAND [ARGS...]\n"
|
||||
"Run COMMAND with the project .env; existing environment variables take priority.\n"
|
||||
"The working directory is preserved. From backend, for example:\n"
|
||||
" python3 ../scripts/env_config.py ./mvnw test",
|
||||
file=sys.stderr if not command else sys.stdout,
|
||||
)
|
||||
return 2 if not command else 0
|
||||
|
||||
try:
|
||||
environment = load_environment(Path(__file__).resolve().parents[1] / ".env", dict(os.environ))
|
||||
except ValueError as error:
|
||||
message = str(error)
|
||||
if re.fullmatch(r"Invalid \.env syntax at line [0-9]+", message) is None:
|
||||
message = "Invalid .env syntax."
|
||||
print(message, file=sys.stderr)
|
||||
return 1
|
||||
except OSError:
|
||||
print("Unable to read .env.", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
try:
|
||||
os.execvpe(command[0], command, environment)
|
||||
except OSError:
|
||||
print("Unable to start command.", file=sys.stderr)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in new issue
Block a user