Cover GDM module with tests, added FilesLabelerFactory, renamed GdmBuilder

This commit is contained in:
Vladyslav Hroshev
2025-04-13 23:50:22 +03:00
parent ca4e4d4cbe
commit 58658ff7fc
17 changed files with 775 additions and 31 deletions

View File

@@ -1,15 +1,28 @@
import os
from abc import ABC, abstractmethod
from typing import Tuple, TypeAlias
LabeledFileGroup: TypeAlias = Tuple[str, str]
class FilesLabelerFactory(ABC):
@abstractmethod
def create(self, temp_folder: str, *files_to_update_references: str) -> 'FilesLabeler':
pass
class FilesLabelerFactoryImpl(FilesLabelerFactory):
def create(self, temp_folder: str, *files_to_update_references: str) -> 'FilesLabeler':
return FilesLabeler(temp_folder, *files_to_update_references)
class FilesLabeler:
def __init__(self, directory: str, *args: str):
def __init__(self, directory: str, *files_to_update_references: str):
"""
Initialize the working directory and files to change
"""
self.directory = directory
self.files = args
self.files = files_to_update_references
def append_label(self, label: str):
"""

View File

@@ -6,6 +6,7 @@ from scripts.install.colors_definer import ColorsDefiner
from scripts.types.installation_color import InstallationMode
from scripts.utils.alternatives_updater import AlternativesUpdater, PathString
from scripts.utils.command_runner.subprocess_command_runner import SubprocessCommandRunner
from scripts.utils.files_labeler import FilesLabelerFactoryImpl
from scripts.utils.global_theme.gdm import GDMTheme
from scripts.utils.global_theme.gdm_installer import GDMThemeInstaller
from scripts.utils.global_theme.gdm_preparer import GDMThemePreparer
@@ -17,7 +18,7 @@ from scripts.utils.logger.logger import LoggerFactory
from scripts.utils.theme.gnome_shell_theme_builder import GnomeShellThemeBuilder
class GdmBuilder:
class GDMThemeBuilder:
"""
Builder class for creating GDMTheme instances with configurable components.
@@ -26,7 +27,7 @@ class GdmBuilder:
automatically resolved during build() if not provided.
Example usage:
builder = GdmBuilder(colors_provider)
builder = GMDThemeBuilder(colors_provider)
theme = builder.with_mode("dark").with_filled(True).build()
"""
def __init__(self, colors_provider: ColorsDefiner):
@@ -46,42 +47,42 @@ class GdmBuilder:
self._installer: Optional[GDMThemeInstaller] = None
self._remover: Optional[GDMThemeRemover] = None
def with_mode(self, mode: InstallationMode | None) -> 'GdmBuilder':
def with_mode(self, mode: InstallationMode | None) -> 'GDMThemeBuilder':
"""Set the mode for the theme."""
self._mode = mode
return self
def with_filled(self, is_filled=True) -> 'GdmBuilder':
def with_filled(self, is_filled=True) -> 'GDMThemeBuilder':
"""Set the filled state for the theme."""
self._is_filled = is_filled
return self
def with_logger_factory(self, logger_factory: LoggerFactory) -> 'GdmBuilder':
def with_logger_factory(self, logger_factory: LoggerFactory) -> 'GDMThemeBuilder':
"""Inject a logger factory for logging purposes."""
self._logger_factory = logger_factory
return self
def with_gresource(self, gresource: Gresource) -> 'GdmBuilder':
def with_gresource(self, gresource: Gresource) -> 'GDMThemeBuilder':
"""Inject a gresource instance for managing gresource files."""
self._gresource = gresource
return self
def with_ubuntu_gdm_alternatives_updater(self, alternatives_updater: UbuntuGDMAlternativesUpdater) -> 'GdmBuilder':
def with_ubuntu_gdm_alternatives_updater(self, alternatives_updater: UbuntuGDMAlternativesUpdater) -> 'GDMThemeBuilder':
"""Inject an alternatives updater for managing GDM alternatives."""
self._ubuntu_gdm_alternatives_updater = alternatives_updater
return self
def with_preparer(self, preparer: GDMThemePreparer) -> 'GdmBuilder':
def with_preparer(self, preparer: GDMThemePreparer) -> 'GDMThemeBuilder':
"""Inject a preparer for preparing the theme."""
self._preparer = preparer
return self
def with_installer(self, installer: GDMThemeInstaller) -> 'GdmBuilder':
def with_installer(self, installer: GDMThemeInstaller) -> 'GDMThemeBuilder':
"""Inject an installer for installing the theme."""
self._installer = installer
return self
def with_remover(self, remover: GDMThemeRemover) -> 'GdmBuilder':
def with_remover(self, remover: GDMThemeRemover) -> 'GDMThemeBuilder':
"""Inject a remover for removing the theme."""
self._remover = remover
return self
@@ -141,13 +142,15 @@ class GdmBuilder:
"""Create a GDMThemePreparer if not explicitly provided."""
if self._preparer: return
theme_builder = GnomeShellThemeBuilder(self.colors_provider)
files_labeler_factory = FilesLabelerFactoryImpl()
self._preparer = GDMThemePreparer(
temp_folder=self._temp_folder,
default_mode=self._mode,
is_filled=self._is_filled,
gresource=self._gresource,
theme_builder=theme_builder,
logger_factory=self._logger_factory
logger_factory=self._logger_factory,
files_labeler_factory=files_labeler_factory,
)
def _resolve_installer(self):

View File

@@ -1,5 +1,6 @@
import os
from scripts.utils.files_labeler import FilesLabelerFactory
from scripts.utils.global_theme.gdm_theme_prepare import GDMThemePrepare
from scripts.utils.gresource.gresource import Gresource
from scripts.utils.logger.logger import LoggerFactory
@@ -19,13 +20,16 @@ class GDMThemePreparer:
def __init__(self, temp_folder: str, default_mode: str | None, is_filled: bool,
gresource: Gresource,
theme_builder: GnomeShellThemeBuilder,
logger_factory: LoggerFactory):
logger_factory: LoggerFactory,
files_labeler_factory: FilesLabelerFactory):
"""
:param temp_folder: Temporary folder for extracted theme files
:param default_mode: Default theme mode to use if not specified in CSS filename
:param is_filled: Whether to generate filled (True) or outlined (False) styles
:param is_filled: Whether to generate filled (True) or dimmed (False) styles
:param gresource: Gresource instance for managing gresource files
:param theme_builder: Theme builder instance for creating themes
:param logger_factory: Logger factory for logging messages
:param files_labeler_factory: Factory for creating FilesLabeler instances
"""
self.temp_folder = temp_folder
self.gresource_temp_folder = gresource.temp_folder
@@ -36,6 +40,7 @@ class GDMThemePreparer:
self.gresource = gresource
self.theme_builder = theme_builder
self.logger_factory = logger_factory
self.files_labeler_factory = files_labeler_factory
def use_backup_as_source(self):
"""Use backup gresource file for extraction"""
@@ -72,11 +77,12 @@ class GDMThemePreparer:
theme.prepare()
theme_file = os.path.join(self.gresource_temp_folder, file_name)
return GDMThemePrepare(theme=theme, theme_file=theme_file, label=mode)
files_labeler = self.files_labeler_factory.create(
theme.temp_folder, theme.main_styles)
return GDMThemePrepare(
theme=theme, theme_file=theme_file, label=mode, files_labeler=files_labeler)
def _setup_theme_builder(self, file_name: str, mode: str):
self.theme_builder.with_temp_folder(self.temp_folder)
theme_name = file_name.replace(".css", "")
(self.theme_builder

View File

@@ -12,15 +12,18 @@ class GDMThemePrepare:
- CSS property and keyword removal for customization
- Theme installation with color adjustments
"""
def __init__(self, theme: Theme, theme_file: str, label: str = None):
def __init__(self, theme: Theme, theme_file: str, label: str | None,
files_labeler: FilesLabeler):
"""
:param theme: The theme object to prepare
:param theme_file: Path to the original decompiled CSS file
:param label: Optional label for the theme (e.g. "dark", "light")
:param files_labeler: FilesLabeler instance for labeling files
"""
self.theme = theme
self.theme_file = theme_file
self.label = label
self.files_labeler = files_labeler
def label_theme(self):
"""
@@ -31,8 +34,7 @@ class GDMThemePrepare:
if self.label is None:
raise ValueError("Label is not set for the theme.")
files_labeler = FilesLabeler(self.theme.temp_folder, self.theme.main_styles)
files_labeler.append_label(self.label)
self.files_labeler.append_label(self.label)
def remove_keywords(self, *args: str):
"""Remove specific keywords from the theme file"""
@@ -52,7 +54,7 @@ class GDMThemePrepare:
:param trigger: String marker used to identify installed themes
"""
with open(self.theme_file, 'r') as gnome_theme:
gnome_styles = gnome_theme.read() + trigger
gnome_styles = gnome_theme.read() + '\n' + trigger + '\n'
self.theme.add_to_start(gnome_styles)
def install(self, hue: int, color: str, sat: int | None, destination: str):

