utils: add source_info utility module

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Eric Callahan 2023-02-09 19:33:03 -05:00
parent 277aecd305
commit 79467e6484
No known key found for this signature in database
GPG Key ID: 5A1EB336DFB4C71B
5 changed files with 108 additions and 25 deletions

View File

@ -18,7 +18,7 @@ import time
from copy import deepcopy from copy import deepcopy
from inotify_simple import INotify from inotify_simple import INotify
from inotify_simple import flags as iFlags from inotify_simple import flags as iFlags
from ...utils import MOONRAKER_PATH from ...utils import source_info
# Annotation imports # Annotation imports
from typing import ( from typing import (
@ -70,7 +70,8 @@ class FileManager:
self.file_paths: Dict[str, str] = {} self.file_paths: Dict[str, str] = {}
app_args = self.server.get_app_args() app_args = self.server.get_app_args()
self.datapath = pathlib.Path(app_args["data_path"]) self.datapath = pathlib.Path(app_args["data_path"])
self.add_reserved_path("moonraker", MOONRAKER_PATH, False) srcdir = str(source_info.source_path())
self.add_reserved_path("moonraker", srcdir, False)
db: DBComp = self.server.load_component(config, "database") db: DBComp = self.server.load_component(config, "database")
db_path = db.get_database_path() db_path = db.get_database_path()
self.add_reserved_path("database", db_path, False) self.add_reserved_path("database", db_path, False)

View File

@ -22,7 +22,7 @@ import tempfile
import getpass import getpass
import configparser import configparser
from ..confighelper import FileSourceWrapper from ..confighelper import FileSourceWrapper
from ..utils import MOONRAKER_PATH from ..utils import source_info
# Annotation imports # Annotation imports
from typing import ( from typing import (
@ -1656,7 +1656,7 @@ class InstallValidator:
tmp_svc = pathlib.Path( tmp_svc = pathlib.Path(
tempfile.gettempdir() tempfile.gettempdir()
).joinpath(f"{unit}-tmp.svc") ).joinpath(f"{unit}-tmp.svc")
src_path = pathlib.Path(MOONRAKER_PATH) src_path = source_info.source_path()
# Create local environment file # Create local environment file
sysd_data = self.data_path.joinpath("systemd") sysd_data = self.data_path.joinpath("systemd")
if not sysd_data.exists(): if not sysd_data.exists():

View File

@ -8,7 +8,7 @@ from __future__ import annotations
import os import os
import sys import sys
import copy import copy
from ...utils import MOONRAKER_PATH from ...utils import source_info
from typing import ( from typing import (
TYPE_CHECKING, TYPE_CHECKING,
Dict Dict
@ -29,7 +29,7 @@ BASE_CONFIG: Dict[str, Dict[str, str]] = {
"install_script": "scripts/install-moonraker.sh", "install_script": "scripts/install-moonraker.sh",
"host_repo": "arksine/moonraker", "host_repo": "arksine/moonraker",
"env": sys.executable, "env": sys.executable,
"path": MOONRAKER_PATH, "path": str(source_info.source_path()),
"managed_services": "moonraker" "managed_services": "moonraker"
}, },
"klipper": { "klipper": {

View File

@ -19,6 +19,7 @@ import shlex
import re import re
import struct import struct
import socket import socket
from . import source_info
# Annotation imports # Annotation imports
from typing import ( from typing import (
@ -28,13 +29,13 @@ from typing import (
ClassVar, ClassVar,
Tuple, Tuple,
Dict, Dict,
Union
) )
if TYPE_CHECKING: if TYPE_CHECKING:
from types import ModuleType from types import ModuleType
from asyncio.trsock import TransportSocket from asyncio.trsock import TransportSocket
MOONRAKER_PATH = str(pathlib.Path(__file__).parent.parent.parent.resolve())
SYS_MOD_PATHS = glob.glob("/usr/lib/python3*/dist-packages") SYS_MOD_PATHS = glob.glob("/usr/lib/python3*/dist-packages")
SYS_MOD_PATHS += glob.glob("/usr/lib/python3*/site-packages") SYS_MOD_PATHS += glob.glob("/usr/lib/python3*/site-packages")
@ -87,20 +88,15 @@ def retrieve_git_version(source_path: str) -> str:
return f"t{tag}-g{ver}-shallow" return f"t{tag}-g{ver}-shallow"
def get_software_version() -> str: def get_software_version() -> str:
pkg_ver = source_info.package_version()
if pkg_ver is not None:
return pkg_ver
version: str = "?" version: str = "?"
src_path = source_info.source_path()
try: try:
import moonraker.__version__ as ver # type: ignore version = retrieve_git_version(str(src_path))
version = ver.__version__
except Exception: except Exception:
pass vfile = src_path.joinpath("moonraker/.version")
else:
if version:
return version
try:
version = retrieve_git_version(MOONRAKER_PATH)
except Exception:
vfile = pathlib.Path(os.path.join(
MOONRAKER_PATH, "moonraker/.version"))
if vfile.exists(): if vfile.exists():
try: try:
version = vfile.read_text().strip() version = vfile.read_text().strip()
@ -110,12 +106,15 @@ def get_software_version() -> str:
return version return version
def hash_directory(dir_path: str, def hash_directory(
ignore_exts: List[str], dir_path: Union[str, pathlib.Path],
ignore_dirs: List[str] ignore_exts: List[str],
) -> str: ignore_dirs: List[str]
) -> str:
if isinstance(dir_path, str):
dir_path = pathlib.Path(dir_path)
checksum = hashlib.blake2s() checksum = hashlib.blake2s()
if not os.path.exists(dir_path): if not dir_path.exists():
return "" return ""
for dpath, dnames, fnames in os.walk(dir_path): for dpath, dnames, fnames in os.walk(dir_path):
valid_dirs: List[str] = [] valid_dirs: List[str] = []
@ -135,8 +134,14 @@ def hash_directory(dir_path: str,
pass pass
return checksum.hexdigest() return checksum.hexdigest()
def verify_source(path: str = MOONRAKER_PATH) -> Optional[Tuple[str, bool]]: def verify_source(
rfile = pathlib.Path(os.path.join(path, ".release_info")) path: Optional[Union[str, pathlib.Path]] = None
) -> Optional[Tuple[str, bool]]:
if path is None:
path = source_info.source_path()
elif isinstance(path, str):
path = pathlib.Path(path)
rfile = path.joinpath(".release_info")
if not rfile.exists(): if not rfile.exists():
return None return None
try: try:

View File

@ -0,0 +1,77 @@
# General Server Utilities
#
# Copyright (C) 2023 Eric Callahan <arksine.code@gmail.com>
#
# This file may be distributed under the terms of the GNU GPLv3 license
from __future__ import annotations
import importlib.resources as ilr
import pathlib
import sys
import site
# Annotation imports
from typing import (
Optional,
)
def package_path() -> pathlib.Path:
return pathlib.Path(__file__).parent.parent
def source_path() -> pathlib.Path:
return package_path().parent
def is_git_repo(src_path: Optional[pathlib.Path] = None) -> bool:
if src_path is None:
return source_path().joinpath(".git").is_dir()
return src_path.joinpath(".git").is_dir()
def is_dist_package(src_path: Optional[pathlib.Path] = None) -> bool:
if src_path is None:
# Fetch dist info for moonraker. This should be the most reliable
# method
src_path = source_path()
site_dirs = site.getsitepackages()
return str(src_path) in site_dirs
else:
# Make an assumption based on the source path. If its name is
# site-packages or dist-packages then presumably it is an
# installed package
return src_path.name in ["dist-packages", "site-packages"]
def package_version() -> Optional[str]:
try:
import moonraker.__version__ as ver # type: ignore
version = ver.__version__
except Exception:
pass
else:
if version:
return version
return None
def read_asset(asset_name: str) -> Optional[str]:
if sys.version_info < (3, 10):
with ilr.path("moonraker.assets", asset_name) as p:
if not p.is_file():
return None
return p.read_text()
else:
files = ilr.files("moonraker.assets")
with ilr.as_file(files.joinpath(asset_name)) as p:
if not p.is_file():
return None
return p.read_text()
def get_asset_path() -> Optional[pathlib.Path]:
if sys.version_info < (3, 10):
with ilr.path("moonraker.assets", "__init__.py") as p:
asset_path = p.parent
else:
files = ilr.files("moonraker.assets")
with ilr.as_file(files.joinpath("__init__.py")) as p:
asset_path = p.parent
if not asset_path.is_dir():
# Somehow running in a zipapp. This is an error.
return None
return asset_path