Initial commit

This commit is contained in:
sarah committed 2026-09-24 22:04:04 +02:00
commit bea0f43947
25 files changed
+2327

No files matched your search

+131
View File
@@ -0,0 +1,131 @@
# SaraSuite
Installs, updates and removes Sara programs (SaraSortd, SaraFem, and eventually the SaraView client).
It's one AppImage file: download it, run it, pick a program.
- **Install**: downloads the program's latest commit from its git repo, copies it into
`~/.local/share/SaraSuite/Programs/<Name>/` with its own Python venv, places its configs in
`~/.config/SaraSuite/<Name>/`, and writes its desktop entries, systemd user units, D-Bus
services and so on.
- **Update**: shown when the repo has a newer commit. Program files and integration files are
replaced; configs are *merged*: your edits always win, defaults you never touched follow the
new version, new keys are added (see `ConfigMerge.py`).
- **Remove**: takes out everything the install placed (it's all recorded in a receipt) plus
everything the program made by itself while running. Configs are only removed when
"Remove configs" is ticked. Your own files are never removed: folders that might hold them
are only removed when empty. Files that existed before SaraSuite installed over them are put back.
## Sources
Programs come straight from git over HTTPS, no `git` binary needed: the latest commit is read
from `<repo>.git/info/refs` and the files from `<repo>/archive/<commit>.tar.gz`, which GitHub and
Gitea both serve the same way. Repos must be public (no login support yet).
The host is one setting in `~/.config/SaraSuite/SaraSuite/Config.toml`; manifests refer to it as
`{GitHost}`. It defaults to the Gitea on SpineS (only reachable over Tailscale):
```toml
GitHost = "http://git.srhtnin.garden/sarah"
```
The only thing a program needs from the system is `python3` (for its venv).
## Running and building
- AppImage: `Packaging/BuildAppImage.sh` builds `dist/SaraSuite-x86_64.AppImage`
(PyInstaller one-file build + `appimagetool`, like SaraFem's). When run as an AppImage,
the header has an "Add to app menu" button.
- From source: `python3 -m venv .venv && .venv/bin/pip install -r requirements.txt`, then
`Packaging/Launch.sh`.
- Without a desktop (e.g. a server), the same file works from a terminal:
```
SaraSuite-x86_64.AppImage list
SaraSuite-x86_64.AppImage install SaraSortd --set RootDir=~/Sorting --option Autostart=on
SaraSuite-x86_64.AppImage update SaraSortd
SaraSuite-x86_64.AppImage remove SaraSortd [--configs] [--keep-runtime]
```
## Where things live
| Path | What |
| --- | --- |
| `~/.local/share/SaraSuite/Programs/<Name>/` | installed program (`App/`) and its `.venv/` |
| `~/.local/share/SaraSuite/Receipts/<Name>.toml` | everything the install placed |
| `~/.local/share/SaraSuite/Pristine/<Name>/` | the default configs as last installed (the merge base) |
| `~/.local/share/SaraSuite/Backups/<Name>/` | files that were moved aside, and configs from before a merge |
| `~/.cache/SaraSuite/Downloads/` | downloaded source, removed after installing |
| `~/.config/SaraSuite/<Name>/` | the program's configs |
## Adding a program
Make `Programs/<Name>/Manifest.toml`. Templates go in `Programs/<Name>/Templates/`.
Manifests are bundled into the AppImage, so a new or changed manifest means rebuilding it
(installed programs then show an update, even without a new commit).
Anything the manifest can't describe goes in an optional `Programs/<Name>/Hooks.py`.
Targets, templates and `Set` values can use `{Variables}`: `Name`, `GitHost`, `Home`, `ConfigHome`,
`DataHome`, `CacheHome`, `SystemdUserDir`, `ApplicationsDir`, `DBusServicesDir`, `ProgramDir`,
`AppDir`, `Python` (the venv's python), `ConfigDir`, `DesktopName` (e.g. `COSMIC`),
`Desktop` (e.g. `cosmic`), plus every Question's `Id`.
```toml
Name = "Example"
Description = "Shown on the program's card."
RestartUnits = ["xdg-desktop-portal.service"] # try-restarted after install/update/remove
[Version] # optional, shown on the card
File = "Example.py"
Pattern = 'Version = "([^"]+)"'
[Source]
Git = "{GitHost}/Example"
Branch = "main" # optional, default: the repo's default branch
Include = ["*.py", "assets/**"] # default: everything
Exclude = ["Packaging"] # .git, .venv, build, ... are always excluded
[Python]
RequirementsFile = "requirements.txt" # or: Requirements = ["toml"]
[[Questions]] # asked at install time, usable as {RootDir}
Id = "RootDir"
Prompt = "Folder to use"
Default = "~/Somewhere"
Kind = "Path" # expanded to an absolute path
[[Options]] # checkboxes at install time
Id = "Autostart"
Label = "Start on login"
Default = true
[[Configs]] # placed once, merged on updates
Source = "Conf.toml" # in the source checkout
Target = "{ConfigDir}/Conf.toml"
Set = { "Paths.RootDir" = "{RootDir}" }
[[Templates]] # owned by SaraSuite, rewritten on every update
Source = "Example.service" # in Templates/
Target = "{SystemdUserDir}/Example.service"
Option = "Autostart" # optional: only while the option is ticked
Root = false # true: outside $HOME, written through pkexec
Executable = false
[[Services]] # systemd --user units, enabled + started
Unit = "Example.service"
Option = "Autostart"
[[IniEdits]] # one key in a file SaraSuite doesn't own; restored on removal
File = "{ConfigHome}/mimeapps.list"
Section = "Default Applications"
Key = "inode/directory"
Value = "Example.desktop"
[[Leftovers]] # made by the program itself, only touched on removal
Path = "{CacheHome}/Example" # globs allowed
Kind = "Runtime" # or "Config"
Mode = "Remove" # or "IfEmpty"
Note = "thumbnail cache"
```
`Hooks.py` can define `Leftovers(Context: dict) -> list[Manifests.Leftover]` for leftovers
that depend on the program's own config (see `Programs/SaraSortd/Hooks.py`).