feat: ship Rust login manager and GitLab release pipeline

Replace the legacy Go implementation as the production path, quarantine the reference tree, add deterministic release packaging and version metadata, and run verification through GitLab CI.
This commit is contained in:
2026-09-25 21:33:46 +05:30
parent 1723ab53b8
commit faf5b27328
49 changed files with 6795 additions and 747 deletions

149
legacy/go/session/scan.go Normal file
View File

@@ -0,0 +1,149 @@
// session — environment scanning from xsessions, wayland-sessions,
// and custom script directories. Includes desktop entry parser.
//
// Mirrors vendor/src/post_login/mod.rs:get_envs and parse_desktop_entry.
package session
import (
"bufio"
"fmt"
"os"
"path/filepath"
"strings"
)
type DesktopEntry struct {
Name string
Exec string
DesktopNames string
Hidden bool
NoDisplay bool
}
func parseDesktopEntry(path string) (*DesktopEntry, error) {
f, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("open %s: %w", path, err)
}
defer f.Close()
e := &DesktopEntry{}
inSection := false
sc := bufio.NewScanner(f)
for sc.Scan() {
line := strings.TrimSpace(sc.Text())
if line == "" || line[0] == '#' {
continue
}
if line[0] == '[' && line[len(line)-1] == ']' {
inSection = line == "[Desktop Entry]"
continue
}
if !inSection {
continue
}
eq := strings.IndexByte(line, '=')
if eq < 0 {
continue
}
k, v := line[:eq], line[eq+1:]
switch k {
case "Name":
e.Name = v
case "Exec":
e.Exec = v
case "DesktopNames":
e.DesktopNames = v
case "Hidden":
e.Hidden = strings.EqualFold(v, "true")
case "NoDisplay":
e.NoDisplay = strings.EqualFold(v, "true")
}
}
if sc.Err() != nil {
return nil, sc.Err()
}
if e.Exec == "" {
return nil, fmt.Errorf("no Exec in %s", path)
}
if e.Name == "" {
e.Name = e.Exec
}
return e, nil
}
func ScanEnvs(xSessions, wlSessions, xScripts, wlScripts string, includeTTY bool) []PostLoginEnv {
var envs []PostLoginEnv
scanDesktopDir(xSessions, "x11", &envs)
scanDesktopDir(wlSessions, "wayland", &envs)
scanScriptDir(xScripts, "x11", &envs)
scanScriptDir(wlScripts, "wayland", &envs)
if len(envs) == 0 || includeTTY {
envs = append(envs, PostLoginEnv{Kind: "tty", Title: "TTYSHELL"})
}
return envs
}
func scanDesktopDir(dir, kind string, envs *[]PostLoginEnv) {
entries, err := os.ReadDir(dir)
if err != nil {
return
}
for _, e := range entries {
if e.IsDir() || filepath.Ext(e.Name()) != ".desktop" {
continue
}
path := filepath.Join(dir, e.Name())
de, err := parseDesktopEntry(path)
if err != nil || de.Hidden || de.NoDisplay {
continue
}
desktopNames, sessionDesktop := splitDesktopNames(de.DesktopNames, e.Name())
*envs = append(*envs, PostLoginEnv{
Kind: kind,
Title: de.Name,
XinitrcPath: de.Exec,
ScriptPath: de.Exec,
DesktopNames: desktopNames,
SessionDesktop: sessionDesktop,
})
}
}
func splitDesktopNames(raw, fallback string) (currentDesktop, sessionDesktop string) {
if raw == "" {
return fallback, fallback
}
parts := strings.SplitN(raw, ";", 2)
sessionDesktop = strings.TrimSpace(parts[0])
currentDesktop = strings.ReplaceAll(raw, ";", ":")
return
}
func scanScriptDir(dir, kind string, envs *[]PostLoginEnv) {
entries, err := os.ReadDir(dir)
if err != nil {
return
}
for _, e := range entries {
if e.IsDir() {
continue
}
info, err := e.Info()
if err != nil {
continue
}
if info.Mode()&0111 == 0 {
continue
}
path := filepath.Join(dir, e.Name())
*envs = append(*envs, PostLoginEnv{
Kind: kind,
Title: e.Name(),
XinitrcPath: path,
ScriptPath: path,
})
}
}