View File

@@ -17,7 +17,7 @@ class UbuntuGDMAlternativesUpdater:
"""
:param alternatives_updater: Handler for update-alternatives operations
"""
self.ubuntu_gresource_link = config.ubuntu_gresource_link
self.ubuntu_gresource_link_name = config.ubuntu_gresource_link
self.destination_dir = config.global_gnome_shell_theme
self.destination_file = config.gnome_shell_gresource
@@ -26,7 +26,7 @@ class UbuntuGDMAlternativesUpdater:
self._update_gresource_paths()
def _update_gresource_paths(self):
self.ubuntu_gresource_path = os.path.join(self.destination_dir, self.ubuntu_gresource_link)
self.ubuntu_gresource_path = os.path.join(self.destination_dir, self.ubuntu_gresource_link_name)
self.gnome_gresource_path = os.path.join(self.destination_dir, self.destination_file)
def with_custom_destination(self, destination_dir: str, destination_file: str):
@@ -47,7 +47,7 @@ class UbuntuGDMAlternativesUpdater:
"""
self.alternatives_updater.install_and_set(
link=self.ubuntu_gresource_path,
name=self.ubuntu_gresource_link,
name=self.ubuntu_gresource_link_name,
path=self.gnome_gresource_path,
priority=priority
)
@@ -60,6 +60,6 @@ class UbuntuGDMAlternativesUpdater:
the system to fall back to the default GDM theme.
"""
self.alternatives_updater.remove(
name=self.ubuntu_gresource_link,
name=self.ubuntu_gresource_link_name,
path=self.gnome_gresource_path
)

View File

@@ -10,10 +10,10 @@ def remove_properties(file, *args):
with open(file, "r") as read_file:
content = read_file.read()
for line in content.splitlines():
for i, line in enumerate(content.splitlines()):
if not any(prop in line for prop in args):
new_content += line + "\n"
elif "}" in line:
elif "}" in line and not "{" in line:
new_content += "}\n"
with open(file, "w") as write_file: