Perbaiki backup/restore dan script yang tidak jalan dari shortcut

Backup/restore:
- berkas .lazy (format versi 2) kini menyimpan ISI berkas: binary/script dan ikon
  (maks 512 MB per berkas); format versi 1 tetap bisa diimpor
- impor memakai shortcut.Restore: binary ditulis ke ~/.local/bin lokal, ikon dari
  cadangan (atau diunduh ulang dari icon_source), .desktop ditulis dengan path
  lokal, salinan Desktop dibuat sesuai target
- path dari komputer lama tidak dipakai mentah -> tidak ada lagi 'banyak file
  missing'; entri yang tidak bisa dipulihkan ditandai dan bisa dibetulkan via edit
- tes end-to-end: pasang 3 shortcut -> ekspor -> pulihkan di HOME lain -> semua
  berkas lokal, script hasil restore benar-benar jalan

Script:
- script dipasang sebagai wrapper + <slug>.real: wrapper menambahkan
  ~/.local/bin ke PATH dan cd ke folder asli script (desktop environment
  menjalankan dengan cwd = home, PATH sesi)
- .desktop dapat Path= sesuai folder asli script
- opsi 'Run in a terminal window (scripts)' di dialog install & edit
- uninstall membuang wrapper + script aslinya
This commit is contained in:
oxpoe committed 2026-10-13 09:25:49 +07:00
1 parent fdb503e152
commit 581cd07dba
16 files changed
+779 -59

No files matched your search

+60 -1
View File
@@ -62,7 +62,7 @@ func TestExportImportRoundtrip(t *testing.T) {
}
// urutan hasil impor berdasarkan nama: WhatsApp Web lalu Winbox
web, exe := got[0], got[1]
web, exe := got[0].Item, got[1].Item
if web.Slug != "whatsapp-web" || web.URL != "https://web.whatsapp.com" || !web.Targets.Menu || web.Targets.Desktop {
t.Errorf("data webapp tidak utuh: %+v", web)
}
@@ -77,6 +77,65 @@ func TestExportImportRoundtrip(t *testing.T) {
}
}
func TestExportStoresFileContents(t *testing.T) {
home := t.TempDir()
binary := filepath.Join(home, "app")
if err := os.WriteFile(binary, []byte("isi-binary-penting"), 0o755); err != nil {
t.Fatal(err)
}
iconFile := filepath.Join(home, "app.png")
iconBytes := append([]byte("\x89PNG\r\n\x1a\n"), []byte("ikon")...)
if err := os.WriteFile(iconFile, iconBytes, 0o644); err != nil {
t.Fatal(err)
}
items := []store.Shortcut{{
Slug: "app", Name: "App", Type: store.TypeExecutable, Kind: "binary",
BinaryPath: binary, IconPath: iconFile, DesktopPath: filepath.Join(home, "app.desktop"),
Terminal: true, Targets: store.Targets{Menu: true},
}}
path := filepath.Join(home, "db.lazy")
if err := Export(path, "1.2.0", items); err != nil {
t.Fatal(err)
}
got, err := Import(path)
if err != nil {
t.Fatal(err)
}
if string(got[0].Binary) != "isi-binary-penting" {
t.Errorf("isi binary tidak ikut tercadang: %q", got[0].Binary)
}
if string(got[0].Icon) != string(iconBytes) {
t.Errorf("isi ikon tidak ikut tercadang: %q", got[0].Icon)
}
if !got[0].Item.Terminal {
t.Error("flag terminal hilang")
}
}
func TestExportSkipsMissingFiles(t *testing.T) {
home := t.TempDir()
items := []store.Shortcut{{
Slug: "hilang", Name: "Hilang", Type: store.TypeExecutable,
BinaryPath: filepath.Join(home, "tidak-ada"), DesktopPath: filepath.Join(home, "x.desktop"),
Targets: store.Targets{Menu: true},
}}
path := filepath.Join(home, "db.lazy")
if err := Export(path, "1.2.0", items); err != nil {
t.Fatal(err)
}
got, err := Import(path)
if err != nil {
t.Fatal(err)
}
if len(got) != 1 || len(got[0].Binary) != 0 {
t.Errorf("berkas hilang tidak boleh bikin ekspor gagal: %+v", got)
}
}
func TestExportOverwritesOldFile(t *testing.T) {
path := filepath.Join(t.TempDir(), "db.lazy")
if err := os.WriteFile(path, []byte("bukan sqlite"), 0o644); err != nil {