diff --git a/internal/dl/dl.go b/internal/dl/dl.go index 7c67ddb..a51a9af 100644 --- a/internal/dl/dl.go +++ b/internal/dl/dl.go @@ -25,20 +25,64 @@ type Download struct { Metadata bool } -func PipxUpgrade() error { - cmd := exec.Command("pipx", "upgrade-all") +func UpgradeYtDlp(cmd string) error { + resolved, err := resolveYtDlpPath(cmd) + if err != nil { + return err + } + if strings.Contains(resolved, filepath.Join("pipx", "venvs")) { + return runLoggedCommand("pipx", exec.Command("pipx", "upgrade-all")) + } + + return runLoggedCommand("yt-dlp", exec.Command(resolved, "--update")) +} + +func resolveYtDlpPath(cmd string) (string, error) { + if cmd == "" { + cmd = "yt-dlp" + } + + if filepath.IsAbs(cmd) { + return evalPath(cmd) + } + + if strings.Contains(cmd, string(os.PathSeparator)) { + abs, err := filepath.Abs(cmd) + if err != nil { + return "", fmt.Errorf("resolve yt-dlp path: %w", err) + } + return evalPath(abs) + } + + located, err := exec.LookPath(cmd) + if err != nil { + return "", fmt.Errorf("locate yt-dlp: %w", err) + } + + return evalPath(located) +} + +func evalPath(path string) (string, error) { + resolved, err := filepath.EvalSymlinks(path) + if err != nil { + return "", fmt.Errorf("resolve yt-dlp symlink: %w", err) + } + return resolved, nil +} + +func runLoggedCommand(tag string, cmd *exec.Cmd) error { stdout, err := cmd.StdoutPipe() if err != nil { - return fmt.Errorf("pipx upgrade stdout: %w", err) + return fmt.Errorf("%s stdout: %w", tag, err) } stderr, err := cmd.StderrPipe() if err != nil { - return fmt.Errorf("pipx upgrade stderr: %w", err) + return fmt.Errorf("%s stderr: %w", tag, err) } - log.Println("[pipx] running pipx upgrade-all") + log.Printf("[%s] running %s %v\n", tag, cmd.Path, cmd.Args[1:]) var wg sync.WaitGroup wg.Add(2) @@ -47,7 +91,10 @@ func PipxUpgrade() error { defer wg.Done() scanner := bufio.NewScanner(stdout) for scanner.Scan() { - log.Printf("[pipx] %s\n", scanner.Text()) + log.Printf("[%s] %s\n", tag, scanner.Text()) + } + if err := scanner.Err(); err != nil { + log.Printf("[%s] stdout error: %v\n", tag, err) } }() @@ -55,18 +102,21 @@ func PipxUpgrade() error { defer wg.Done() scanner := bufio.NewScanner(stderr) for scanner.Scan() { - log.Printf("[pipx] %s\n", scanner.Text()) + log.Printf("[%s] %s\n", tag, scanner.Text()) + } + if err := scanner.Err(); err != nil { + log.Printf("[%s] stderr error: %v\n", tag, err) } }() if err := cmd.Start(); err != nil { - return fmt.Errorf("pipx upgrade start: %w", err) + return fmt.Errorf("%s start: %w", tag, err) } wg.Wait() if err := cmd.Wait(); err != nil { - return fmt.Errorf("pipx upgrade failed: %w", err) + return fmt.Errorf("%s failed: %w", tag, err) } return nil diff --git a/main.go b/main.go index 9daca10..14a257b 100644 --- a/main.go +++ b/main.go @@ -15,12 +15,12 @@ import ( ) func run(cfg config.Config) { - if err := dl.PipxUpgrade(); err != nil { - log.Fatalf("failed to upgrade pipx packages: %v", err) - } - provider := cfg.Provider["youtube"] + if err := dl.UpgradeYtDlp(provider.Cmd); err != nil { + log.Fatalf("failed to ensure yt-dlp is up to date: %v", err) + } + opml, err := format.OpmlLoad(provider.Opml_file) if err != nil { panic(err)