- Go 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| cmd | ||
| testdata | ||
| .gitignore | ||
| appindex.go | ||
| appindex_e2e_test.go | ||
| appindex_parse.go | ||
| appindex_parse_test.go | ||
| appindex_sources_test.go | ||
| auto.go | ||
| bundle.go | ||
| channel.go | ||
| channel_test.go | ||
| decompress.go | ||
| decompress_unix.go | ||
| decompress_win.go | ||
| dirs.go | ||
| dirs_darwin.go | ||
| dirs_unix.go | ||
| dirs_windows.go | ||
| diskspace.go | ||
| diskspace_test.go | ||
| diskspace_unix.go | ||
| diskspace_windows.go | ||
| download.go | ||
| entry.go | ||
| exec_unix.go | ||
| exec_windows.go | ||
| go.mod | ||
| go.sum | ||
| install.go | ||
| install_kinds_test.go | ||
| install_stub_windows_test.go | ||
| installed_pacakges.go | ||
| installed_packages_test.go | ||
| migrate_legacy_other.go | ||
| migrate_legacy_win.go | ||
| progress.go | ||
| README.md | ||
| register_unix.go | ||
| register_win.go | ||
| root.go | ||
| root_test.go | ||
| run_unix.go | ||
| run_win.go | ||
| shortcut_win.go | ||
| tempclean.go | ||
| tempclean_test.go | ||
| updatetask_win.go | ||
| updatetask_win_test.go | ||
| utils.go | ||
| verify.go | ||
| verify_test.go | ||
| version_test.go | ||
Spitfire Package Manager (SPM)
A package management library designed to handle automatic updates for Spitfire browser and all of its components.
SPM is currently used in:
📑 APPINDEX
SPM reads the APPINDEX format documented by Repo
https://nightly.spitfirebrowser.xyz/APPINDEX
https://release.spitfirebrowser.xyz/APPINDEX
Supported kinds by SPM
SPM manages only the machine-level applications. That being browser, launcher and bundle.
Other kinds are profile-level (layout, config...) and are handled by browser's about:store thus not supported by SPM.
🗂 Install layout
Every channel is its own install, named by spm.DisplayName(): Spitfire (release), Spitfire Nightly, Spitfire Beta. The channel is baked into the binary:
go build -ldflags "-X weforge.xyz/Spitfire/SPM.Channel=nightly"
It picks the repo (nightly. / beta. / release.spitfirebrowser.xyz), the install root and every name Windows shows, so channels never touch each other's files, registry keys or tasks.
Windows - %ProgramFiles%\<DisplayName>, machine-wide, written by the elevated installer and by the <DisplayName>\Update scheduled task:
Spitfire Nightly\
├── spitfire.exe the one launch path: stub from weforge.xyz/Spitfire/Stub, shortcuts, taskbar pins and the default-browser registry entries point here
├── spitfire-toolbox.exe the launcher kind: setup window, Toolbox, `--update --silent` (run by the task), `--uninstall --silent`...
├── versions\<version>\ one complete browser per version, a new one installs beside the running one
│ └── system-install system install marker so profiles go to %APPDATA%\WeForge.xyz\Spitfire
└── spm\ SPM state, nothing the user launches
├── installed.ini what is installed by SPM, the stub reads the browser's V:<version> from here at every start
└── trust\ pinned repo ROOT + last index serial
Linux - by default SPM is not used at all: the browser ships as .deb, .rpm, .apk... (see Install.sh)
SPM can be used as a user-space fallback on systems without a supported package format or without system privileges, installing into ~/.local/share/weforge.xyz/<spitfire|spitfire-nightly|spitfire-beta>:
spitfire-nightly/
├── spitfire symlink to the current versions/<version>/spitfire, swapped by rename
├── spitfire-toolbox the launcher kind
├── versions/<version>/ one complete browser per version
│ └── system-install marker, profiles go to ~/.config/weforge.xyz/spitfire, not here
└── spm/
├── installed.ini
└── trust/
📦 Library usage:
spm.Install(specs) does the whole sequence: fetch and verify the index, download and unpack every spec that is missing or outdated (with dependencies), copy it into place, register with Windows. spm.Update() does the same for whatever installed.ini records. spm.Reinstall(specs) downloads every spec, then wipes the browser trees. Poll spm.GetStatus() from another goroutine for a progress bar.
package main
import (
"fmt"
"time"
spm "weforge.xyz/Spitfire/SPM"
)
func main() {
// A spec is at least an AppID. Other atributes default to this machine.
specs := []spm.AppIndexEntry{{AppID: "xyz.weforge.Spitfire"}, {AppID: "xyz.weforge.Launcher"}}
done := make(chan error, 1)
go func() { done <- spm.Install(specs) }()
for {
select {
case err := <-done:
if err != nil {
fmt.Println("install failed:", err)
return
}
spm.Run() // Starts the installed browser
return
case <-time.After(200 * time.Millisecond):
s := spm.GetStatus() // Total progress of the whole run
fmt.Printf("\r%3d%% %s %s", s.Total, s.Step, s.Package)
}
}
}
Total is weighted from the index: a package's download by its compressed size (S:), unpacking and copying by its uncompressed size (I:), so a small launcher update moves the bar a little and a browser update a lot.
⚡ CLI usage (spm binary)
SPM also ships with a standalone CLI tool located in cmd/main.go
It's useful for testing, scripting, or when you want to update Spitfire components manually.
Build:
go build -o spm ./cmd/main.go
Usage:
spm <install|reinstall|update|register|unregister|uninstall|run> [flags]
install spm.Install: -pkg and its dependencies, whatever is missing or outdated
reinstall spm.Reinstall: -pkg and its dependencies from scratch, the old install is wiped first
update spm.Update: whatever installed.ini records
Flags (for install, reinstall):
-pkg appid[:os[:arch[:kind]]] repeatable; empty parts keep the defaults (this OS/arch, kind from the index)
Examples:
spm install -pkg xyz.weforge.Spitfire
spm install -pkg xyz.weforge.Launcher -pkg xyz.weforge.Spitfire
spm update
⚙ Environment variables
SPM respects the following environment variables:
| Var | Values | Desc |
|---|---|---|
| SPM_PREFERRED_DECOMPRESS | "7zip", "7zr", "tar", "purego" | Overrides default decompression method. |
| SPITFIRE_INDEX_URL, SPITFIRE_ROOT_KEY | URL, base64 key | Replace the channel's built-in repo, for test repos. |
| SPITFIRE_INSTALL_DIR | path | Overrides the release install dir (SPITFIRE_NIGHTLY_INSTALL_DIR, SPITFIRE_BETA_INSTALL_DIR for the others). An installed toolbox otherwise uses the root it runs from, an installer the channel default. |
License