Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions synodic_client/application/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from synodic_client.config import set_dev_mode
from synodic_client.logging import configure_logging
from synodic_client.protocol import register_protocol
from synodic_client.resolution import resolve_auto_start, resolve_config
from synodic_client.resolution import resolve_config, seed_user_config_from_build
from synodic_client.startup import register_startup, remove_startup
from synodic_client.updater import initialize_velopack

Expand All @@ -32,10 +32,13 @@
initialize_velopack()

if not _dev_mode:
# Seed user config from the build config (one-time propagation).
seed_user_config_from_build()

register_protocol(sys.executable)

_config = resolve_config()
if resolve_auto_start(_config):
if _config.auto_start:
register_startup(sys.executable)
else:
remove_startup()
Expand Down
22 changes: 15 additions & 7 deletions synodic_client/application/qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,21 @@
from synodic_client.application.screen.tray import TrayScreen
from synodic_client.application.uri import parse_uri
from synodic_client.client import Client
from synodic_client.config import GlobalConfiguration, set_dev_mode
from synodic_client.config import set_dev_mode
from synodic_client.logging import configure_logging
from synodic_client.protocol import register_protocol
from synodic_client.resolution import resolve_auto_start, resolve_config, resolve_update_config
from synodic_client.resolution import (
ResolvedConfig,
resolve_config,
resolve_update_config,
resolve_version,
seed_user_config_from_build,
)
from synodic_client.startup import register_startup, remove_startup
from synodic_client.updater import initialize_velopack


def _init_services(logger: logging.Logger) -> tuple[Client, API, GlobalConfiguration]:
def _init_services(logger: logging.Logger) -> tuple[Client, API, ResolvedConfig]:
"""Create and configure core services.

Returns:
Expand All @@ -47,11 +53,10 @@ def _init_services(logger: logging.Logger) -> tuple[Client, API, GlobalConfigura
cached_dirs = porringer.cache.list_directories()

logger.info(
'Synodic Client v%s started (channel: %s, source: %s, config_fields_set: %s, cached_projects: %d)',
client.version,
'Synodic Client v%s started (channel: %s, source: %s, cached_projects: %d)',
resolve_version(client),
update_config.channel.name,
update_config.repo_url,
sorted(config.model_fields_set),
len(cached_dirs),
)

Expand Down Expand Up @@ -140,8 +145,11 @@ def application(*, uri: str | None = None, dev_mode: bool = False) -> None:
initialize_velopack()
register_protocol(sys.executable)

# Seed user config from build config (one-time propagation).
seed_user_config_from_build()

startup_config = resolve_config()
if resolve_auto_start(startup_config):
if startup_config.auto_start:
register_startup(sys.executable)
else:
remove_startup()
Expand Down
23 changes: 13 additions & 10 deletions synodic_client/application/screen/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
MUTED_STYLE,
NO_MARGINS,
)
from synodic_client.config import GlobalConfiguration, save_config
from synodic_client.resolution import ResolvedConfig, update_user_config

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -332,7 +332,7 @@ def __init__(
parent: QWidget | None = None,
*,
show_close: bool = True,
config: GlobalConfiguration | None = None,
config: ResolvedConfig | None = None,
) -> None:
"""Initialize the preview widget.

Expand Down Expand Up @@ -579,14 +579,14 @@ def _flush_prerelease_overrides(self) -> None:
if self._config is None or self._manifest_key is None:
return

pkgs = self._config.prerelease_packages or {}
pkgs = dict(self._config.prerelease_packages or {})
if self._prerelease_overrides:
pkgs[self._manifest_key] = sorted(self._prerelease_overrides)
else:
pkgs.pop(self._manifest_key, None)

self._config.prerelease_packages = pkgs if pkgs else None
save_config(self._config)
new_value = pkgs if pkgs else None
self._config = update_user_config(prerelease_packages=new_value)
logger.info('Pre-release overrides for %s: %s', self._manifest_key, self._prerelease_overrides)

if not self._installing:
Expand Down Expand Up @@ -918,21 +918,21 @@ def __init__(
manifest_url: str,
parent: QWidget | None = None,
*,
config: GlobalConfiguration | None = None,
config: ResolvedConfig | None = None,
) -> None:
"""Initialize the install preview window.

Args:
porringer: The porringer API instance.
manifest_url: The URL of the manifest to install.
parent: Optional parent widget.
config: Resolved global configuration for per-manifest pre-release
config: Resolved configuration for per-manifest pre-release
state and update detection flags.
"""
super().__init__(parent)
self._porringer = porringer
self._manifest_url = manifest_url
self._config = config or GlobalConfiguration()
self._config = config
self._temp_dir_path: str | None = None
self._runner: QThread | None = None

