feat: reimplement WAV extraction in Go (replaces extract_wavs.sh)
extract.go replaces the bash script with idiomatic Go: - akaiutil process communication via stdin/stdout pipes - partition enumeration (df output parsing) - volume enumeration (dir output parsing per partition) - sample2wavall per volume with WAV count aggregation runAkaiutil is a package-level var — tests stub it with canned output to verify parsing without a real akaiutil binary or ISO. Removed: findScript(), -tool flag on extract, os/exec from main.go Kept: extract_wavs.sh as a standalone utility (no longer called)
This commit is contained in:
@@ -8,7 +8,6 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
@@ -100,10 +99,9 @@ Download flags:
|
||||
-dir "./isos" output directory (default: current dir)
|
||||
-jobs 2 concurrent downloads (default: 2)
|
||||
|
||||
Extract flags:
|
||||
Extract flags:
|
||||
-dir "./isos" directory containing ISO files
|
||||
-out "./wavs" output directory for WAV files
|
||||
-tool "./extract_wavs.sh" path to extraction script
|
||||
-jobs 2 concurrent extractions (default: 2)
|
||||
|
||||
Pipeline flags:
|
||||
@@ -382,15 +380,9 @@ func cmdExtract(args []string) {
|
||||
fs := flag.NewFlagSet("extract", flag.ExitOnError)
|
||||
isoDir := fs.String("dir", ".", "directory with ISO files")
|
||||
outDir := fs.String("out", "./wavs", "output directory for WAVs")
|
||||
toolFlag := fs.String("tool", "", "path to extraction script (default: auto-detect)")
|
||||
jobs := fs.Int("jobs", 2, "concurrent extractions")
|
||||
_ = fs.Parse(args)
|
||||
|
||||
toolPath := *toolFlag
|
||||
if toolPath == "" {
|
||||
toolPath = findScript("extract_wavs.sh")
|
||||
}
|
||||
|
||||
os.MkdirAll(*outDir, 0755)
|
||||
|
||||
entries, err := os.ReadDir(*isoDir)
|
||||
@@ -414,8 +406,6 @@ func cmdExtract(args []string) {
|
||||
|
||||
sem := make(chan struct{}, *jobs)
|
||||
var wg sync.WaitGroup
|
||||
var mu sync.Mutex
|
||||
results := map[string]string{}
|
||||
|
||||
for _, iso := range isos {
|
||||
wg.Add(1)
|
||||
@@ -425,10 +415,7 @@ func cmdExtract(args []string) {
|
||||
defer func() { <-sem }()
|
||||
|
||||
out := *outDir
|
||||
result, err := extractISO(toolPath, isoPath, out)
|
||||
mu.Lock()
|
||||
results[filepath.Base(isoPath)] = result
|
||||
mu.Unlock()
|
||||
result, err := extractISO(isoPath, out)
|
||||
if err != nil {
|
||||
fmt.Printf(" FAIL %-40s %v\n", filepath.Base(isoPath), err)
|
||||
} else {
|
||||
@@ -439,46 +426,6 @@ func cmdExtract(args []string) {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func extractISO(toolPath, isoPath, outDir string) (string, error) {
|
||||
absTool, err := filepath.Abs(toolPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if _, err := os.Stat(absTool); os.IsNotExist(err) {
|
||||
return "", fmt.Errorf("script not found: %s", absTool)
|
||||
}
|
||||
|
||||
isoOutDir := filepath.Join(outDir, sanitiseISOName(filepath.Base(isoPath)))
|
||||
|
||||
if _, err := os.Stat(isoOutDir); err == nil {
|
||||
var wavCount int
|
||||
filepath.WalkDir(isoOutDir, func(p string, d os.DirEntry, err error) error {
|
||||
if err == nil && !d.IsDir() && strings.HasSuffix(strings.ToLower(d.Name()), ".wav") {
|
||||
wavCount++
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if wavCount > 0 {
|
||||
return fmt.Sprintf("skipped (%d WAVs exist)", wavCount), nil
|
||||
}
|
||||
}
|
||||
|
||||
cmd := exec.Command("bash", absTool, isoPath, outDir)
|
||||
cmd.Stderr = nil
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("extract: %w", err)
|
||||
}
|
||||
|
||||
lines := strings.Split(string(output), "\n")
|
||||
for _, line := range lines {
|
||||
if strings.Contains(line, "Total WAV files:") {
|
||||
return strings.TrimSpace(line), nil
|
||||
}
|
||||
}
|
||||
return "extracted (check output)", nil
|
||||
}
|
||||
|
||||
func sanitiseISOName(path string) string {
|
||||
name := path
|
||||
if ext := filepath.Ext(name); ext != "" {
|
||||
@@ -520,7 +467,6 @@ func cmdPipeline(args []string) {
|
||||
|
||||
isoDir := filepath.Join(*baseDir, "isos")
|
||||
wavDir := filepath.Join(*baseDir, "wavs")
|
||||
toolPath := findScript("extract_wavs.sh")
|
||||
|
||||
// Remaining args after flags are treated as explicit identifiers
|
||||
identifiers := fs.Args()
|
||||
@@ -566,28 +512,13 @@ func cmdPipeline(args []string) {
|
||||
cmdDownload([]string{"-f", idFile, "-dir", isoDir, "-jobs", fmt.Sprintf("%d", *dlJobs)})
|
||||
|
||||
fmt.Println("\n=== Phase 3: Extract ===")
|
||||
cmdExtract([]string{"-dir", isoDir, "-out", wavDir, "-tool", toolPath, "-jobs", fmt.Sprintf("%d", *extJobs)})
|
||||
cmdExtract([]string{"-dir", isoDir, "-out", wavDir, "-jobs", fmt.Sprintf("%d", *extJobs)})
|
||||
|
||||
fmt.Printf("\n=== Pipeline Complete ===\n")
|
||||
fmt.Printf(" ISOs: %s\n", isoDir)
|
||||
fmt.Printf(" WAVs: %s\n", wavDir)
|
||||
}
|
||||
|
||||
func findScript(name string) string {
|
||||
candidates := []string{
|
||||
filepath.Join(filepath.Dir(os.Args[0]), name),
|
||||
filepath.Join(filepath.Dir(os.Args[0]), "scripts", name),
|
||||
name,
|
||||
filepath.Join("scripts", name),
|
||||
}
|
||||
for _, p := range candidates {
|
||||
if _, err := os.Stat(p); err == nil {
|
||||
return p
|
||||
}
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
// ─── Helpers ───────────────────────────────────────────────────────────
|
||||
|
||||
func fatal(format string, args ...any) {
|
||||
|
||||
Reference in New Issue
Block a user