Publish training skills collection
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Shared Gitea configuration helpers for issue scripts."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from urllib.parse import urlparse
|
||||
|
||||
|
||||
DEFAULT_ENV_FILE = Path("~/.config/gitea/gitea.env").expanduser()
|
||||
SECRETS_ENV_FILE = Path("~/.config/secrets/gitea.env").expanduser()
|
||||
LEGACY_ENV_FILE = Path("~/.config/gitea/data-analysis-agent.env").expanduser()
|
||||
REQUIRED_ENV = ("GITEA_BASE_URL", "GITEA_OWNER", "GITEA_REPO", "GITEA_TOKEN")
|
||||
|
||||
|
||||
def load_env_file(path: Path) -> dict[str, str]:
|
||||
values: dict[str, str] = {}
|
||||
if not path.exists():
|
||||
return values
|
||||
|
||||
for raw_line in path.read_text(encoding="utf-8").splitlines():
|
||||
line = raw_line.strip()
|
||||
if not line or line.startswith("#"):
|
||||
continue
|
||||
if line.startswith("export "):
|
||||
line = line[len("export ") :]
|
||||
if "=" not in line:
|
||||
continue
|
||||
key, raw_value = line.split("=", 1)
|
||||
key = key.strip()
|
||||
try:
|
||||
parsed = shlex.split(raw_value.strip(), comments=False, posix=True)
|
||||
except ValueError as exc:
|
||||
raise SystemExit(f"Could not parse {path}: {exc}") from exc
|
||||
values[key] = parsed[0] if parsed else ""
|
||||
return values
|
||||
|
||||
|
||||
def discover_origin_config() -> dict[str, str]:
|
||||
try:
|
||||
remote = subprocess.run(
|
||||
["git", "remote", "get-url", "origin"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
).stdout.strip()
|
||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||
return {}
|
||||
|
||||
if not remote:
|
||||
return {}
|
||||
|
||||
parsed = urlparse(remote)
|
||||
host = ""
|
||||
path = ""
|
||||
if parsed.scheme in {"http", "https", "ssh"} and parsed.netloc:
|
||||
host = parsed.hostname or parsed.netloc.split("@")[-1].split(":")[0]
|
||||
path = parsed.path.lstrip("/")
|
||||
else:
|
||||
match = re.match(r"(?:(?P<user>[^@]+)@)?(?P<host>[^:]+):(?P<path>.+)$", remote)
|
||||
if match:
|
||||
host = match.group("host")
|
||||
path = match.group("path")
|
||||
|
||||
if not host or not path:
|
||||
return {}
|
||||
|
||||
if path.endswith(".git"):
|
||||
path = path[:-4]
|
||||
parts = [part for part in path.split("/") if part]
|
||||
if len(parts) < 2:
|
||||
return {}
|
||||
|
||||
return {
|
||||
"GITEA_BASE_URL": f"https://{host}",
|
||||
"GITEA_OWNER": parts[-2],
|
||||
"GITEA_REPO": parts[-1],
|
||||
}
|
||||
|
||||
|
||||
def config(env_file: Path | None = None) -> dict[str, str]:
|
||||
env_path = (env_file or DEFAULT_ENV_FILE).expanduser()
|
||||
file_values = load_env_file(env_path)
|
||||
if env_path == DEFAULT_ENV_FILE:
|
||||
secrets_values = load_env_file(SECRETS_ENV_FILE)
|
||||
legacy_values = load_env_file(LEGACY_ENV_FILE)
|
||||
file_values = {**legacy_values, **secrets_values, **file_values}
|
||||
|
||||
origin_values = discover_origin_config()
|
||||
base_url = (
|
||||
os.environ.get("GITEA_BASE_URL")
|
||||
or os.environ.get("GITEA_URL")
|
||||
or origin_values.get("GITEA_BASE_URL")
|
||||
or file_values.get("GITEA_BASE_URL")
|
||||
or file_values.get("GITEA_URL", "")
|
||||
)
|
||||
values = {
|
||||
"GITEA_BASE_URL": base_url,
|
||||
"GITEA_OWNER": os.environ.get("GITEA_OWNER")
|
||||
or origin_values.get("GITEA_OWNER")
|
||||
or file_values.get("GITEA_OWNER", ""),
|
||||
"GITEA_REPO": os.environ.get("GITEA_REPO")
|
||||
or origin_values.get("GITEA_REPO")
|
||||
or file_values.get("GITEA_REPO", ""),
|
||||
"GITEA_TOKEN": os.environ.get("GITEA_TOKEN") or file_values.get("GITEA_TOKEN", ""),
|
||||
}
|
||||
missing = [key for key, value in values.items() if not value]
|
||||
if missing:
|
||||
raise SystemExit(
|
||||
"Missing required Gitea configuration: "
|
||||
+ ", ".join(missing)
|
||||
+ f"\nSet them in the shell, {env_path}, {SECRETS_ENV_FILE}, "
|
||||
+ "or run from a git repo with a Gitea origin."
|
||||
)
|
||||
return values
|
||||
|
||||
|
||||
def auth_config(env_file: Path | None = None) -> dict[str, str]:
|
||||
"""Return Gitea API auth config without requiring a repository context."""
|
||||
env_path = (env_file or DEFAULT_ENV_FILE).expanduser()
|
||||
file_values = load_env_file(env_path)
|
||||
if env_path == DEFAULT_ENV_FILE:
|
||||
secrets_values = load_env_file(SECRETS_ENV_FILE)
|
||||
legacy_values = load_env_file(LEGACY_ENV_FILE)
|
||||
file_values = {**legacy_values, **secrets_values, **file_values}
|
||||
|
||||
origin_values = discover_origin_config()
|
||||
base_url = (
|
||||
os.environ.get("GITEA_BASE_URL")
|
||||
or os.environ.get("GITEA_URL")
|
||||
or origin_values.get("GITEA_BASE_URL")
|
||||
or file_values.get("GITEA_BASE_URL")
|
||||
or file_values.get("GITEA_URL", "")
|
||||
)
|
||||
values = {
|
||||
"GITEA_BASE_URL": base_url,
|
||||
"GITEA_OWNER": os.environ.get("GITEA_OWNER")
|
||||
or origin_values.get("GITEA_OWNER")
|
||||
or file_values.get("GITEA_OWNER", ""),
|
||||
"GITEA_TOKEN": os.environ.get("GITEA_TOKEN") or file_values.get("GITEA_TOKEN", ""),
|
||||
}
|
||||
missing = [key for key in ("GITEA_BASE_URL", "GITEA_TOKEN") if not values[key]]
|
||||
if missing:
|
||||
raise SystemExit(
|
||||
"Missing required Gitea configuration: "
|
||||
+ ", ".join(missing)
|
||||
+ f"\nSet them in the shell, {env_path}, {SECRETS_ENV_FILE}, "
|
||||
+ "or run from a git repo with a Gitea origin."
|
||||
)
|
||||
return values
|
||||
Reference in New Issue
Block a user