Expand Down Expand Up @@ -1038,13 +1038,16 @@ def start(self) -> None:
self._preview_widget.set_manifest_key(self._manifest_url)

manifest_key = normalize_manifest_key(self._manifest_url)
overrides = set((self._config.prerelease_packages or {}).get(manifest_key, []))
config = self._config
if config is None:
return
overrides = set((config.prerelease_packages or {}).get(manifest_key, []))

preview_worker = PreviewWorker(
self._porringer,
self._manifest_url,
project_directory=self._project_directory,
detect_updates=self._config.detect_updates,
detect_updates=config.detect_updates,
prerelease_packages=overrides or None,
)

Expand Down
33 changes: 14 additions & 19 deletions synodic_client/application/screen/screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
PLUGIN_UPDATE_STYLE,
SETTINGS_GEAR_STYLE,
)
from synodic_client.config import GlobalConfiguration, save_config
from synodic_client.resolution import ResolvedConfig, update_user_config

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -306,14 +306,14 @@ class PluginsView(QWidget):
def __init__(
self,
porringer: API,
config: GlobalConfiguration,
config: ResolvedConfig,
parent: QWidget | None = None,
) -> None:
"""Initialize the plugins view.

Args:
porringer: The porringer API instance.
config: Resolved global configuration (for auto-update toggles).
config: Resolved configuration (for auto-update toggles).
parent: Optional parent widget.
"""
super().__init__(parent)
Expand Down Expand Up @@ -484,21 +484,16 @@ def _gather_packages(

def _on_auto_update_toggled(self, plugin_name: str, enabled: bool) -> None:
"""Persist the auto-update toggle change to config."""
mapping = self._config.plugin_auto_update
if mapping is None:
mapping = {}
self._config.plugin_auto_update = mapping
mapping = dict(self._config.plugin_auto_update or {})

if enabled:
mapping.pop(plugin_name, None)
else:
mapping[plugin_name] = False

# Clean up the dict if all plugins are enabled
if not mapping:
self._config.plugin_auto_update = None

save_config(self._config)
new_value = mapping if mapping else None
self._config = update_user_config(plugin_auto_update=new_value)
logger.info('Auto-update for %s set to %s', plugin_name, enabled)


Expand All @@ -510,12 +505,12 @@ class ProjectsView(QWidget):
install execution.
"""

def __init__(self, porringer: API, config: GlobalConfiguration, parent: QWidget | None = None) -> None:
def __init__(self, porringer: API, config: ResolvedConfig, parent: QWidget | None = None) -> None:
"""Initialize the projects view.

Args:
porringer: The porringer API instance.
config: Resolved global configuration.
config: Resolved configuration.
parent: Optional parent widget.
"""
super().__init__(parent)
Expand Down Expand Up @@ -805,17 +800,17 @@ class MainWindow(QMainWindow):
def __init__(
self,
porringer: API | None = None,
config: GlobalConfiguration | None = None,
config: ResolvedConfig | None = None,
) -> None:
"""Initialize the main window.

Args:
porringer: Optional porringer API instance for manifest display.
config: Resolved global configuration for plugin auto-update state.
config: Resolved configuration for plugin auto-update state.
"""
super().__init__()
self._porringer = porringer
self._config = config or GlobalConfiguration()
self._config = config
self.setWindowTitle('Synodic Client')
self.setMinimumSize(*MAIN_WINDOW_MIN_SIZE)
self.setWindowIcon(app_icon())
Expand All @@ -832,7 +827,7 @@ def plugins_view(self) -> PluginsView | None:

def show(self) -> None:
"""Show the window, initializing UI lazily on first show."""
if self._tabs is None and self._porringer is not None:
if self._tabs is None and self._porringer is not None and self._config is not None:
self._tabs = QTabWidget(self)

self._projects_view = ProjectsView(self._porringer, self._config, self)
Expand Down Expand Up @@ -867,13 +862,13 @@ class Screen:
def __init__(
self,
porringer: API | None = None,
config: GlobalConfiguration | None = None,
config: ResolvedConfig | None = None,
) -> None:
"""Initialize the screen.

Args:
porringer: Optional porringer API instance.
config: Resolved global configuration.
config: Resolved configuration.
"""
self._porringer = porringer
self._config = config
Expand Down
Loading