Skip to content

Commit

Permalink
fix: support for multiple package screens in one config (#139)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcoceppi authored Aug 7, 2023
1 parent 36b12a0 commit c9db948
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 50 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ jobs:
virtualenvs-create: true
virtualenvs-in-project: true
- name: System Deps
run: sudo apt install libgirepository1.0-dev libgtk-3-dev libadwaita-1-dev
run: |
sudo apt update
sudo apt install libgirepository1.0-dev libgtk-3-dev libadwaita-1-dev
- name: Cache Dependencies
id: cache-deps
uses: actions/cache@v3
Expand Down
69 changes: 69 additions & 0 deletions tests/example-multi-package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
title: uBlue First Boot
properties:
mode: "run-on-change"
actions:
pre:
- run: /full/path/to/bin --with --params
- run: /another/command run
- yafti.plugin.flatpak:
install: org.gnome.Calculator
post:
- run: /run/these/commands --after --all --screens
screens:
first-screen:
source: yafti.screen.title
values:
title: "That was pretty cool"
icon: "/path/to/icon"
description: |
Time to play overwatch
can-we-modify-your-flatpaks:
source: yafti.screen.consent
values:
title: Welcome traveler
condition:
run: flatpak remotes --system | grep fedora
description: |
This tool modifies your flatpaks and flatpak sources. If you do not want to do this exit the installer.
For new users just do it (tm)
actions:
- run: flatpak remote-delete fedora --force
- run: flatpak remove --system --noninteractive --all
applications:
source: yafti.screen.package
values:
title: Install flatpaks
show_terminal: true
package_manager: yafti.plugin.flatpak
groups:
Core:
description: All the good stuff
packages:
- Calculator: org.gnome.Calculator
- Firefox: org.mozilla.firefox
Gaming:
description: GAMES GAMES GAMES
default: false
packages:
- Steam: com.valvesoftware.Steam
- Games: org.gnome.Games
applications-two:
source: yafti.screen.package
values:
title: Install more flatpaks
show_terminal: true
package_manager: yafti.plugin.flatpak
groups:
Office:
description: All the work stuff
default: false
packages:
- LibreOffice: org.libreoffice.LibreOffice
- Calendar: org.gnome.Calendar
final-screen:
source: yafti.screen.title
values:
title: "All done"
icon: "/atph/to/icon"
description: |
Thanks for installing, join the community, next steps
25 changes: 9 additions & 16 deletions tests/test_screen_package_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,27 @@


def test_state_set():
state = PackageScreenState()
state = PackageScreenState("test_state_set")
state.set("hello", True)
assert state.get("hello") is True


def test_state_set_fail():
state = PackageScreenState()
state = PackageScreenState("test_state_set_fail")
with pytest.raises(ValidationError):
state.set("hello", "world")


def test_state_load():
input = {"hello": True, "world": False}
state = PackageScreenState()
state = PackageScreenState("test_state_load")
state.load(input)
assert state.get("hello") is True
assert state.get("world") is False


def test_state_from_dict():
input = {"hello": True, "world": False}
state = PackageScreenState.from_dict(input)
assert state.get("hello") is True
assert state.get("world") is False


def test_state_remove():
state = PackageScreenState()
state = PackageScreenState("test_state_remove")
state.set("kenobi", False)
state.set("general", True)
assert state.get("kenobi") is False
Expand All @@ -42,7 +35,7 @@ def test_state_remove():


def test_state_on_off():
state = PackageScreenState()
state = PackageScreenState("test_state_on_off")
state.on("grievous")
assert state.get("grievous") is True
state.off("grievous")
Expand All @@ -55,7 +48,7 @@ def test_state_on_off():


def test_state_toggle():
state = PackageScreenState()
state = PackageScreenState("test_state_toggle")
state.on("chewy")
assert state.get("chewy") is True
state.toggle("chewy")
Expand All @@ -65,13 +58,13 @@ def test_state_toggle():


def test_state_toggle_error():
state = PackageScreenState()
state = PackageScreenState("test_state_toggle_error")
with pytest.raises(KeyError):
state.toggle("barf")


def test_state_get_on():
state = PackageScreenState()
state = PackageScreenState("test_state_get_on")
state.on("chewy")
state.on("han")
state.off("greedo")
Expand All @@ -81,7 +74,7 @@ def test_state_get_on():


def test_state_keys():
state = PackageScreenState()
state = PackageScreenState("test_state_keys")
state.on("AA")
state.on("BB")
state.off("CC")
Expand Down
11 changes: 9 additions & 2 deletions yafti/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"""

import logging
from typing import Annotated

import typer
import yaml
Expand All @@ -25,12 +26,18 @@
from yafti.parser import Config


def run(config: typer.FileText = typer.Argument("/etc/yafti.yml"), debug: bool = False):
def run(
config: typer.FileText = typer.Argument("/etc/yafti.yml"),
debug: bool = False,
force_run: Annotated[
bool, typer.Option("-f", "--force", help="Ignore run mode and force run")
] = False,
):
log.set_level(logging.DEBUG if debug else logging.INFO)
log.debug("starting up", config=config, debug=debug)
config = Config.parse_obj(yaml.safe_load(config))
app = Yafti(config)
app.run(None)
app.run(None, force_run=force_run)


def app():
Expand Down
17 changes: 9 additions & 8 deletions yafti/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def __init__(self, cfg: Config = None, loop=None):
self.config = cfg
self.loop = loop or gbulb.get_event_loop()

def run(self, *args, **kwargs):
def run(self, *args, force_run: bool = False, **kwargs):
configured_mode = self.config.properties.mode
_p: Path = self.config.properties.path.expanduser()
# TODO(GH-#103): Remove this prior to 1.0 release. Start.
Expand All @@ -43,15 +43,16 @@ def run(self, *args, **kwargs):
_p.unlink()
_old_p.rename(_p)
# TODO(GH-#103): End.
if configured_mode == YaftiRunModes.disable:
return

if configured_mode == YaftiRunModes.changed:
if _p.exists() and _p.read_text() == self.config_sha:
if not force_run:
if configured_mode == YaftiRunModes.disable:
return

if configured_mode == YaftiRunModes.ignore and _p.exists():
return
if configured_mode == YaftiRunModes.changed:
if _p.exists() and _p.read_text() == self.config_sha:
return

if configured_mode == YaftiRunModes.ignore and _p.exists():
return

super().run(*args, **kwargs)

Expand Down
6 changes: 4 additions & 2 deletions yafti/screen/package/screen/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from yafti import log
from yafti.abc import YaftiScreen
from yafti.screen.console import ConsoleScreen
from yafti.screen.package.state import STATE
from yafti.screen.package.state import PackageScreenState

_xml = """\
<?xml version="1.0" encoding="UTF-8"?>
Expand Down Expand Up @@ -77,6 +77,7 @@ class PackageInstallScreen(YaftiScreen, Gtk.Box):

def __init__(
self,
id: str,
title: str = "Package Installation",
package_manager: str = "yafti.plugin.flatpak",
package_manager_defaults: Optional[dict] = None,
Expand All @@ -89,6 +90,7 @@ def __init__(
self.package_manager = PLUGINS.get(package_manager)
self.package_manager_defaults = package_manager_defaults or {}
self.btn_console.connect("clicked", self.toggle_console)
self.state = PackageScreenState(id)

async def on_activate(self):
if self.started or self.already_run:
Expand All @@ -114,7 +116,7 @@ async def do_pulse(self):
def draw(self):
self.console.hide()
self.append(self.console)
packages = [item.replace("pkg:", "") for item in STATE.get_on("pkg:")]
packages = [item.replace("pkg:", "") for item in self.state.get_on("pkg:")]
asyncio.create_task(self.do_pulse())
return self.install(packages)

Expand Down
13 changes: 9 additions & 4 deletions yafti/screen/package/screen/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
from yafti.abc import YaftiScreen, YaftiScreenConfig
from yafti.screen.package.models import PackageConfig, PackageGroupConfig
from yafti.screen.package.screen import PackageInstallScreen, PackagePickerScreen
from yafti.screen.package.state import STATE
from yafti.screen.package.utils import parse_packages
from yafti.screen.package.state import PackageScreenState
from yafti.screen.package.utils import parse_packages, generate_fingerprint

_xml = """\
<?xml version="1.0" encoding="UTF-8"?>
Expand Down Expand Up @@ -62,17 +62,22 @@ def __init__(
self.show_terminal = show_terminal
self.package_manager = package_manager
self.package_manager_defaults = package_manager_defaults
STATE.load(parse_packages(self.packages))
self.fingerprint = generate_fingerprint(self.packages)
self.state = PackageScreenState(self.fingerprint)
self.state.load(parse_packages(self.packages))
self.pkg_carousel.connect("page-changed", self.changed)
self.draw()

def draw(self):
self.pkg_carousel.append(
PackagePickerScreen(title=self.title, packages=self.packages)
PackagePickerScreen(
id=self.fingerprint, title=self.title, packages=self.packages
)
)
self.pkg_carousel.append(
PackageInstallScreen(
title=self.title,
id=self.fingerprint,
package_manager=self.package_manager,
package_manager_defaults=self.package_manager_defaults,
)
Expand Down
14 changes: 8 additions & 6 deletions yafti/screen/package/screen/picker.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from yafti import log
from yafti.abc import YaftiScreen
from yafti.screen.dialog import DialogBox
from yafti.screen.package.state import STATE
from yafti.screen.package.state import PackageScreenState
from yafti.screen.utils import find_parent

_xml = """\
Expand Down Expand Up @@ -58,13 +58,15 @@ class Config(BaseModel):

def __init__(
self,
id: str,
title: str,
packages: list | dict,
**kwargs,
):
super().__init__(**kwargs)
self.status_page.set_title(title)
self.packages = packages
self.state = PackageScreenState(id)
self.draw()

def draw(self):
Expand All @@ -76,17 +78,17 @@ def draw(self):
action_row = Adw.ActionRow(title=name, subtitle=details.get("description"))

def state_set(group, _, value):
STATE.set(f"group:{group}", value)
self.state.set(f"group:{group}", value)
d = self.packages.get(group)
for pkg in d.get("packages", []):
for pkg_name in pkg.values():
if isinstance(pkg_name, dict):
pkg_name = json.dumps(pkg_name)
STATE.set(f"pkg:{pkg_name}", value)
self.state.set(f"pkg:{pkg_name}", value)

state_set(name, None, details.get("default", True))
_switcher = Gtk.Switch()
_switcher.set_active(STATE.get(f"group:{name}"))
_switcher.set_active(self.state.get(f"group:{name}"))
_switcher.set_valign(Gtk.Align.CENTER)

state_set_fn = partial(state_set, name)
Expand Down Expand Up @@ -148,12 +150,12 @@ def _build_apps(self, packages: list):
_app_switcher = Gtk.Switch()
if isinstance(pkg, dict):
pkg = json.dumps(pkg)
_app_switcher.set_active(STATE.get(f"pkg:{pkg}"))
_app_switcher.set_active(self.state.get(f"pkg:{pkg}"))
_app_switcher.set_valign(Gtk.Align.CENTER)

def set_state(pkg, btn, value):
log.debug("state-set", pkg=pkg, value=value)
STATE.set(f"pkg:{pkg}", value)
self.state.set(f"pkg:{pkg}", value)

set_state_func = partial(set_state, pkg)
_app_switcher.connect("state-set", set_state_func)
Expand Down
20 changes: 9 additions & 11 deletions yafti/screen/package/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@
class PackageScreenState:
__slots__ = ["state"]

@classmethod
def from_dict(cls, data: dict) -> "PackageScreenState":
self = cls()
self.load(data)
return self
def __new__(cls, id: str):
if not hasattr(cls, "instances"):
cls.instances = {}
if id not in cls.instances:
cls.instances[id] = super(PackageScreenState, cls).__new__(cls)
return cls.instances[id]

def __init__(self, id: str):
self.state = {}

@validate_arguments
def load(self, data: dict):
for k, v in data.items():
self.set(k, v)

def __init__(self):
self.state = {}

@validate_arguments
def remove(self, item: str) -> None:
del self.state[item]
Expand Down Expand Up @@ -53,6 +54,3 @@ def keys(self) -> list[str]:
@validate_arguments
def get(self, item: str) -> bool:
return self.state.get(item)


STATE = PackageScreenState()
Loading

0 comments on commit c9db948

Please sign in to comment.