From 3353d3d9237315091745766e5bbc75ebea667639 Mon Sep 17 00:00:00 2001 From: Justin Hawkins Date: Tue, 28 Nov 2023 21:30:48 +1030 Subject: [PATCH] Juggle the test to the right place, call it also while saving config to be consistent --- config/config.go | 30 ++++++++++++++++++++++-- config/config_test.go | 40 ++++++++++++++++++++++++++++++++ download/download.go | 36 ++++++++--------------------- download/download_test.go | 42 ---------------------------------- main.go | 2 +- web/data/templates/config.tmpl | 5 +++- 6 files changed, 82 insertions(+), 73 deletions(-) diff --git a/config/config.go b/config/config.go index 9b17795..ba6cc53 100644 --- a/config/config.go +++ b/config/config.go @@ -189,9 +189,10 @@ func (c *Config) UpdateFromJSON(j []byte) error { } // check the command exists - _, err := exec.LookPath(newConfig.DownloadProfiles[i].Command) + + _, err := AbsPathToExecutable(newConfig.DownloadProfiles[i].Command) if err != nil { - return fmt.Errorf("Could not find %s on the path", newConfig.DownloadProfiles[i].Command) + return fmt.Errorf("problem with command '%s': %s", newConfig.DownloadProfiles[i].Command, err) } } @@ -337,3 +338,28 @@ func (cs *ConfigService) WriteConfig() { } file.Close() } + +// AbsPathToExecutable takes a command name, which may or may not be path-qualified, +// and returns the fully qualified path to it, or an error if could not be found, or +// if it does not appear to be a file. +func AbsPathToExecutable(cmd string) (string, error) { + + pathCmd, err := exec.LookPath(cmd) + if err != nil { + return "", fmt.Errorf("could not LookPath '%s': %w", cmd, err) + } + + execAbsolutePath, err := filepath.Abs(pathCmd) + if err != nil { + return "", fmt.Errorf("could not get absolute path to '%s': %w", cmd, err) + } + fi, err := os.Stat(execAbsolutePath) + if err != nil { + return "", fmt.Errorf("could not get stat '%s': %w", cmd, err) + } + if !fi.Mode().IsRegular() { + return "", fmt.Errorf("'%s' is not a regular file: %w", cmd, err) + } + + return execAbsolutePath, nil +} diff --git a/config/config_test.go b/config/config_test.go index f4a23af..22b8e7d 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -2,6 +2,8 @@ package config import ( "os" + "os/exec" + "path/filepath" "testing" "github.com/stretchr/testify/assert" @@ -172,3 +174,41 @@ func configServiceFromString(configString string) *ConfigService { } return &cs } + +func TestLookForExecutable(t *testing.T) { + cmdPath, err := exec.LookPath("sleep") + if err != nil { + t.Errorf("cannot run this test without knowing about sleep: %s", err) + t.FailNow() + } + cmdDir := filepath.Dir(cmdPath) + + cmd := "sleep" + path, err := AbsPathToExecutable(cmd) + if assert.NoError(t, err) { + assert.Equal(t, cmdPath, path) + } + + cmd = cmdPath + path, err = AbsPathToExecutable(cmd) + if assert.NoError(t, err) { + assert.Equal(t, cmdPath, path) + } + + cmd = "../../../../../../../../.." + cmdPath + path, err = AbsPathToExecutable(cmd) + if assert.NoError(t, err) { + assert.Equal(t, cmdPath, path) + } + cmd = "./sleep" + _, err = AbsPathToExecutable(cmd) + assert.Error(t, err) + + os.Chdir(cmdDir) + cmd = "./sleep" + path, err = AbsPathToExecutable(cmd) + if assert.NoError(t, err) { + assert.Equal(t, cmdPath, path) + } + +} diff --git a/download/download.go b/download/download.go index e24f8cc..4d9108f 100644 --- a/download/download.go +++ b/download/download.go @@ -281,13 +281,18 @@ func (dl *Download) Begin() { cmdSlice = append(cmdSlice, dl.Url) } - dl.Log = append(dl.Log, fmt.Sprintf("executing: %s with args: %s", dl.DownloadProfile.Command, strings.Join(cmdSlice, " "))) - - cmdPath, err := absPathToExecutable(dl.DownloadProfile.Command) + cmdPath, err := config.AbsPathToExecutable(dl.DownloadProfile.Command) if err != nil { - panic(err) + dl.State = STATE_FAILED + dl.Finished = true + dl.FinishedTS = time.Now() + dl.Log = append(dl.Log, fmt.Sprintf("error finding executable for downloader: %s", err.Error())) + dl.Lock.Unlock() + return } + dl.Log = append(dl.Log, fmt.Sprintf("executing: %s (%s) with args: %s", dl.DownloadProfile.Command, cmdPath, strings.Join(cmdSlice, " "))) + cmd := exec.Command(cmdPath, cmdSlice...) cmd.Dir = dl.Config.Server.DownloadPath log.Printf("Executing command executable: %s) in %s", cmdPath, dl.Config.Server.DownloadPath) @@ -299,7 +304,6 @@ func (dl *Download) Begin() { dl.FinishedTS = time.Now() dl.Log = append(dl.Log, fmt.Sprintf("error setting up stdout pipe: %v", err)) dl.Lock.Unlock() - return } @@ -373,28 +377,6 @@ func (dl *Download) Begin() { dl.Lock.Unlock() } -func absPathToExecutable(cmd string) (string, error) { - - pathCmd, err := exec.LookPath(cmd) - if err != nil { - return "", fmt.Errorf("could not LookPath '%s': %w", cmd, err) - } - - execAbsolutePath, err := filepath.Abs(pathCmd) - if err != nil { - return "", fmt.Errorf("could not get absolute path to '%s': %w", cmd, err) - } - fi, err := os.Stat(execAbsolutePath) - if err != nil { - return "", fmt.Errorf("could not get stat '%s': %w", cmd, err) - } - if !fi.Mode().IsRegular() { - return "", fmt.Errorf("'%s' is not a regular file: %w", cmd, err) - } - - return execAbsolutePath, nil -} - // updateDownload updates the download based on data from the reader. Expects the // Download to be unlocked. func (dl *Download) updateDownload(r io.Reader) { diff --git a/download/download_test.go b/download/download_test.go index 18cd2ba..0c07deb 100644 --- a/download/download_test.go +++ b/download/download_test.go @@ -1,15 +1,11 @@ package download import ( - "os" - "os/exec" - "path/filepath" "strings" "sync" "testing" "time" - "github.com/stretchr/testify/assert" "github.com/tardisx/gropple/config" ) @@ -364,41 +360,3 @@ Deleting original file The Greatest Shot In Television [2WoDQBhJCVQ].f140.m4a (p } } - -func TestLookForExecutable(t *testing.T) { - cmdPath, err := exec.LookPath("sleep") - if err != nil { - t.Errorf("cannot run this test without knowing about sleep: %s", err) - t.FailNow() - } - cmdDir := filepath.Dir(cmdPath) - - cmd := "sleep" - path, err := absPathToExecutable(cmd) - if assert.NoError(t, err) { - assert.Equal(t, cmdPath, path) - } - - cmd = cmdPath - path, err = absPathToExecutable(cmd) - if assert.NoError(t, err) { - assert.Equal(t, cmdPath, path) - } - - cmd = "../../../../../../../../.." + cmdPath - path, err = absPathToExecutable(cmd) - if assert.NoError(t, err) { - assert.Equal(t, cmdPath, path) - } - cmd = "./sleep" - _, err = absPathToExecutable(cmd) - assert.Error(t, err) - - os.Chdir(cmdDir) - cmd = "./sleep" - path, err = absPathToExecutable(cmd) - if assert.NoError(t, err) { - assert.Equal(t, cmdPath, path) - } - -} diff --git a/main.go b/main.go index b41c5a5..e33ed59 100644 --- a/main.go +++ b/main.go @@ -15,7 +15,7 @@ import ( func main() { versionInfo := &version.Manager{ - VersionInfo: version.Info{CurrentVersion: "v1.1.1-alpha.1"}, + VersionInfo: version.Info{CurrentVersion: "v1.1.1-alpha.2"}, } log.Printf("Starting gropple %s - https://github.com/tardisx/gropple", versionInfo.GetInfo().CurrentVersion) diff --git a/web/data/templates/config.tmpl b/web/data/templates/config.tmpl index 70e13c7..6d7d11e 100644 --- a/web/data/templates/config.tmpl +++ b/web/data/templates/config.tmpl @@ -84,7 +84,10 @@ - Which command to run. Your path will be searched, or you can specify the full path here. + Which command to run. Your path will be searched, or you can specify the full path here. + If you are using gropple in portable mode and store the executables with the gropple executable, use a prefix of + ./, for instance yt-dlp.exe. +