The package ships Flathub in /usr/share/flatpak/remotes.d, so the module declares no remote of its own and checks it instead. Eleven Go tools: list, runtimes, remotes (naming the desktop's duplicate user Flathub), updates, unused, disk usage, and install, remove, update and remove-unused, the system installation's acts through sudo -n and the account's without. uninstall --unused has no dry run, so flatpak_unused works it out from flatpak's own answers: an application's runtime and SDK, the extension points of what is used, and pins. Acts run as jobs inside the bundle, because an install outlasts a call.
214 lines
7.2 KiB
Go
214 lines
7.2 KiB
Go
// The flatpak module's tools (novox/hq research 027/02, 026/05): the applications and runtimes in
|
|
// both installations, the remotes, pending updates, what nothing uses any more and the space it all
|
|
// takes; and installing, removing and updating. A Go bundle the node's runtime launches over stdio
|
|
// (ADR 0188, ADR 0193); it runs as the operator account. An act on the system installation goes
|
|
// through `sudo -n`; one on the account's own installation does not.
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
stdio "git.novox.be/novox/mesh-sdk/go"
|
|
)
|
|
|
|
var providedBy = map[string]string{
|
|
"flatpak": "the flatpak package, which this module installs",
|
|
"du": "the coreutils package",
|
|
}
|
|
|
|
func main() {
|
|
if err := stdio.Serve("", tools()); err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
var installationArg = map[string]any{"type": "string", "enum": []string{"system", "user"},
|
|
"description": "the system installation (default), or the account's own"}
|
|
|
|
func installationOf(args map[string]any, def string) (string, error) {
|
|
i, err := optText(args, "installation", def)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if i == "" {
|
|
return "", nil
|
|
}
|
|
return i, oneOf("installation", i, "system", "user")
|
|
}
|
|
|
|
func refArg(args map[string]any, key string) (string, error) {
|
|
r, err := text(args, key)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return r, checkRef(r)
|
|
}
|
|
|
|
func tools() []stdio.Tool {
|
|
return []stdio.Tool{
|
|
{
|
|
Name: "flatpak_list",
|
|
Description: "The installed applications, in both installations or one: id, name, version, branch, origin, " +
|
|
"installation and size. (r)",
|
|
Input: map[string]any{"installation": installationArg},
|
|
Run: func(args map[string]any) (any, error) {
|
|
inst, err := installationOf(args, "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return List("app", inst)
|
|
},
|
|
},
|
|
{
|
|
Name: "flatpak_runtimes",
|
|
Description: "The installed runtimes and extensions, in both installations or one: id, branch, origin, installation and size. (r)",
|
|
Input: map[string]any{"installation": installationArg},
|
|
Run: func(args map[string]any) (any, error) {
|
|
inst, err := installationOf(args, "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return List("runtime", inst)
|
|
},
|
|
},
|
|
{
|
|
Name: "flatpak_remotes",
|
|
Description: "The remotes of both installations, with how many installed refs come from each, and findings: " +
|
|
"Flathub missing from the system installation, the same remote in both installations, a remote nothing " +
|
|
"is installed from. (r)",
|
|
Input: map[string]any{},
|
|
Run: func(map[string]any) (any, error) { return Remotes() },
|
|
},
|
|
{
|
|
Name: "flatpak_updates",
|
|
Description: "What an update would change: each ref with a newer commit on its remote. Asks the remotes, so it needs the network. (r)",
|
|
Input: map[string]any{"installation": installationArg},
|
|
Run: func(args map[string]any) (any, error) {
|
|
inst, err := installationOf(args, "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return Updates(inst)
|
|
},
|
|
},
|
|
{
|
|
Name: "flatpak_unused",
|
|
Description: "The runtimes and extensions no installed application needs any more, computed without changing " +
|
|
"anything: a runtime is used when an application names it as its runtime or SDK, when it fills an " +
|
|
"extension point of something used, or when it is pinned. With the space each takes. (r)",
|
|
Input: map[string]any{},
|
|
Run: func(map[string]any) (any, error) { return Unused() },
|
|
},
|
|
{
|
|
Name: "flatpak_disk_usage",
|
|
Description: "The space flatpak takes: each installation's directory on disk, and the applications and " +
|
|
"runtimes by size, largest first. (r)",
|
|
Input: map[string]any{},
|
|
Run: func(map[string]any) (any, error) { return DiskUsage() },
|
|
},
|
|
{
|
|
Name: "flatpak_install",
|
|
Description: "Install an application or runtime from a remote (default flathub), in the system installation " +
|
|
"(default) or the account's. Answers when finished, or after 18 s with a job to follow with flatpak_job. (a)",
|
|
Input: map[string]any{
|
|
"ref": map[string]any{"type": "string", "description": "an application id such as org.gimp.GIMP, or a full ref"},
|
|
"remote": map[string]any{"type": "string", "description": "the remote (default flathub)"},
|
|
"installation": installationArg,
|
|
},
|
|
Run: func(args map[string]any) (any, error) {
|
|
ref, err := refArg(args, "ref")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
remote, err := optText(args, "remote", "flathub")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
inst, err := installationOf(args, "system")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return Install(ref, remote, inst)
|
|
},
|
|
},
|
|
{
|
|
Name: "flatpak_remove",
|
|
Description: "Uninstall an application or runtime, keeping its data unless delete_data is set. Answers when finished, or with a job to follow. (a)",
|
|
Input: map[string]any{
|
|
"ref": map[string]any{"type": "string", "description": "the application id or ref"},
|
|
"installation": installationArg,
|
|
"delete_data": map[string]any{"type": "boolean", "description": "remove the application's data in the home too"},
|
|
},
|
|
Run: func(args map[string]any) (any, error) {
|
|
ref, err := refArg(args, "ref")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
inst, err := installationOf(args, "system")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
del, err := optFlag(args, "delete_data", false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return Remove(ref, inst, del)
|
|
},
|
|
},
|
|
{
|
|
Name: "flatpak_update",
|
|
Description: "Update one ref, or everything in an installation when no ref is given. Answers when finished, or with a job to follow. (a)",
|
|
Input: map[string]any{
|
|
"ref": map[string]any{"type": "string", "description": "the application id or ref (default all)"},
|
|
"installation": installationArg,
|
|
},
|
|
Run: func(args map[string]any) (any, error) {
|
|
ref, err := optText(args, "ref", "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if ref != "" {
|
|
if err := checkRef(ref); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
inst, err := installationOf(args, "system")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return Update(ref, inst)
|
|
},
|
|
},
|
|
{
|
|
Name: "flatpak_remove_unused",
|
|
Description: "Uninstall what flatpak itself finds unused in one installation (system by default). " +
|
|
"flatpak_unused shows what that is beforehand. Answers when finished, or with a job to follow. (a)",
|
|
Input: map[string]any{"installation": installationArg},
|
|
Run: func(args map[string]any) (any, error) {
|
|
inst, err := installationOf(args, "system")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return RemoveUnused(inst)
|
|
},
|
|
},
|
|
{
|
|
Name: "flatpak_job",
|
|
Description: "A long act this module started: running or finished, its exit status and the end of its output. Without job, every act this process knows. (r)",
|
|
Input: map[string]any{"job": map[string]any{"type": "string", "description": "the job id an act answered"}},
|
|
Run: func(args map[string]any) (any, error) {
|
|
id, err := optText(args, "job", "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if id == "" {
|
|
return map[string]any{"jobs": listJobs()}, nil
|
|
}
|
|
return jobByID(id)
|
|
},
|
|
},
|
|
}
|
|
}
|