Files
Das-OS/srcpkgs/publisher/files/python/publisher/detect.py
T
dasandClaude Sonnet 5.5 62b8b98086 Fix pale Wi-Fi/Bluetooth tray icons, das-panel-icon help, publisher and deployer (0.9.5)
- Light theme uses Papirus-Light: the panel icons of Papirus are #dfdfdf,
  made for dark panels (xsettings, theme index, login screen).
- das-panel-icon help/-h/--help print usage instead of setting an icon;
  unknown options are rejected.
- New packages publisher (publish) and deployer (deploy) on the desktop
  image: config in ~/.config/<name>/ (neutral example copied on first run),
  history in ~/.local/state/<name>/.
- das-theme 0.3.0, das-settings 0.6.0.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 14:44:36 +02:00

82 lines
3.1 KiB
Python

"""Guess an [[app]] block for a local project: Android (+ electron desktop), Go, or any dir with builds."""
from __future__ import annotations
import os
import re
from pathlib import Path
from . import packages
from .config import App
_ROOT_NAME = re.compile(r"""rootProject\.name\s*=\s*["']([^"']+)["']""")
_GO_VERSION = re.compile(r'Version\s*=\s*"')
def _rel(p: Path, base: Path) -> str:
return str(p.relative_to(base))
def _home(p: Path) -> str:
home = Path.home()
return "~/" + str(p.relative_to(home)) if p.is_relative_to(home) else str(p)
def _site_name(raw: str) -> str:
"""A name apps.jsp groups correctly: no spaces, no _<digit>."""
name = re.sub(r"[^A-Za-z0-9_.\-]+", "", raw)
return re.sub(r"[_-]v?(?=\d)", "", name) or "App"
def _name_from_builds(files: list[Path]) -> str:
for f in files:
m = packages.LOCAL_VERSION.search(f.name)
if m and m.start() > 0:
return f.name[:m.start()]
return ""
def _first(base: Path, *names: str) -> Path | None:
for n in names:
if (base / n).is_file():
return base / n
return None
def new_app(path: Path, name: str | None = None) -> App:
path = path.expanduser().resolve()
# no build command is guessed: Android Studio signs into app/release, gradle into app/build/outputs
globs, builds, version_file = [], [], ""
gradle = _first(path, "app/build.gradle.kts", "app/build.gradle")
if gradle:
version_file = _rel(gradle, path)
# both places of a signed release APK: the best build of the two is published
for d in ("app/release", "app/build/outputs/apk/release"):
globs.append(f"{d}/*.apk")
builds += sorted((path / d).glob("*.apk"))
dist = path / "desktop/dist"
if dist.is_dir():
for ext in (".AppImage", ".deb", ".rpm", ".exe", ".msi", ".dmg"):
if any(dist.glob(f"*{ext}")):
globs.append(f"desktop/dist/*{ext}")
else:
go_version = next((p for p in path.glob("internal/version/*.go")
if _GO_VERSION.search(p.read_text(errors="replace"))), None)
if go_version:
version_file = _rel(go_version, path)
elif (path / "pyproject.toml").is_file():
version_file = "pyproject.toml"
for d in ("build", "dist", "bin", "release"):
for f in sorted((path / d).glob("*")) if (path / d).is_dir() else []:
if f.is_file() and packages.kind_of(f.name, os.access(f, os.X_OK)):
builds.append(f)
k = packages.kind_of(f.name)
globs.append(f"{d}/*{k.ext}" if k and k.ext else f"{d}/{f.name}")
globs = list(dict.fromkeys(globs))
if not name:
settings = _first(path, "settings.gradle.kts", "settings.gradle")
m = _ROOT_NAME.search(settings.read_text(errors="replace")) if settings else None
name = _name_from_builds(builds) or (m.group(1) if m else "") or path.name
return App(name=_site_name(name), src=_home(path), packages=globs, version_file=version_file)