1
0
Fork 0

refactor: abstract away features related to AppImage installation

This commit is contained in:
Kim, Jimin 2024-06-14 23:23:13 +09:00
parent ab2f3f52c0
commit fae975d5ee
Signed by: pomp
GPG key ID: 2B516173EDD492EB
4 changed files with 126 additions and 52 deletions

View file

@ -1,14 +1,7 @@
package installers
import (
"context"
"os"
"os/exec"
"path/filepath"
"github.com/developomp/pompup/internal/wrapper"
"github.com/google/go-github/github"
"github.com/pterm/pterm"
)
func init() {
@ -16,16 +9,12 @@ func init() {
Name: "osu!",
Desc: "osu!lazer and tablet driver",
Setup: func() {
matches, err := filepath.Glob(wrapper.InHome("Programs/AppImages/gearlever_osu*.appimage"))
if err != nil {
pterm.Fatal.Println("Failed to check osu installation:", err)
}
if len(matches) == 1 {
if wrapper.IsAppImageInstalled("osu") {
return
}
if !wrapper.PathExists(wrapper.InHome("Downloads/osu.appimage")) {
downloadOsuAppImage()
if !wrapper.PathExists(wrapper.InHome("Downloads/osu.AppImage")) {
wrapper.DownloadFromGitHub("ppy", "osu", "osu\\.AppImage")
}
},
Reminders: []string{
@ -34,41 +23,3 @@ func init() {
},
})
}
// downloadOsuAppImage downloads osu!lazer AppImage to user's Downloads directory
// without installing it. The user then has to manually install it using gearlever.
func downloadOsuAppImage() {
// GET https://api.github.com/repos/ppy/osu/releases/latest
client := github.NewClient(nil)
release, _, err := client.Repositories.GetLatestRelease(context.Background(), "ppy", "osu")
if err != nil {
pterm.Fatal.Println("Failed to get latest osu version:", err)
}
var downloadURL string
for _, asset := range release.Assets {
if *asset.Name == "osu.AppImage" {
downloadURL = *asset.BrowserDownloadURL
break
}
}
if len(downloadURL) == 0 {
pterm.Fatal.Println("Failed to get latest osu version.")
}
osuPath := wrapper.InHome("Downloads/osu.appimage")
// create parent directories
err = os.MkdirAll(filepath.Dir(osuPath), wrapper.DefaultDirPerm)
if err != nil {
pterm.Fatal.Printfln("Failed to create directory \"%s\": %s", osuPath, err)
}
// download latest osu AppImage
pterm.Debug.Println("Downloading", osuPath, "from", downloadURL)
cmd := exec.Command("wget", downloadURL, "-q", "--show-progress", "-O", osuPath)
cmd.Stderr = os.Stderr // show stderr
cmd.Stdout = os.Stdout // show stdout
if err := cmd.Run(); err != nil {
pterm.Fatal.Println("Failed to download osu lazer AppImage:", err)
}
}

View file

@ -5,7 +5,10 @@ import (
"fmt"
"os"
"os/exec"
"regexp"
"runtime"
"github.com/pterm/pterm"
)
// Startup error
@ -65,6 +68,34 @@ func IsFlatpakInstalled(packageName string) bool {
return BashRun(fmt.Sprintf("flatpak list | grep -E '%v'", packageName)) == nil
}
func IsAppImageInstalled(packageName string) bool {
return IsFileInDir(InHome("Programs/AppImages"), "(?i)gearlever_"+packageName+"_.*.appimage")
}
func IsFileInDir(dirPath, filePattern string) bool {
entries, err := os.ReadDir(dirPath)
if err != nil {
pterm.Fatal.Printfln("Failed to read %s: %s", dirPath, err)
}
for _, e := range entries {
if RegexMatch(filePattern, e.Name()) {
return true // match found
}
}
return false // match not found
}
func RegexMatch(pattern string, s string) bool {
matched, err := regexp.MatchString(fmt.Sprintf("^%s$", pattern), s)
if err != nil {
pterm.Fatal.Printfln("Failed to check regex. pattern='%s' s='%s'", pattern, s)
}
return matched
}
// PathExists checks whether the given path exists or not
func PathExists(path string) bool {
_, err := os.Stat(path)

View file

@ -0,0 +1,40 @@
package wrapper_test
import (
"testing"
"github.com/developomp/pompup/internal/wrapper"
)
type RegexMatchCase = struct {
pattern string
s string
expected bool
}
func TestRegexMatch(t *testing.T) {
cases := []RegexMatchCase{
{"..", "aa", true},
{".*", "aaa", true},
{"a\\.b", "a.b", true},
{"a-b_.*c", "a-b_abc", true},
{"asdf", "asdf", true},
// missing letters
{"asdf", "asd", false},
{"asdf", "sdf", false},
{"asd", "asdf", false},
{"sdf", "asdf", false},
// case insensitive search
{"(?i)asdf", "AsDf", true},
}
for _, c := range cases {
result := wrapper.RegexMatch(c.pattern, c.s)
if result != c.expected {
t.Fatalf(`RegexMatch("%s", "%s") is %v when it should be %v`, c.pattern, c.s, result, c.expected)
}
}
}

View file

@ -0,0 +1,52 @@
package wrapper
import (
"context"
"os"
"os/exec"
"path/filepath"
"github.com/google/go-github/github"
"github.com/pterm/pterm"
)
// DownloadFromGitHub downloads a file from GitHub releases to ~/Downloads directory without installing it.
// The user has to manually install it using gearlever.
func DownloadFromGitHub(user, repo, filePattern string) {
// GET https://api.github.com/repos/<user or org>/<repo>/releases/latest
client := github.NewClient(nil)
release, _, err := client.Repositories.GetLatestRelease(context.Background(), user, repo)
if err != nil {
pterm.Fatal.Printfln("Failed to get latest %s/%s version: %s", user, repo, err)
}
var downloadURL, fileName string
for _, asset := range release.Assets {
matched := RegexMatch(filePattern, *asset.Name)
if matched {
fileName = *asset.Name
downloadURL = *asset.BrowserDownloadURL
break
}
}
if len(downloadURL) == 0 {
pterm.Fatal.Printfln("Failed to get latest %s/%s version.", user, repo)
}
filePath := InHome("Downloads/" + fileName)
// create parent directories
err = os.MkdirAll(filepath.Dir(filePath), DefaultDirPerm)
if err != nil {
pterm.Fatal.Printfln("Failed to create directory \"%s\": %s", filePath, err)
}
// download file
pterm.Debug.Println("Downloading", filePath, "from", downloadURL)
cmd := exec.Command("wget", downloadURL, "-q", "--show-progress", "-O", filePath)
cmd.Stderr = os.Stderr // show stderr
cmd.Stdout = os.Stdout // show stdout
if err := cmd.Run(); err != nil {
pterm.Fatal.Printfln("Failed to download %s/%s: %s", user, repo, err)
}
}